Skip to content
This repository has been archived by the owner on Sep 20, 2024. It is now read-only.

Add Google Hangouts Chat support to Botkit #1414

Merged
merged 5 commits into from
Oct 19, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion bin/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ var fs = require('fs');

var botkit = Vorpal()

var platforms = ['web', 'teams', 'ciscospark', 'slack', 'facebook'];
var platforms = ['web', 'teams', 'ciscospark', 'slack', 'facebook', 'googlehangouts'];
var platform_src = [{
platform: 'web',
artifact: 'https://github.com/howdyai/botkit-starter-web.git',
Expand Down Expand Up @@ -38,6 +38,11 @@ var platform_src = [{
platform: 'facebook',
artifact: 'https://github.com/howdyai/botkit-starter-facebook.git',
directory: 'botkit-starter-facebook'
},
{
platform: 'googlehangouts',
artifact: 'git@github.com:howdyai/botkit-starter-googlehangouts.git',
directory: 'botkit-starter-googlehangouts'
}
];

Expand Down
1 change: 1 addition & 0 deletions docs/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ All documentation for Botkit now lives at our official documentation site, [http
* [Twilio SMS](https://botkit.ai/docs/readme-twiliosms.html)
* [Twilio IPM](https://botkit.ai/docs/readme-twilioipm.html)
* [Microsoft Bot Framework](https://botkit.ai/docs/readme-botframework.html)
* [Google Hangouts Chat](https://botkit.ai/docs/google-hangouts-chat.html)
* [Extending Botkit with Plugins and Middleware](https://botkit.ai/docs/middleware.html)
* [Message Pipeline](https://botkit.ai/docs/readme-pipeline.html)
* [List of current plugins](https://botkit.ai/docs/readme-middlewares.html)
Expand Down
91 changes: 91 additions & 0 deletions examples/google_hangouts_bot.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
var Botkit = require('../lib/Botkit.js');

var controller = Botkit.googlehangoutsbot({
endpoint: 'Axjn86rTGRQwisaYFyT0XZyiOCh7rZUPGx1A',
token: "YOUR_TOKEN",
debug: true,
});

var bot = controller.spawn({});

controller.setupWebserver(3000, function (err, webserver) {
controller.createWebhookEndpoints(webserver, bot, function () {
console.log(`🚀 Congratulation, the web server is online!`);
});
});

controller.on('message_received', function (bot, message) {
bot.reply(message, `You said '${message.text}'`);
});

controller.hears('new thread', 'message_received', function (bot, message) {
bot.replyAsNewThread(message, `Hello ! this is a new thread`);
});

controller.hears('thread key', 'message_received', function (bot, message) {
bot.replyWithThreadKey(message, {
threadKey : "YOUR_THREAD_KEY",
requestBody : {
text : `Hi ! this message inside the same thread`
}
});
});

controller.hears('convo', 'message_received', function (bot, message) {

bot.startConversation(message, function(err, convo) {

convo.ask('You want to know more about Botkit ?', [
{
pattern: bot.utterances.yes,
callback: function(response, convo) {
convo.say('Take a look here https://botkit.ai/docs/');
convo.next();
}
},
{
pattern: bot.utterances.no,
default: true,
callback: function(response, convo) {
convo.say('No problem');
convo.next();
}
}
]);
});

});

controller.hears('cards', 'message_received', function (bot, message) {
bot.reply(message, {
requestBody: {
cards: [
{
"sections": [
{
"widgets": [
{
"image": { "imageUrl": "https://image.slidesharecdn.com/botkitsignal-160526164159/95/build-a-bot-with-botkit-1-638.jpg?cb=1464280993" }
},
{
"buttons": [
{
"textButton": {
"text": "Get Started",
"onClick": {
"openLink": {
"url": "https://botkit.ai/docs/"
}
}
}
}
]
}
]
}
]
}
]
}
});
});
2 changes: 2 additions & 0 deletions lib/Botkit.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ var SparkBot = require(__dirname + '/CiscoSparkbot.js');
var ConsoleBot = require(__dirname + '/ConsoleBot.js');
var JabberBot = require(__dirname + '/JabberBot.js');
var WebBot = require(__dirname + '/Web.js');
var GoogleHangoutsBot = require(__dirname + '/GoogleHangoutsBot.js');

module.exports = {
core: CoreBot,
Expand All @@ -22,4 +23,5 @@ module.exports = {
jabberbot: JabberBot,
socketbot: WebBot,
anywhere: WebBot,
googlehangoutsbot: GoogleHangoutsBot
};
208 changes: 208 additions & 0 deletions lib/GoogleHangoutsBot.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
var Botkit = require(__dirname + '/CoreBot.js');
var {google} = require('googleapis');

function GoogleHangoutsBot(configuration) {

var api_version = 'v1';

var google_hangouts_botkit = Botkit(configuration || {});

google_hangouts_botkit.defineBot(function (botkit, config) {

var bot = {
type: 'googleHangouts',
botkit: botkit,
config: config || {},
utterances: botkit.utterances,
};

bot.send = function (message, cb) {

const chat = google.chat({version: api_version, auth: bot.authClient});

chat.spaces.messages.create(message)
.then(res => {
botkit.debug('Successfully sent message to Google Hangouts : ' + res.data.name);
if (cb) {
cb(null, res.data);
}
})
.catch(err => {
botkit.debug('Error while sending message to Google Hangouts', err);
if (cb) {
cb(err);
}
});
};

bot.reply = function (src, resp, cb) {

var message_to_send = {
parent: src.space.name,
threadKey: undefined,
requestBody: {}
};

if (typeof (resp) == 'string') {
message_to_send.requestBody.text = resp;
} else if (resp.text) {
message_to_send.requestBody.text = resp.text;
} else {
message_to_send.requestBody = resp.requestBody;
}

message_to_send.requestBody.thread = {
name: src.message.thread.name
};

bot.say(message_to_send, cb);

};

bot.replyWithThreadKey = function (src, resp, cb) {

var msg = {};

msg.parent = src.space.name;
msg.threadKey = resp.threadKey;
msg.requestBody = resp.requestBody;

bot.say(msg, cb);
};

bot.replyAsNewThread = function (src, resp, cb) {

var msg = {};

msg.parent = src.space.name;

if (typeof (resp) == 'string') {
msg.requestBody = {
text: resp
};
} else {
msg.requestBody = resp;
}

bot.say(msg, cb);
};

bot.findConversation = function (message, cb) {
botkit.debug('CUSTOM FIND CONVO', message.user, message.channel);
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.debug('FOUND EXISTING CONVO!');
cb(botkit.tasks[t].convos[c]);
return;
}
}
}

cb();
};

return bot;
});

google_hangouts_botkit.createWebhookEndpoints = function (webserver, bot, cb) {

var endpoint = '/hangouts/' + google_hangouts_botkit.config.endpoint;

google_hangouts_botkit.log(
'** Serving webhook endpoints for Google Hangout Platform at : ' +
'http://' + google_hangouts_botkit.config.hostname + ':' + google_hangouts_botkit.config.port + endpoint
);

webserver.post(endpoint, function (req, res) {
google_hangouts_botkit.handleWebhookPayload(req, res, bot);
});

if (cb) {
cb();
}

return google_hangouts_botkit;
};

google_hangouts_botkit.handleWebhookPayload = function (req, res, bot) {

var payload = req.body;

if (google_hangouts_botkit.config.token && google_hangouts_botkit.config.token !== payload.token) {
res.status(401);
google_hangouts_botkit.debug('Token verification failed, Ignoring message');
} else {
res.status(200);
google_hangouts_botkit.ingest(bot, payload, res);
}

res.send();
};

google_hangouts_botkit.middleware.format.use(function (bot, message, platform_message, next) {

platform_message.parent = message.parent;
platform_message.threadKey = message.threadKey;
platform_message.requestBody = message.requestBody;

next();

});

google_hangouts_botkit.middleware.spawn.use(function (worker, next) {

let params = {
scopes: 'https://www.googleapis.com/auth/chat.bot'
};

google
.auth
.getClient(params)
.then(client => {
worker.authClient = client;
})
.catch(err => {
console.error('Could not get google auth client !');
throw new Error(err);
});

next();

});

google_hangouts_botkit.middleware.normalize.use(function handlePostback(bot, message, next) {
message.user = message.user.name;
if (message.message) {
message.channel = message.message.thread.name;
message.text = message.message.argumentText.trim();
} else {
message.channel = message.space.name;
}
next();
});

google_hangouts_botkit.middleware.categorize.use(function (bot, message, next) {

if ('MESSAGE' === message.type) {
message.type = 'message_received';
}

if ('ADDED_TO_SPACE' === message.type) {
message.type = 'ROOM' === message.space.type ? 'room_join' : 'direct_message';
}

if ('REMOVED_FROM_SPACE' === message.type) {
message.type = 'ROOM' === message.space.type ? 'room_leave' : 'remove_conversation';
}

next();

});

google_hangouts_botkit.startTicking();

return google_hangouts_botkit;
};

module.exports = GoogleHangoutsBot;
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"debug": "^3.1.0",
"email-addresses": "^3.0.1",
"express": "^4.15.2",
"googleapis": "^32.0.0",
"https-proxy-agent": "^2.2.1",
"jfs": "^0.3.0",
"localtunnel": "^1.8.2",
Expand Down