         @robot.logger.warning "esa API GET request failed: #{error}"
 
 module.exports = (robot) ->
-  esa = new EsaClientRobot(robot, process.env.HUBOT_ESA_TEAM_NAME, process.env.HUBOT_ESA_ACCESS_TOKEN)
-  robot.router.post '/hubot/esa', (req, res) ->
+  options =
+    team: process.env.HUBOT_ESA_TEAM
+    token: process.env.HUBOT_ESA_ACCESS_TOKEN
+    room: process.env.HUBOT_ESA_WEBHOOK_DEFAULT_ROOM
+    endpoint: process.env.HUBOT_ESA_WEBHOOK_ENDPOINT || '/hubot/esa'
+
+  return robot.logger.error "Missing configuration: HUBOT_ESA_TEAM" unless options.team?
+  return robot.logger.error "Missing configuration: HUBOT_ESA_ACCESS_TOKEN" unless options.token?
+  return robot.logger.error "Missing configuration: HUBOT_ESA_WEBHOOK_DEFAULT_ROOM" unless options.room?
+
+  esa = new EsaClientRobot(robot, options.team, options.token)
+  robot.router.post options.endpoint, (req, res) ->
+    # https://docs.esa.io/posts/37#3-4-0
+    unless req.headers['user-agent'] == 'esa-Hookshot/v1'
+      robot.logger.warning "Requested unknown user agent: #{req.headers['user-agent']}"
+      res.writeHead(403)
+      res.end()
+      return
+    robot.messageRoom options.room, handleWebhook(req.body or {})
     res.writeHead(204)
     res.end()
-    unless process.env.HUBOT_ESA_WEBHOOK_DEFAULT_ROOM
-      robot.logger.warning "HUBOT_ESA_WEBHOOK_DEFAULT_ROOM is not set."
-      return
-    unless req.headers['user-agent'] == 'esa-Hookshot/v1'
-      robot.logger.warning "Requested unknown user agent: #{req.headers['user-agent']}"
-      return
-    robot.messageRoom process.env.HUBOT_ESA_WEBHOOK_DEFAULT_ROOM, handleWebhook(req.body or {})
 
   robot.respond /esa stats/, (res) ->
     esa.getRequest("/stats", (stats) ->
       res.send "Members: #{stats.members}\nPosts: #{stats.posts}\nComments: #{stats.comments}\nStars: #{stats.stars}\nDaily Active Users: #{stats.daily_active_users}\nWeekly Active Users: #{stats.weekly_active_users}\nMonthly Active Users: #{stats.monthly_active_users}"
     )
   robot.hear /https:\/\/(.+)\.esa\.io\/posts\/(\d+)\b/, (res) ->
-    unless res.match[1] == process.env.HUBOT_ESA_TEAM_NAME then return
+    unless res.match[1] == options.team then return
     esa.getRequest("/posts/#{res.match[2]}", (post) ->
       res.send "esa: #{post.full_name}"
     )
   robot.hear /https:\/\/(.+)\.esa\.io\/posts\/(\d+)\#comment-(\d+)/, (res) ->
-    unless res.match[1] == process.env.HUBOT_ESA_TEAM_NAME then return
+    unless res.match[1] == options.team then return
     esa.getRequest("/comments/#{res.match[3]}", (comment) ->
       res.send "#{comment.body_md}"
     )


class EsaClientRobot
  constructor: (@robot, @team, @access_token) ->
    unless @team then @robot.logger.warning "HUBOT_ESA_TEAM_NAME is not set."
    unless @team then @robot.logger.warning "HUBOT_ESA_ACCESS_TOKEN is not set."

  baseUrl: ->
    "https://api.esa.io/v1/teams/#{@team}"

#   HUBOT_ESA_ACCESS_TOKEN
#   HUBOT_ESA_TEAM_NAME
#   HUBOT_ESA_WEBHOOK_DEFAULT_ROOM
#   HUBOT_ESA_WEBHOOK_ENDPOINT
#
# Author:
#   hmsk <k.hamasaki@gmail.com>
