- NEW: Whatsapp directline client is now working in preview.

This commit is contained in:
Rodrigo Rodriguez 2018-05-12 16:08:24 -03:00
parent 1d0dc4cf25
commit b122882aac
8 changed files with 79 additions and 39 deletions

View file

@ -1,3 +1,7 @@
## Version 0.0.20
- NEW: Whatsapp directline client is now working in preview.
## Version 0.0.19 ## Version 0.0.19
- NEW: Whatsapp directline client started. - NEW: Whatsapp directline client started.

View file

@ -97,6 +97,8 @@ export class GuaribasInstance extends Model<GuaribasInstance> implements IGBInst
@Column whatsappServiceNumber: string; @Column whatsappServiceNumber: string;
@Column whatsappServiceUrl: string;
@Column spellcheckerKey: string; @Column spellcheckerKey: string;
@Column theme: string; @Column theme: string;

View file

@ -172,7 +172,8 @@ export class GBMinService {
e.sysPackages.push(p); e.sysPackages.push(p);
if (sysPackage.name === "GBWhatsappPackage") { if (sysPackage.name === "GBWhatsappPackage") {
server.post("/instances/:botId/whatsapp", (req, res) => { let url = "/instances/:botId/whatsapp";
server.post(url, (req, res) => {
p["channel"].received(req, res); p["channel"].received(req, res);
}); });
} }

View file

@ -109,14 +109,16 @@ export class AskDialog extends IGBDialog {
session.userData.isAsking = false; session.userData.isAsking = false;
if (session.userData.subjects.length > 0) { if (session.userData.subjects.length > 0) {
let subjectText = `${KBService.getSubjectItemsSeparatedBySpaces( let subjectText =
`${KBService.getSubjectItemsSeparatedBySpaces(
session.userData.subjects session.userData.subjects
)}`; )}`;
let msgs = [ let msgs = [
`Respondendo nao apenas sobre ${subjectText}... `, `Respondendo nao apenas sobre ${subjectText}... `,
`Respondendo de modo mais abrangente...`, `Respondendo de modo mais abrangente...`,
`Vou te responder de modo mais abrangente... Não apenas sobre ${subjectText}` `Vou te responder de modo mais abrangente...
Não apenas sobre ${subjectText}`
]; ];
session.send(msgs); session.send(msgs);
} }
@ -195,7 +197,7 @@ export class AskDialog extends IGBDialog {
} }
]) ])
.triggerAction({ .triggerAction({
matches: /^(procurar|bing|google|perguntar)/i matches: /^(bing|google)/i
}); });
bot.beginDialogAction("ask", "/ask"); bot.beginDialogAction("ask", "/ask");
} }

View file

@ -55,7 +55,7 @@ export class GBWhatsappPackage implements IGBPackage {
loadBot(min: GBMinInstance): void { loadBot(min: GBMinInstance): void {
this.channel = new WhatsappDirectLine(min.botId, min.instance.whatsappBotKey, min.instance.whatsappServiceKey, this.channel = new WhatsappDirectLine(min.botId, min.instance.whatsappBotKey, min.instance.whatsappServiceKey,
min.instance.whatsappServiceNumber); min.instance.whatsappServiceNumber, min.instance.whatsappServiceUrl);
} }
unloadBot(min: GBMinInstance): void { unloadBot(min: GBMinInstance): void {

View file

@ -49,53 +49,83 @@ export class WhatsappDirectLine extends GBService {
pollInterval = 1000; pollInterval = 1000;
directLineClientName = 'DirectLineClient'; directLineClientName = 'DirectLineClient';
directLineSpecUrl = 'https://docs.botframework.com/en-us/restapi/directline3/swagger.json'; directLineSpecUrl = 'https://docs.botframework.com/en-us/restapi/directline3/swagger.json';
directLineClient: any; directLineClient: any;
whatsappServiceKey: string; whatsappServiceKey: string;
whatsappServiceNumber: string; whatsappServiceNumber: string;
whatsappServiceUrl: string;
botId: string; botId: string;
constructor(botId, directLineSecret, whatsappServiceKey, whatsappServiceNumber) { conversationIds = {};
constructor(botId, directLineSecret, whatsappServiceKey, whatsappServiceNumber, whatsappServiceUrl) {
super(); super();
this.botId = botId; this.botId = botId;
this.whatsappServiceKey = whatsappServiceKey; this.whatsappServiceKey = whatsappServiceKey;
this.whatsappServiceNumber = whatsappServiceNumber; this.whatsappServiceNumber = whatsappServiceNumber;
this.whatsappServiceUrl = whatsappServiceUrl;
// TODO: Migrate to Swagger 3. // TODO: Migrate to Swagger 3.
this.directLineClient = rp(this.directLineSpecUrl) this.directLineClient = rp(this.directLineSpecUrl)
.then(function (spec) { .then((spec) => {
return new Swagger({ return new Swagger({
spec: JSON.parse(spec.trim()), spec: JSON.parse(spec.trim()),
usePromise: true usePromise: true
}); });
}) })
.then(function (client) { .then(async (client) => {
client.clientAuthorizations.add('AuthorizationBotConnector', client.clientAuthorizations.add('AuthorizationBotConnector',
new Swagger.ApiKeyAuthorization('Authorization', 'Bearer ' + new Swagger.ApiKeyAuthorization('Authorization', 'Bearer ' +
directLineSecret, 'header')); directLineSecret, 'header'));
var options = {
method: 'POST',
url: UrlJoin(this.whatsappServiceUrl, "webhook"),
qs:
{
token: this.whatsappServiceKey,
webhookUrl: `https://cec02d94.ngrok.io/instances/${this.botId}/whatsapp`
},
headers:
{
'cache-control': 'no-cache'
}
};
try {
const result = await request.post(options);
} catch (error) {
logger.error('Error initializing DirectLine client', error);
}
return client; return client;
}) })
.catch(function (err) { .catch((err) => {
logger.error('Error initializing DirectLine client', err); logger.error('Error initializing DirectLine client', err);
}); });
} }
received(req, res) { received(req, res) {
let text = req.body.messages[0].body;
let from = req.body.messages[0].author.split('@')[0];
let fromName = req.body.messages[0].senderName;
logger.info(`GBWhatsapp: Hook called. Event: ${req.body.event}, if (req.body.messages[0].fromMe){
muid: ${req.body.muid}, contact: ${req.body.contact.name}, return; // Exit here.
(${req.body.contact.uid}, ${req.body.contact.type})`); }
let conversationId = null; // req.body.cuid; logger.info(`GBWhatsapp: Hook called. from: ${from}(${fromName}), text: ${text})`);
let text = req.body.message.body.text;
let from = req.body.contact.uid; let conversationId = this.conversationIds[from];
let fromName = req.body.contact.name;
this.directLineClient.then((client) => { this.directLineClient.then((client) => {
if (conversationId == null) { if (this.conversationIds[from] == null) {
logger.info(`GBWhatsapp: Starting new conversation on Bot.`); logger.info(`GBWhatsapp: Starting new conversation on Bot.`);
client.Conversations.Conversations_StartConversation() client.Conversations.Conversations_StartConversation()
@ -104,6 +134,8 @@ export class WhatsappDirectLine extends GBService {
}) })
.then((conversationId) => { .then((conversationId) => {
this.conversationIds[from] = conversationId;
this.inputMessage(client, conversationId, text, this.inputMessage(client, conversationId, text,
from, fromName); from, fromName);
@ -139,7 +171,7 @@ export class WhatsappDirectLine extends GBService {
}, },
replyToId: from replyToId: from
} }
}).catch(function (err) { }).catch((err) => {
logger.error(`GBWhatsapp: Error receiving message: ${err}.`); logger.error(`GBWhatsapp: Error receiving message: ${err}.`);
}); });
@ -162,31 +194,32 @@ export class WhatsappDirectLine extends GBService {
return response.obj.activities; return response.obj.activities;
}) })
.then((activities) => { .then((activities) => {
this.printMessages(activities, from, fromName); this.printMessages(activities, conversationId, from, fromName);
}); });
}, this.pollInterval); }, this.pollInterval);
} }
printMessages(activities,from, fromName) { printMessages(activities, conversationId, from, fromName) {
if (activities && activities.length) { if (activities && activities.length) {
// Ignore own messages. // Ignore own messages.
activities = activities.filter((m) => { return m.from.id === this.botId }); activities = activities.filter((m) => { return m.from.id === this.botId && m.type === "message"});
if (activities.length) { if (activities.length) {
// Print other messages. // Print other messages.
activities.forEach(activity => { this.printMessage(activities[0], conversationId, from, fromName);
this.printMessage(activity, from, fromName); // activities.forEach(activity => {
}); // this.printMessage(activity, conversationId, from, fromName);
// });
} }
} }
} }
printMessage(activity, from, fromName) { printMessage(activity, conversationId, from, fromName) {
let output: string; let output: string;
@ -196,7 +229,7 @@ export class WhatsappDirectLine extends GBService {
} }
if (activity.attachments) { if (activity.attachments) {
activity.attachments.forEach(function (attachment) { activity.attachments.forEach((attachment) => {
switch (attachment.contentType) { switch (attachment.contentType) {
case "application/vnd.microsoft.card.hero": case "application/vnd.microsoft.card.hero":
output += this.renderHeroCard(attachment); output += this.renderHeroCard(attachment);
@ -210,7 +243,7 @@ export class WhatsappDirectLine extends GBService {
}); });
} }
this.sendToDevice(from, fromName, output); this.sendToDevice(conversationId, from, fromName, output);
} }
renderHeroCard(attachment) { renderHeroCard(attachment) {
@ -230,17 +263,15 @@ export class WhatsappDirectLine extends GBService {
output += '*'.repeat(width + 1) + '/'; output += '*'.repeat(width + 1) + '/';
} }
async sendToDevice(to, toName, msg) { async sendToDevice(conversationId, to, toName, msg) {
var options = { var options = {
method: 'POST', method: 'POST',
url: 'https://www.waboxapp.com/api/send/chat', url: UrlJoin(this.whatsappServiceUrl, 'message'),
qs: qs:
{ {
token: this.whatsappServiceKey, token: this.whatsappServiceKey,
uid: this.whatsappServiceNumber, phone: to,
to: to, body: msg
custom_uid: 'GBZAP' + (new Date()).toISOString,
text: msg
}, },
headers: headers:
{ {

View file

@ -1,6 +1,6 @@
{ {
"name": "botserver", "name": "botserver",
"version": "0.0.19", "version": "0.0.20",
"description": "General Bot Community Edition open-core server.", "description": "General Bot Community Edition open-core server.",
"contributors": [ "contributors": [
"Rodrigo Rodriguez <me@rodrigorodriguez.com>" "Rodrigo Rodriguez <me@rodrigorodriguez.com>"
@ -32,7 +32,7 @@
"async": "^1.5.2", "async": "^1.5.2",
"body-parser": "^1.18.2", "body-parser": "^1.18.2",
"botbuilder": "^3.14.0", "botbuilder": "^3.14.0",
"botlib": "0.0.18", "botlib": "0.0.19",
"chai": "^4.1.2", "chai": "^4.1.2",
"chokidar": "^2.0.2", "chokidar": "^2.0.2",
"csv-parse": "^2.4.0", "csv-parse": "^2.4.0",

View file

@ -61,7 +61,7 @@ var logger = new (winston.Logger)({
logger.add(winston.transports.Console, { logger.add(winston.transports.Console, {
label: 'General Bot Server', label: 'General Bot Server',
level: 'info', level: 'error',
prettyPrint: true, prettyPrint: true,
colorize: true, colorize: true,
silent: false, silent: false,
@ -71,7 +71,7 @@ logger.add(winston.transports.Console, {
logger.add(winston.transports.File, { logger.add(winston.transports.File, {
label: 'General Bot Server', label: 'General Bot Server',
prettyPrint: true, prettyPrint: true,
level: 'info', level: 'error',
silent: false, silent: false,
colorize: false, colorize: false,
timestamp: true, timestamp: true,