gigaaa-botkit-ext
Version:
Gigaaa Platfrom integration with Botkit
602 lines (499 loc) • 16.4 kB
JavaScript
var Botkit = require('botkit');
var GigaaaApi = require('./GigaaaApi');
function GigaaaBot(configuration) {
var controller = Botkit.core(configuration || {});
controller.middleware.ingest.use(function (bot, message, reply_channel, next) {
bot.http_response = reply_channel;
next();
});
controller.middleware.categorize.use(function (bot, message, next) {
message.type = 'message_received';
next();
});
controller.middleware.spawn.use(function (bot, next) {
bot.api = new GigaaaApi({
token: controller.config.token,
bearerToken: controller.config.bearerToken
});
next();
});
// provide one or more normalize middleware functions that take a raw incoming message
// and ensure that the key botkit fields are present -- user, channel, text, and type
controller.middleware.normalize.use(function (bot, message, next) {
message.user = message.user_id;
message.text = message.message;
message.channel = message.service_id;
next();
});
controller.middleware.normalize.use(function (bot, message, next) {
bot.findConversation({
user: message.user,
channel: message.channel
}, function (convo) {
if (convo) {
if (isAbort(message)) {
if (convo.ignoreAbort) {
convo.vars.payload.shouldAbort = true;
} else {
convo.stop();
bot.http_response.json("ok");
next("Conversation Aborted");
}
}
convo.task.bot.http_response = bot.http_response;
}
next();
});
});
controller.middleware.format.use(function (bot, message, platform_message, next) {
if (message.user) {
platform_message.user_id = message.user;
}
if (message.error) {
platform_message.error = message.error;
}
if (message.empty) {
platform_message.actions = {};
platform_message.expect_reply = false;
platform_message.skip_scroll = false;
if (message.loop) {
platform_message.loop = true;
}
return next();
}
if (message.extras) {
platform_message.extras = message.extras
}
if (message.expectedEntities && Array.isArray(message.expectedEntities) && message.expectedEntities.every(e => typeof e === 'string')) {
platform_message.expected_entities = message.expectedEntities;
}
if (message.generic) {
platform_message.expect_reply = message.expectReply ? message.expectReply : false;
platform_message.actions = {};
if (message.text && message.messageOnTop) {
platform_message.actions.speak = {
text: decodeText(message.text)
};
if (message.tts && !message.tts.includes("{{")) {
platform_message.actions.speak.tts = decodeText(message.tts);
}
}
if (message.text && message.alarm) {
platform_message.actions.speak = {
text: message.text,
}
platform_message.actions.set_alarm = message.alarm
}
if (message.text && message.plugin_action) {
platform_message.actions.speak = {
text: message.text,
tts: message.tts || message.text
}
platform_message.actions.plugin_action = { action: message.plugin_action }
}
if (message.table) {
platform_message.actions.display_list = {
layout: "table",
table: message.tableElements
}
}
if (message.list) {
platform_message.actions.display_list = {
layout: "simple",
elements: message.listElements,
type: message.type,
extras: message.extras
}
}
if (message.form) {
platform_message.actions.form = {
layout: "simple",
elements: message.listElements,
confirmationButton: message.confirmationButton,
type: message.type,
extras: message.extras
}
}
if (message.listOfLists) {
platform_message.actions.list_of_lists = {
layout: "list_of_lists",
elements: message.listElements,
type: message.type
}
}
if (message.text && !message.messageOnTop) {
platform_message.actions.speak = {
text: decodeText(message.text)
};
if (message.tts && !message.tts.includes("{{")) {
platform_message.actions.speak.tts = decodeText(message.tts);
}
}
if (message.buttons) {
platform_message.actions['buttons'] = message.buttons;
}
if (message.interaction) {
platform_message.actions['message_interaction'] = {
type: message.type,
elements: message.elements
}
}
if (message.screen_action) {
platform_message.actions['screen_action'] = {
action: message.screen_action,
data: message.data
}
}
if (message.language_action) {
platform_message.actions['language_action'] = {
action: message.language_action,
data: message.data
}
}
if (message.media_action) {
platform_message.actions['media_action'] = {
action: message.media_action,
data: message.data
}
}
if (message.volume_action) {
platform_message.actions['volume_action'] = {
action: message.volume_action,
data: message.data
}
}
if (message.account_action) {
platform_message.actions['account_action'] = {
action: message.account_action,
data: message.data
}
}
if (message.prepared_interaction) {
platform_message.actions = { prepared_interaction: message.prepared_interaction };
}
if (message.prepareAudioFile) {
platform_message.actions['prepare_audio_file'] = message.prepareAudioFile;
}
if (message.sendAudioFile) {
platform_message.actions['send_audio_file'] = message.sendAudioFile;
}
if (message.answer_group) {
platform_message.actions.speak["answer_group"] = message.answer_group;
}
return next();
}
if (message.mood) {
platform_message.actions = {};
platform_message.expect_reply = message.expectReply ? message.expectReply : false;
if (message.text && message.text !== 'show-gigs') {
platform_message.actions.speak = {
text: decodeText(message.text)
};
if (message.tts && !message.tts.includes("{{")) {
platform_message.actions.speak.tts = decodeText(message.tts);
}
}
platform_message.actions.skipScroll = true;
platform_message.actions.mood_match_list = {
"moods": message.moodsList
};
return next();
}
if (message.screen_action) {
platform_message.actions = {
screen_action: {
action: message.screen_action,
data: message.data
}
};
return next();
}
if (message.media_action) {
platform_message.actions = {
media_action: {
action: message.mediaControl,
data: message.data
}
};
return next();
}
if (message.volume_action) {
platform_message.actions = {
volume_action: {
action: message.mediaControl,
data: message.data
}
};
return next();
}
if (message.account_action) {
platform_message.actions = {
account_action: {
action: message.mediaControl,
data: message.data
}
};
return next();
}
if (message.language_action) {
platform_message.actions = {
language_action: {
action: message.mediaControl,
data: message.data
}
};
return next();
}
if (message.buttons) {
platform_message.actions = {
buttons: message.buttons
}
return next();
}
if (message.interaction) {
platform_message.actions = {
message_interaction: {
type: message.type,
elements: message.elements
}
}
return next();
}
if (message.changeLocationPath) {
platform_message.actions = {};
platform_message.actions.change_location_path = {
"path": message.newPath
};
return next();
}
if (message.externalUrlInApp) {
platform_message.actions = {
"open_external_url_in_app": {
"url": message.url
}
};
if (message.text && message.text !== '-') {
platform_message.actions['speak'] = {
text: message.text,
tts: message.tts || message.text,
answer_group: message.answer_group
}
}
return next();
}
if (message.externalUrl) {
platform_message.actions = {
"open_external_url": {
"url": message.url,
"type": message.type,
"extras": message.extras
}
};
if (message.text && message.text !== '-') {
platform_message.actions['speak'] = {
text: message.text,
tts: message.tts || message.text,
answer_group: message.answer_group
}
}
return next();
}
if (message.list) {
platform_message.actions = {
"display_list": {
"layout": "simple",
"elements": message.listElements,
"type": message.type,
"extras": message.extras
}
};
platform_message.expect_reply = message.expectReply ? message.expectReply : false;
return next();
}
if (message.table) {
platform_message.actions = {
"display_list": {
"layout": message.tableType ? message.tableType : "table",
"table": message.tableElements
}
};
platform_message.expect_reply = message.expectReply ? message.expectReply : false;
return next();
}
if (message.form) {
platform_message.actions = {
"form": {
"layout": "form",
"elements": message.listElements,
"confirmationButton": message.confirmationButton,
"type": message.type,
"extras": message.extras
}
};
platform_message.expect_reply = message.expectReply ? message.expectReply : false;
return next();
}
if (message.files && message.files.length) {
platform_message.actions = {
"open_external_url_in_app": {
"url": message.files[0].url
}
};
} else {
platform_message.actions = {
"speak": {
"text": decodeText(message.text)
}
};
if (message.tts && !message.tts.includes("{{")) {
platform_message.actions.speak.tts = decodeText(message.tts);
}
if (message.answer_group) {
platform_message.actions.speak["answer_group"] = message.answer_group;
}
}
platform_message.expect_reply = message.expectReply ? message.expectReply : false;
platform_message.skip_scroll = message.skipScroll ? message.skipScroll : false;
platform_message.externalCallsLog = message.externalCallsLog;
next();
});
controller.defineBot(function (botkit, config) {
var bot = {
type: 'gigaaa',
botkit: botkit,
config: config || {},
utterances: botkit.utterances,
};
bot.startConversation = function (message, cb) {
botkit.startConversation(this, message, cb);
};
bot.createConversation = function (message, cb) {
botkit.createConversation(this, message, cb);
};
bot.send = function (message, cb) {
try {
bot.http_response.json(message);
if (configuration && configuration.onSend) {
configuration.onSend(true, message);
}
} catch (err) {
if (configuration && configuration.onSend) {
configuration.onSend(false, message, err);
}
}
cb();
};
bot.findConversation = function (message, cb) {
for (var t = 0; t < botkit.tasks.length; t++) {
for (var c = 0; c < botkit.tasks[t].convos.length; c++) {
if (
botkit.tasks[t].convos[c].isActive() &&
botkit.tasks[t].convos[c].source_message.user === message.user &&
botkit.tasks[t].convos[c].source_message.channel === message.channel &&
botkit.excludedEvents.indexOf(message.type) === -1 // this type of message should not be included
) {
var foundConversation = botkit.tasks[t].convos[c];
cb(foundConversation);
return;
}
}
}
cb();
};
bot.reply = function (src, resp, cb) {
if (typeof (resp) == 'string') {
resp = {
text: resp
};
}
resp.user = src.user;
resp.channel = src.channel;
resp.to = src.user;
bot.say(resp, cb);
};
// return info about the specific instance of this bot
// including identity information, and any other info that is relevant
bot.getInstanceInfo = function (cb) {
return new Promise(function (resolve, reject) {
var instance = {
identity: {},
team: {},
};
if (bot.identity) {
instance.identity.name = bot.identity.name;
instance.identity.id = bot.identity.id;
instance.team.name = bot.identity.name;
instance.team.url = bot.identity.root_url;
instance.team.id = bot.identity.name;
} else {
instance.identity.name = 'Botkit Gigaaa';
instance.identity.id = 'gigaaa';
}
if (cb) cb(null, instance);
resolve(instance);
});
};
bot.getMessageUser = function (message, cb) {
return new Promise(function (resolve, reject) {
// normalize this into what botkit wants to see
controller.storage.users.get(message.user, function (err, user) {
if (!user) {
user = {
id: message.user,
name: 'Unknown',
attributes: {},
};
}
var profile = {
id: user.id,
username: user.name,
first_name: user.attributes.first_name || '',
last_name: user.attributes.last_name || '',
full_name: user.attributes.full_name || '',
email: user.attributes.email, // may be blank
gender: user.attributes.gender, // no source for this info
timezone_offset: user.attributes.timezone_offset,
timezone: user.attributes.timezone,
};
if (cb) {
cb(null, profile);
}
resolve(profile);
});
});
};
return bot;
});
controller.handleWebhookPayload = function (req, res) {
var payload = req.body;
if (!payload.service_id) {
payload.service_id = req.query.gigaaa_service_id;
}
payload.service_uuid = payload.service || req.query.service;
payload.headers = req.headers;
controller.ingest(controller.spawn({}), payload, res);
};
// Substantially shorten the delay for processing messages in conversations
controller.setTickDelay(10);
return controller;
}
/**
* @param message the incoming message object
* function will check if arriving message is meant to abort any ongoing conversation
*/
function isAbort(message) {
if (message.abort === true) {
return true;
}
if (message.abort === "1") {
return true;
}
return false;
}
// Decode HTML entities
function decodeText(str) {
return str.replace(/&#(\d+);/g, function (match, dec) {
return String.fromCharCode(dec);
});
}
module.exports = GigaaaBot;