- NEW: Whatsapp directline client is now working in preview.
This commit is contained in:
parent
1d0dc4cf25
commit
b122882aac
8 changed files with 79 additions and 39 deletions
|
@ -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.
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -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");
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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,10 +134,12 @@ 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);
|
||||||
|
|
||||||
this.pollMessages(client, conversationId,from, fromName);
|
this.pollMessages(client, conversationId, from, fromName);
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
console.error('Error starting conversation', err);
|
console.error('Error starting conversation', err);
|
||||||
|
@ -139,14 +171,14 @@ 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}.`);
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pollMessages(client, conversationId,from, fromName){
|
pollMessages(client, conversationId, from, fromName) {
|
||||||
|
|
||||||
logger.info(`GBWhatsapp: Starting polling message for conversationId:
|
logger.info(`GBWhatsapp: Starting polling message for conversationId:
|
||||||
${conversationId}.`);
|
${conversationId}.`);
|
||||||
|
@ -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:
|
||||||
{
|
{
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Add table
Reference in a new issue