-
Notifications
You must be signed in to change notification settings - Fork 4
/
server.js
90 lines (77 loc) · 2.33 KB
/
server.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
const bodyParser = require('body-parser')
const express = require('express')
const request = require('request')
// configure the yargs instance used
// to parse chat messages.
const parser = require('yargs')
.usage('/joe [command]')
.commandDir('commands')
.demand(1)
.strict()
.help()
.epilog("yargs' slack-bot Pirate Joe")
const app = express()
let logger = console
// Slack's slash commands are passed as an urlencoded
// HTTP post: https://api.slack.com/slash-commands
app.use(bodyParser.urlencoded({ extended: false }))
// slack webhook endpoint.
app.post('/', function (req, res) {
let context = Object.assign({}, req.body)
// slack secret token must be provided.
if (!req.body || req.body.token !== process.env.SLACK_TOKEN) {
return res.sendStatus(401)
}
// provides a respond function that any yargs
// command can use to respond to Slack.
context.respond = buildResponder(req.body.response_url)
// run the yargs parser on the inbound slack command.
parser.parse(req.body.text || '', context, (err, argv, output) => {
if (err) logger.error(err.message)
if (output) argv.respond(output)
})
res.send('')
})
// returns a helper function for dispatching messages
// back to Slack.
function buildResponder (responseUrl) {
return function (msg) {
request.post({
url: responseUrl,
json: true,
body: {
response_type: 'in_channel',
text: msg
}
}, function (err, res, body) {
if (err) return logger.error(err)
if (res && res.statusCode >= 400) logger.error('invalid response =', res.statusCode)
else logger.info(body)
})
}
}
// ping endpoint.
app.get('/', function (req, res) {
res.send('pong')
})
// start our slack webhook server.
module.exports = function (cb, opts) {
let port = process.env.PORT || 3000
cb = cb || function () {}
opts = opts || {}
if (opts.logger) logger = opts.logger
if (opts.port) port = opts.port
const server = app.listen(port, function (foo) {
if (process.env.HEROKU) keepAlive()
logger.info('Pirate Joe bot listening on :' + port, 'beep boop')
return cb(null, server)
})
}
// ping our application every 5 minutes so
// that Heroku does not sleep it.
function keepAlive () {
setInterval(function () {
logger.info('pinged', process.env.APP_URL)
request.get(process.env.APP_URL)
}, 300000)
}