Building 3rd party service webhook for Whatsapp.gblib.
Signed-off-by: Rodrigo Rodriguez <me@rodrigorodriguez.com>
This commit is contained in:
parent
ba85db06dd
commit
1d0dc4cf25
5 changed files with 145 additions and 112 deletions
43
README.md
43
README.md
|
@ -1,9 +1,9 @@
|
||||||

|

|
||||||
|
|
||||||
Welcome to General Bots Community Edition
|
Welcome to General Bot Community Edition
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
General Bots is a package based chat bot server focused in convention
|
General Bot is a package based chat bot server focused in convention
|
||||||
over configuration and code-less approaches, which brings software packages
|
over configuration and code-less approaches, which brings software packages
|
||||||
and application server concepts to help parallel bot development.
|
and application server concepts to help parallel bot development.
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ How To
|
||||||
|
|
||||||
### Run the server locally
|
### Run the server locally
|
||||||
|
|
||||||
1. Install [Node.js](https://www.npmjs.com/get-npm) the current generation General Bots code execution platform;
|
1. Install [Node.js](https://www.npmjs.com/get-npm) the current generation General Bot code execution platform;
|
||||||
2. Open a **Terminal** on Linux and Mac or a **Command Prompt** window on Windows;npm
|
2. Open a **Terminal** on Linux and Mac or a **Command Prompt** window on Windows;npm
|
||||||
3. Type `npm install -g botserver` and press *ENTER*;
|
3. Type `npm install -g botserver` and press *ENTER*;
|
||||||
4. Type `gbot` to run the server core.
|
4. Type `gbot` to run the server core.
|
||||||
|
@ -39,7 +39,7 @@ How To
|
||||||
Notes:
|
Notes:
|
||||||
|
|
||||||
* [*nodejs.install* Chocolatey Package](https://chocolatey.org/packages/nodejs.install) is also available.
|
* [*nodejs.install* Chocolatey Package](https://chocolatey.org/packages/nodejs.install) is also available.
|
||||||
* The zip source code of general bots is also available for [Download](https://codeload.github.com/pragmatismo-io/BotServer/zip/master);
|
* The zip source code of General Bot is also available for [Download](https://codeload.github.com/pragmatismo-io/BotServer/zip/master);
|
||||||
|
|
||||||
### Configure the server to deploy specific directory
|
### Configure the server to deploy specific directory
|
||||||
|
|
||||||
|
@ -56,19 +56,21 @@ Note:
|
||||||
1. [Optional] Install [Chocolatey](https://chocolatey.org/install), a Windows Package Manager;
|
1. [Optional] Install [Chocolatey](https://chocolatey.org/install), a Windows Package Manager;
|
||||||
2. Install [git](`https://git-scm.com/`), a Software Configuration Management (SCM).;
|
2. Install [git](`https://git-scm.com/`), a Software Configuration Management (SCM).;
|
||||||
3. Install [Node.js](npmjs.com/get-npm), a [Runtime system](https://en.wikipedia.org/wiki/Runtime_system).
|
3. Install [Node.js](npmjs.com/get-npm), a [Runtime system](https://en.wikipedia.org/wiki/Runtime_system).
|
||||||
(https://www.npmjs.com/get-npm);
|
(https://www.npmjs.com/get-npm) (suggested: LTS 8.x.x);
|
||||||
4. Install [Visual Studio Code](https://chocolatey.org/packages/nodejs.install), Brackets or Atom as an editor of your choice;
|
4. Install [Visual Studio Code](https://chocolatey.org/packages/nodejs.install), Brackets or Atom as an editor of your choice;
|
||||||
5. [Fork](https://en.wikipedia.org/wiki/Fork_(software_development)) by visiting https://github.com/pragmatismo-io/BotServer/fork
|
5. [Fork](https://en.wikipedia.org/wiki/Fork_(software_development)) by visiting https://github.com/pragmatismo-io/BotServer/fork
|
||||||
6. Clone the just forked repository by running `git clone <your-forked-repository-url>/BotServer.git` ;
|
6. Clone the just forked repository by running `git clone <your-forked-repository-url>/BotServer.git` ;
|
||||||
7. Run `npm install` on Command Prompt or PowerShell on the General Bots source-code folder;
|
7. Run `npm install -g typescript`;
|
||||||
8. Enter './deploy/default.gbui' folder;
|
8. Run `npm install` on Command Prompt or PowerShell on the General Bot source-code folder;
|
||||||
9. Run `npm install` folled by `npm run build` (To build default Bot UI);
|
9. Enter './deploy/default.gbui' folder;
|
||||||
10. Enter the On the downloaded folder (../..);
|
10. Run `npm install` folled by `npm run build` (To build default Bot UI);
|
||||||
11. Run the bot server by `npm start`.
|
11. Enter the On the downloaded folder (../..);
|
||||||
|
12. Compile the bot server by `tsc`.
|
||||||
|
13. Run the bot server by `npm start`.
|
||||||
|
|
||||||
Note:
|
Note:
|
||||||
|
|
||||||
* Whenever you are ready to turn your open-source bot ideas in form of .gbapp (source-code) and artifacts like .gbkb, .gbtheme, .gbot or the .gbai full package read [CONTRIBUTING.md](https://github.com/pragmatismo-io/BotServer/blob/master/CONTRIBUTING.md) about performing Pull Requests (PR) and creating other public custom packages repositories of your own personal or organization General Bots Community Edition powered packages.
|
* Whenever you are ready to turn your open-source bot ideas in form of .gbapp (source-code) and artifacts like .gbkb, .gbtheme, .gbot or the .gbai full package read [CONTRIBUTING.md](https://github.com/pragmatismo-io/BotServer/blob/master/CONTRIBUTING.md) about performing Pull Requests (PR) and creating other public custom packages repositories of your own personal or organization General Bot Community Edition powered packages.
|
||||||
|
|
||||||
### Just copy the source code to your machine
|
### Just copy the source code to your machine
|
||||||
|
|
||||||
|
@ -81,7 +83,7 @@ The subjects.json file contains all information related to the subject tree and
|
||||||
### Creating a new Theme folder (.gbtheme folder)
|
### Creating a new Theme folder (.gbtheme folder)
|
||||||
|
|
||||||
A theme is composed of some CSS files and images. That set of files can change
|
A theme is composed of some CSS files and images. That set of files can change
|
||||||
everything in the General Bots UI. Use them extensively before going to change
|
everything in the General Bot UI. Use them extensively before going to change
|
||||||
the UI application itself (HTML & JS).
|
the UI application itself (HTML & JS).
|
||||||
|
|
||||||
Package Types
|
Package Types
|
||||||
|
@ -97,10 +99,10 @@ directory.
|
||||||
The artificial intelligence extensions in form of pluggable apps. Dialogs,
|
The artificial intelligence extensions in form of pluggable apps. Dialogs,
|
||||||
Services and all model related to data. A set of interactions, use cases,
|
Services and all model related to data. A set of interactions, use cases,
|
||||||
integrations in form of conversationals dialogs.
|
integrations in form of conversationals dialogs.
|
||||||
The .gbapp adds the General Bots base library (botlib) for building Node.js TypeScript Apps packages.
|
The .gbapp adds the General Bot base library (botlib) for building Node.js TypeScript Apps packages.
|
||||||
|
|
||||||
|
|
||||||
Four components builds up a General Bots App:
|
Four components builds up a General Bot App:
|
||||||
|
|
||||||
* dialogs
|
* dialogs
|
||||||
* models
|
* models
|
||||||
|
@ -122,7 +124,6 @@ Models builds the foundation of data relationships in form of entities.
|
||||||
|
|
||||||
Services are a façade for bot back-end logic and other custom processing.
|
Services are a façade for bot back-end logic and other custom processing.
|
||||||
|
|
||||||
|
|
||||||
#### Tests
|
#### Tests
|
||||||
|
|
||||||
Tests try to automate code execution validation before crashing in production.
|
Tests try to automate code execution validation before crashing in production.
|
||||||
|
@ -152,7 +153,7 @@ Reference
|
||||||
|
|
||||||
### GeneralBots admin commands
|
### GeneralBots admin commands
|
||||||
|
|
||||||
General Bots can be controlled by the same chat window people talk to, so
|
General Bot can be controlled by the same chat window people talk to, so
|
||||||
here is a list of admin commands related to deploying .gb* files.
|
here is a list of admin commands related to deploying .gb* files.
|
||||||
|
|
||||||
| Command | Description |
|
| Command | Description |
|
||||||
|
@ -167,17 +168,17 @@ here is a list of admin commands related to deploying .gb* files.
|
||||||
* Rodrigo Rodriguez (me@rodrigorodriguez.com) - Coding, Docs & Architecture.
|
* Rodrigo Rodriguez (me@rodrigorodriguez.com) - Coding, Docs & Architecture.
|
||||||
* David Lerner (david.lerner@hotmail.com) - UI, UX & Theming
|
* David Lerner (david.lerner@hotmail.com) - UI, UX & Theming
|
||||||
* Eduardo Romeiro (eromeirosp@outlook.com) - Content & UX
|
* Eduardo Romeiro (eromeirosp@outlook.com) - Content & UX
|
||||||
|
* Jorge Ramos (jramos@pobox.com) - Coding, Docs & Architecture.
|
||||||
|
|
||||||
Powered by Microsoft [BOT Framework](https://dev.botframework.com/) and [Azure](http://www.azure.com).
|
Powered by Microsoft [BOT Framework](https://dev.botframework.com/) and [Azure](http://www.azure.com).
|
||||||
|
|
||||||
General Bots Code Name is [Guaribas](https://en.wikipedia.org/wiki/Guaribas), the name of a city in Brasil, state of Piaui.
|
General Bot Code Name is [Guaribas](https://en.wikipedia.org/wiki/Guaribas), the name of a city in Brasil, state of Piaui.
|
||||||
[Roberto Mangabeira Unger](http://www.robertounger.com/en/): "No one should have to do work that can be done by a machine".
|
[Roberto Mangabeira Unger](http://www.robertounger.com/en/): "No one should have to do work that can be done by a machine".
|
||||||
|
|
||||||
|
|
||||||
## License & Warranty
|
## License & Warranty
|
||||||
|
|
||||||
General Bots Copyright (c) Pragmatismo.io. All rights reserved.
|
General Bot Copyright (c) Pragmatismo.io. All rights reserved.
|
||||||
Licensed under the AGPL-3.0.
|
Licensed under the AGPL-3.0.
|
||||||
|
|
||||||
According to our dual licensing model, this program can be used either
|
According to our dual licensing model, this program can be used either
|
||||||
|
@ -193,7 +194,7 @@ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU Affero General Public License for more details.
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
"General Bots" is a registered trademark of Pragmatismo.io.
|
"General Bot" is a registered trademark of Pragmatismo.io.
|
||||||
The licensing of the program under the AGPLv3 does not imply a
|
The licensing of the program under the AGPLv3 does not imply a
|
||||||
trademark license. Therefore any rights, title and interest in
|
trademark license. Therefore any rights, title and interest in
|
||||||
our trademarks remain entirely with us.
|
our trademarks remain entirely with us.
|
||||||
|
|
|
@ -95,6 +95,8 @@ export class GuaribasInstance extends Model<GuaribasInstance> implements IGBInst
|
||||||
|
|
||||||
@Column whatsappServiceKey: string;
|
@Column whatsappServiceKey: string;
|
||||||
|
|
||||||
|
@Column whatsappServiceNumber: string;
|
||||||
|
|
||||||
@Column spellcheckerKey: string;
|
@Column spellcheckerKey: string;
|
||||||
|
|
||||||
@Column theme: string;
|
@Column theme: string;
|
||||||
|
|
|
@ -42,6 +42,7 @@ import { WhatsappDirectLine } from "./services/WhatsappDirectLine";
|
||||||
|
|
||||||
|
|
||||||
export class GBWhatsappPackage implements IGBPackage {
|
export class GBWhatsappPackage implements IGBPackage {
|
||||||
|
|
||||||
sysPackages: IGBPackage[] = null;
|
sysPackages: IGBPackage[] = null;
|
||||||
channel: WhatsappDirectLine;
|
channel: WhatsappDirectLine;
|
||||||
|
|
||||||
|
@ -53,7 +54,8 @@ export class GBWhatsappPackage implements IGBPackage {
|
||||||
}
|
}
|
||||||
|
|
||||||
loadBot(min: GBMinInstance): void {
|
loadBot(min: GBMinInstance): void {
|
||||||
this.channel = new WhatsappDirectLine(min.instance.whatsappBotKey);
|
this.channel = new WhatsappDirectLine(min.botId, min.instance.whatsappBotKey, min.instance.whatsappServiceKey,
|
||||||
|
min.instance.whatsappServiceNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
unloadBot(min: GBMinInstance): void {
|
unloadBot(min: GBMinInstance): void {
|
||||||
|
|
|
@ -47,18 +47,23 @@ import { GBServiceCallback, GBService, IGBInstance } from "botlib";
|
||||||
export class WhatsappDirectLine extends GBService {
|
export class WhatsappDirectLine extends GBService {
|
||||||
|
|
||||||
pollInterval = 1000;
|
pollInterval = 1000;
|
||||||
directLineSecret = '';
|
|
||||||
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;
|
||||||
|
whatsappServiceKey: string;
|
||||||
|
whatsappServiceNumber: string;
|
||||||
|
botId: string;
|
||||||
|
|
||||||
|
constructor(botId, directLineSecret, whatsappServiceKey, whatsappServiceNumber) {
|
||||||
|
|
||||||
constructor(directLineSecret) {
|
|
||||||
super();
|
super();
|
||||||
|
|
||||||
this.directLineSecret = directLineSecret;
|
this.botId = botId;
|
||||||
|
this.whatsappServiceKey = whatsappServiceKey;
|
||||||
|
this.whatsappServiceNumber = whatsappServiceNumber;
|
||||||
|
|
||||||
// TODO: Migrate to Swagger 3.
|
// TODO: Migrate to Swagger 3.
|
||||||
let directLineClient = rp(this.directLineSpecUrl)
|
this.directLineClient = rp(this.directLineSpecUrl)
|
||||||
.then(function (spec) {
|
.then(function (spec) {
|
||||||
return new Swagger({
|
return new Swagger({
|
||||||
spec: JSON.parse(spec.trim()),
|
spec: JSON.parse(spec.trim()),
|
||||||
|
@ -67,147 +72,173 @@ export class WhatsappDirectLine extends GBService {
|
||||||
})
|
})
|
||||||
.then(function (client) {
|
.then(function (client) {
|
||||||
client.clientAuthorizations.add('AuthorizationBotConnector',
|
client.clientAuthorizations.add('AuthorizationBotConnector',
|
||||||
new Swagger.ApiKeyAuthorization('Authorization', 'Bearer ' + directLineSecret, 'header'));
|
new Swagger.ApiKeyAuthorization('Authorization', 'Bearer ' +
|
||||||
|
directLineSecret, 'header'));
|
||||||
return client;
|
return client;
|
||||||
})
|
})
|
||||||
.catch(function (err) {
|
.catch(function (err) {
|
||||||
console.error('Error initializing DirectLine client', err);
|
logger.error('Error initializing DirectLine client', err);
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO: Remove *this* issue.
|
|
||||||
let _this = this;
|
|
||||||
directLineClient.then(function (client) {
|
|
||||||
client.Conversations.Conversations_StartConversation()
|
|
||||||
.then(function (response) {
|
|
||||||
return response.obj.conversationId;
|
|
||||||
})
|
|
||||||
.then(function (conversationId) {
|
|
||||||
_this.sendMessagesFromConsole(client, conversationId);
|
|
||||||
_this.pollMessages(client, conversationId);
|
|
||||||
})
|
|
||||||
.catch(function (err) {
|
|
||||||
console.error('Error starting conversation', err);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
received(req, res) {
|
received(req, res) {
|
||||||
logger.info(`Whatsapp called. Event: ${req.body.event}, muid: ${req.body.muid}, cuid: ${req.body.cuid}`);
|
|
||||||
|
logger.info(`GBWhatsapp: Hook called. Event: ${req.body.event},
|
||||||
|
muid: ${req.body.muid}, contact: ${req.body.contact.name},
|
||||||
|
(${req.body.contact.uid}, ${req.body.contact.type})`);
|
||||||
|
|
||||||
|
let conversationId = null; // req.body.cuid;
|
||||||
|
let text = req.body.message.body.text;
|
||||||
|
let from = req.body.contact.uid;
|
||||||
|
let fromName = req.body.contact.name;
|
||||||
|
|
||||||
|
this.directLineClient.then((client) => {
|
||||||
|
|
||||||
|
if (conversationId == null) {
|
||||||
|
|
||||||
|
logger.info(`GBWhatsapp: Starting new conversation on Bot.`);
|
||||||
|
client.Conversations.Conversations_StartConversation()
|
||||||
|
.then((response) => {
|
||||||
|
return response.obj.conversationId;
|
||||||
|
})
|
||||||
|
.then((conversationId) => {
|
||||||
|
|
||||||
|
this.inputMessage(client, conversationId, text,
|
||||||
|
from, fromName);
|
||||||
|
|
||||||
|
this.pollMessages(client, conversationId,from, fromName);
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.error('Error starting conversation', err);
|
||||||
|
});
|
||||||
|
|
||||||
|
} else {
|
||||||
|
this.inputMessage(client, conversationId, text,
|
||||||
|
from, fromName);
|
||||||
|
|
||||||
|
this.pollMessages(client, conversationId, from, fromName);
|
||||||
|
}
|
||||||
res.end();
|
res.end();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
sendMessagesFromConsole(client, conversationId) {
|
|
||||||
let _this = this;
|
inputMessage(client, conversationId, text, from, fromName) {
|
||||||
var stdin = process.openStdin();
|
|
||||||
process.stdout.write('Command> ');
|
|
||||||
stdin.addListener('data', function (e) {
|
|
||||||
var input = e.toString().trim();
|
|
||||||
if (input) {
|
|
||||||
// exit
|
|
||||||
if (input.toLowerCase() === 'exit') {
|
|
||||||
return process.exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
client.Conversations.Conversations_PostActivity(
|
client.Conversations.Conversations_PostActivity(
|
||||||
{
|
{
|
||||||
conversationId: conversationId,
|
conversationId: conversationId,
|
||||||
activity: {
|
activity: {
|
||||||
textFormat: 'plain',
|
textFormat: 'plain',
|
||||||
text: input,
|
text: text,
|
||||||
type: 'message',
|
type: 'message',
|
||||||
from: {
|
from: {
|
||||||
id: _this.directLineClientName,
|
id: from,
|
||||||
name: _this.directLineClientName
|
name: fromName
|
||||||
}
|
},
|
||||||
|
replyToId: from
|
||||||
}
|
}
|
||||||
}).catch(function (err) {
|
}).catch(function (err) {
|
||||||
console.error('Error sending message:', err);
|
logger.error(`GBWhatsapp: Error receiving message: ${err}.`);
|
||||||
});
|
});
|
||||||
|
|
||||||
process.stdout.write('Command> ');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** TBD: Poll Messages from conversation using DirectLine client */
|
|
||||||
pollMessages(client, conversationId) {
|
pollMessages(client, conversationId,from, fromName){
|
||||||
let _this = this;
|
|
||||||
console.log('Starting polling message for conversationId: ' + conversationId);
|
logger.info(`GBWhatsapp: Starting polling message for conversationId:
|
||||||
|
${conversationId}.`);
|
||||||
|
|
||||||
var watermark = null;
|
var watermark = null;
|
||||||
setInterval(function () {
|
setInterval(() => {
|
||||||
client.Conversations.Conversations_GetActivities({ conversationId: conversationId, watermark: watermark })
|
client.Conversations.Conversations_GetActivities({
|
||||||
.then(function (response) {
|
conversationId:
|
||||||
watermark = response.obj.watermark; // use watermark so subsequent requests skip old messages
|
conversationId, watermark: watermark
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
watermark = response.obj.watermark;
|
||||||
return response.obj.activities;
|
return response.obj.activities;
|
||||||
})
|
})
|
||||||
.then(_this.printMessages, _this.directLineClientName);
|
.then((activities) => {
|
||||||
|
this.printMessages(activities, from, fromName);
|
||||||
|
});
|
||||||
}, this.pollInterval);
|
}, this.pollInterval);
|
||||||
}
|
}
|
||||||
|
|
||||||
printMessages(activities, directLineClientName) {
|
printMessages(activities,from, fromName) {
|
||||||
|
|
||||||
if (activities && activities.length) {
|
if (activities && activities.length) {
|
||||||
// ignore own messages
|
|
||||||
activities = activities.filter(function (m) { return m.from.id !== directLineClientName });
|
// Ignore own messages.
|
||||||
|
|
||||||
|
activities = activities.filter((m) => { return m.from.id === this.botId });
|
||||||
|
|
||||||
if (activities.length) {
|
if (activities.length) {
|
||||||
|
|
||||||
// print other messages
|
// Print other messages.
|
||||||
|
|
||||||
activities.forEach(activity => {
|
activities.forEach(activity => {
|
||||||
console.log(activity.text);
|
this.printMessage(activity, from, fromName);
|
||||||
});
|
});
|
||||||
|
|
||||||
process.stdout.write('Command> ');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
printMessage(activity) {
|
printMessage(activity, from, fromName) {
|
||||||
|
|
||||||
|
let output: string;
|
||||||
|
|
||||||
if (activity.text) {
|
if (activity.text) {
|
||||||
console.log(activity.text);
|
logger.info(`GBWhatsapp: MSG: ${activity.text}`);
|
||||||
|
output = activity.text;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (activity.attachments) {
|
if (activity.attachments) {
|
||||||
activity.attachments.forEach(function (attachment) {
|
activity.attachments.forEach(function (attachment) {
|
||||||
switch (attachment.contentType) {
|
switch (attachment.contentType) {
|
||||||
case "application/vnd.microsoft.card.hero":
|
case "application/vnd.microsoft.card.hero":
|
||||||
this.renderHeroCard(attachment);
|
output += this.renderHeroCard(attachment);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "image/png":
|
case "image/png":
|
||||||
console.log('Opening the requested image ' + attachment.contentUrl);
|
logger.info('Opening the requested image ' + attachment.contentUrl);
|
||||||
open(attachment.contentUrl);
|
output += `\n${attachment.contentUrl}`;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.sendToDevice(from, fromName, output);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderHeroCard(attachment) {
|
renderHeroCard(attachment) {
|
||||||
var width = 70;
|
let output: string;
|
||||||
var contentLine = function (content) {
|
let width = 70;
|
||||||
|
|
||||||
|
let contentLine = function (content) {
|
||||||
return ' '.repeat((width - content.length) / 2) +
|
return ' '.repeat((width - content.length) / 2) +
|
||||||
content +
|
content +
|
||||||
' '.repeat((width - content.length) / 2);
|
' '.repeat((width - content.length) / 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('/' + '*'.repeat(width + 1));
|
output += '/' + '*'.repeat(width + 1);
|
||||||
console.log('*' + contentLine(attachment.content.title) + '*');
|
output += '*' + contentLine(attachment.content.title) + '*';
|
||||||
console.log('*' + ' '.repeat(width) + '*');
|
output += '*' + ' '.repeat(width) + '*';
|
||||||
console.log('*' + contentLine(attachment.content.text) + '*');
|
output += '*' + contentLine(attachment.content.text) + '*';
|
||||||
console.log('*'.repeat(width + 1) + '/');
|
output += '*'.repeat(width + 1) + '/';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async sendToDevice(to, toName, msg) {
|
||||||
async sendToDevice(senderID, msg) {
|
|
||||||
var options = {
|
var options = {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
url: 'https://www.waboxapp.com/api/send/chat',
|
url: 'https://www.waboxapp.com/api/send/chat',
|
||||||
qs:
|
qs:
|
||||||
{
|
{
|
||||||
token: '',
|
token: this.whatsappServiceKey,
|
||||||
uid: '55****388**',
|
uid: this.whatsappServiceNumber,
|
||||||
to: senderID,
|
to: to,
|
||||||
custom_uid: 'GBZAP' + (new Date()).toISOString,
|
custom_uid: 'GBZAP' + (new Date()).toISOString,
|
||||||
text: msg
|
text: msg
|
||||||
},
|
},
|
||||||
|
@ -218,8 +249,5 @@ export class WhatsappDirectLine extends GBService {
|
||||||
};
|
};
|
||||||
|
|
||||||
const result = await request.get(options);
|
const result = await request.get(options);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -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.16",
|
"botlib": "0.0.18",
|
||||||
"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",
|
||||||
|
|
Loading…
Add table
Reference in a new issue