-
Notifications
You must be signed in to change notification settings - Fork 2
/
bot.js
162 lines (140 loc) · 4.53 KB
/
bot.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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
//
// Copyright (c) 2017 Cisco Systems
// Licensed under the MIT License
//
//
// BotKit configuration
//
// Load environment variables from project .env file
require("node-env-file")(__dirname + "/.env");
// Fetch token from environement
// [COMPAT] supports SPARK_TOKEN for backward compatibility
const accessToken = process.env.ACCESS_TOKEN || process.env.SPARK_TOKEN;
if (!accessToken) {
console.log(
"Could not start as this bot requires a Webex Teams API access token."
);
console.log("Please invoke with an ACCESS_TOKEN environment variable");
console.log("Example:");
console.log(
"> ACCESS_TOKEN=XXXXXXXXXXXX PUBLIC_URL=YYYYYYYYYYYYY node bot.js"
);
process.exit(1);
}
// Get public URL where the Webex cloud platform will post notifications (webhook registration)
let publicUrl = process.env.PUBLIC_URL;
// Infer the app domain for popular Cloud PaaS
if (!publicUrl) {
// Heroku hosting: available if dyno metadata are enabled, https://devcenter.heroku.com/articles/dyno-metadata
if (process.env.HEROKU_APP_NAME) {
publicUrl = "https://" + process.env.HEROKU_APP_NAME + ".herokuapp.com";
}
// Glitch hosting
if (process.env.PROJECT_DOMAIN) {
publicUrl = "https://" + process.env.PROJECT_DOMAIN + ".glitch.me";
}
}
if (!publicUrl) {
console.log("Could not start as this bot must expose a public endpoint.");
console.log(
"Please add env variable PUBLIC_URL on the command line or to the .env file"
);
console.log("Example: ");
console.log(
"> ACCESS_TOKEN=XXXXXXXXXXXX PUBLIC_URL=YYYYYYYYYYYYY node bot.js"
);
process.exit(1);
}
//
// Create bot
//
const Botkit = require("botkit");
const env = process.env.NODE_ENV || "development";
const controller = Botkit.webexbot({
log: true,
public_address: publicUrl,
access_token: accessToken,
// this is a RECOMMENDED security setting that
// checks if incoming payloads originate from Webex
secret: process.env.SECRET,
webhook_name: process.env.WEBHOOK_NAME || "built with BotKit (" + env + ")"
});
const bot = controller.spawn({});
//
// Launch bot
//
const port = process.env.PORT || 3000;
controller.setupWebserver(port, function(err, webserver) {
controller.createWebhookEndpoints(webserver, bot, function() {
console.log("webhooks setup completed!");
});
// installing Healthcheck
const healthcheck = {
up_since: new Date(Date.now()).toGMTString(),
hostname: require("os").hostname() + ":" + port,
version: "v" + require("./package.json").version,
bot: "unknown", // loaded asynchronously
botkit: "v" + bot.botkit.version()
};
webserver.get(process.env.HEALTHCHECK_ROUTE, function(req, res) {
// As the identity is load asynchronously from the
// Webex Teams access token, we need to check until it's fetched
if (healthcheck.bot == "unknown") {
/* eslint-disable no-unused-vars */
const identity = bot.botkit.identity;
/* eslint-enable no-unused-vars */
if (bot.botkit.identity) {
healthcheck.bot = bot.botkit.identity.emails[0];
}
}
res.json(healthcheck);
});
console.log("healthcheck available at: " + process.env.HEALTHCHECK_ROUTE);
});
//
// Load skills
//
const normalizedPath = require("path").join(__dirname, "skills");
require("fs")
.readdirSync(normalizedPath)
.forEach(function(file) {
try {
require("./skills/" + file)(controller, bot);
console.log("loaded skill: " + file);
} catch (err) {
if (err.code == "MODULE_NOT_FOUND") {
if (file != "utils") {
console.log("could not load skill: " + file);
}
}
}
});
//
// Webex Teams Utilities
//
// Utility to add mentions if Bot is in a 'Group' space
bot.appendMention = function(message, command) {
let botName;
// if the message is a raw message
// (from a post message callback such as bot.say())
if (message.roomType && message.roomType == "group") {
botName = bot.botkit.identity.displayName;
return "`@" + botName + " " + command + "`";
}
// if the message is a Botkit message
if (message.raw_message && message.raw_message.data.roomType == "group") {
botName = bot.botkit.identity.displayName;
return "`@" + botName + " " + command + "`";
}
return "`" + command + "`";
};
// [COMPAT] Adding this function to ease interoperability
// with the skills part of the Botkit samples project
bot.enrichCommand = bot.appendMention;
// Autoping for heroku
const https = require("https");
if (process.env.HEROKU_AUTOPING == "true") {
setInterval(function() {
https.get(publicUrl);
}, 1200000); // every 20 minutes (1200000)
}