new(whatsapp.gblib): Bot in groups.

This commit is contained in:
Rodrigo Rodriguez 2021-12-18 21:31:49 -03:00
parent fefcbb04bf
commit 74e0a01f6a
4 changed files with 89 additions and 52 deletions

View file

@ -286,9 +286,9 @@ export class GBConversationalService {
});
}
public async sendToMobile(min: GBMinInstance, mobile: string, message: string) {
public async sendToMobile(min: GBMinInstance, mobile: string, message: string, conversationId ) {
GBLog.info(`Sending message ${message} to ${mobile}...`);
await min.whatsAppDirectLine.sendToDevice(mobile, message);
await min.whatsAppDirectLine.sendToDevice(mobile, message, conversationId);
}
public static async getTextFromAudioBuffer(speechKey, cloudRegion, buffer, locale): Promise<string> {
@ -510,7 +510,7 @@ export class GBConversationalService {
if (!mobile) {
await step.context.sendActivity(currentText);
} else {
await this.sendToMobile(min, mobile, currentText);
await this.sendToMobile(min, mobile, currentText, step.context.activity.conversation.id);
}
await sleep(3000);
currentText = '';
@ -530,7 +530,7 @@ export class GBConversationalService {
if (!mobile) {
await step.context.sendActivity(currentText);
} else {
await this.sendToMobile(min, mobile, currentText);
await this.sendToMobile(min, mobile, currentText, step.context.activity.conversation.id);
}
await sleep(3000);
}
@ -563,7 +563,7 @@ export class GBConversationalService {
if (!mobile) {
await step.context.sendActivity(currentText);
} else {
await this.sendToMobile(min, mobile, currentText);
await this.sendToMobile(min, mobile, currentText, step.context.activity.conversation.id);
}
await sleep(2900);
}
@ -608,7 +608,7 @@ export class GBConversationalService {
await step.context.sendActivity(currentText);
} else {
GBLog.info(`Sending .MD file to mobile: ${mobile}.`);
await this.sendToMobile(min, mobile, currentText);
await this.sendToMobile(min, mobile, currentText, step.context.activity.conversation.id);
}
}
}
@ -888,7 +888,7 @@ export class GBConversationalService {
analytics.createMessage(min.instance.instanceId, user.conversation, null, text);
if (!isNaN(member.id) && !member.id.startsWith('1000')) {
await min.whatsAppDirectLine.sendToDevice(member.id, text);
await min.whatsAppDirectLine.sendToDevice(member.id, text, step.context.activity.conversation.id);
} else {
await step.context.sendActivity(text);
}

View file

@ -173,7 +173,7 @@ export class GBMinService {
});
GBLog.info(`Package deployment done.`);
}
@ -302,17 +302,22 @@ export class GBMinService {
private async WhatsAppCallback(req, res) {
try {
// Detects if the message is echo fro itself.
// Detects if the message is echo from itself.
const id = req.body.messages[0].chatId.split('@')[0];
const id = req.body.messages[0].author.split('@')[0];
const senderName = req.body.messages[0].senderName;
const text = req.body.messages[0].body;
if (req.body.messages[0].fromMe) {
res.end();
return; // Exit here.
}
// Processes group behaviour.
let text = req.body.messages[0].body;
text = text.replace(/\@\d+ /gi, '');
// Detects if the welcome message is enabled.
let activeMin;
@ -358,7 +363,7 @@ export class GBMinService {
await (activeMin as any).whatsAppDirectLine.sendToDevice(
id,
`Olá! Seja bem-vinda(o)!\nMe chamo ${activeMin.instance.title}. Como posso ajudar? Pode me falar que eu te ouço, me manda um aúdio.`
);
, null);
res.end();
}
} else {
@ -383,8 +388,11 @@ export class GBMinService {
} else {
await (activeMin as any).whatsAppDirectLine.sendToDevice(
id,
`Agora falando com ${activeMin.instance.title}...`
`Agora falando com ${activeMin.instance.title}...`,
null
);
}
res.end();
} else {
@ -815,6 +823,9 @@ export class GBMinService {
await adapter['processActivity'](req, res, async context => {
context.activity.text = context.activity.text.replace(/\@General Bots Online /gi, '');
// Get loaded user state
const step = await min.dialogs.createContext(context);
@ -887,7 +898,7 @@ export class GBMinService {
if (step.context.activity.channelId === 'msteams') {
if (step.context.activity.attachments && step.context.activity.attachments.length > 1) {
const file = context.activity.attachments[0];
const credentials = new MicrosoftAppCredentials(min.instance.marketplaceId, min.instance.marketplacePassword);
const botToken = await credentials.getToken();
@ -895,10 +906,9 @@ export class GBMinService {
const t = new SystemKeywords(null, null, null);
const data = await t.getByHttp(file.contentUrl, headers, null, null, null, true);
const folder = `work/${min.instance.botId}.gbai/cache`;
const filename =`${GBAdminService.generateUuid()}.png`;
const filename = `${GBAdminService.generateUuid()}.png`;
if (!Fs.existsSync(folder))
{
if (!Fs.existsSync(folder)) {
Fs.mkdirSync(folder);
}
@ -1268,7 +1278,8 @@ export class GBMinService {
}
}
else {
await min.whatsAppDirectLine.sendToDeviceEx(manualUser.userSystemId, `${manualUser.agentSystemId}: ${text}`, locale);
await min.whatsAppDirectLine.sendToDeviceEx(manualUser.userSystemId, `${manualUser.agentSystemId}: ${text}`, locale,
step.context.activity.conversation.id);
}
}
else {

View file

@ -130,14 +130,15 @@ export class FeedbackDialog extends IGBDialog {
const manualUser = await sec.getUserFromAgentSystemId(userSystemId);
await min.whatsAppDirectLine.sendToDeviceEx(manualUser.userSystemId,
Messages[locale].notify_end_transfer(min.instance.botId), locale);
Messages[locale].notify_end_transfer(min.instance.botId), locale, step.context.activity.conversation.id);
if (userSystemId.charAt(2) === ":" || userSystemId.indexOf('@') > -1) { // Agent is from Teams or Google Chat.
await min.conversationalService.sendText(min, step, Messages[locale].notify_end_transfer(min.instance.botId));
}
else {
await min.whatsAppDirectLine.sendToDeviceEx(userSystemId,
Messages[locale].notify_end_transfer(min.instance.botId), locale);
Messages[locale].notify_end_transfer(min.instance.botId), locale
, step.context.activity.conversation.id);
}
await sec.updateHumanAgent(userSystemId, min.instance.instanceId, null);
@ -152,7 +153,7 @@ export class FeedbackDialog extends IGBDialog {
const agent = await sec.getUserFromSystemId(user.systemUser.agentSystemId);
await min.whatsAppDirectLine.sendToDeviceEx(user.systemUser.userSystemId,
Messages[locale].notify_end_transfer(min.instance.botId), locale);
Messages[locale].notify_end_transfer(min.instance.botId), locale, step.context.activity.conversation.id);
if (user.systemUser.agentSystemId.charAt(2) === ":" || userSystemId.indexOf('@') > -1) { // Agent is from Teams or Google Chat.
@ -160,7 +161,7 @@ export class FeedbackDialog extends IGBDialog {
}
else {
await min.whatsAppDirectLine.sendToDeviceEx(user.systemUser.agentSystemId,
Messages[locale].notify_end_transfer(min.instance.botId), locale);
Messages[locale].notify_end_transfer(min.instance.botId), locale, step.context.activity.conversation.id);
}
await sec.updateHumanAgent(user.systemUser.userSystemId, min.instance.instanceId, null);
@ -177,12 +178,10 @@ export class FeedbackDialog extends IGBDialog {
}
else {
await min.whatsAppDirectLine.sendToDeviceEx(user.systemUser.userSystemId,
'Nenhum atendimento em andamento.');
'Nenhum atendimento em andamento.', locale, step.context.activity.conversation.id);
}
}
return await step.next();
}
])

View file

@ -49,6 +49,8 @@ export class WhatsappDirectLine extends GBService {
public static conversationIds = {};
public static mobiles = {};
public static chatIds = {};
public pollInterval = 5000;
public directLineClientName = 'DirectLineClient';
@ -87,7 +89,7 @@ export class WhatsappDirectLine extends GBService {
}
public async setup(setUrl) {
this.directLineClient =
new Swagger({
spec: JSON.parse(fs.readFileSync('directline-3.0.json', 'utf8')),
@ -130,8 +132,8 @@ export class WhatsappDirectLine extends GBService {
}
public async resetConversationId(number) {
WhatsappDirectLine.conversationIds[number] = undefined;
public async resetConversationId(number, group) {
WhatsappDirectLine.conversationIds[number+group] = undefined;
}
public async check() {
@ -159,7 +161,27 @@ export class WhatsappDirectLine extends GBService {
}
const message = req.body.messages[0];
let group = "";
// Ignore group messages without the mention to Bot.
if (message.chatName.charAt(0) !== '+') {
group = message.chatName;
let smsServiceNumber = this.min.core.getParam<string>(this.min.instance, 'whatsappServiceNumber', null);;
if (smsServiceNumber) {
smsServiceNumber = smsServiceNumber.replace('+', '');
if (!message.body.startsWith('@' + smsServiceNumber)) {
return;
}
}
}
let text = message.body;
text = text.replace(/\@\d+ /gi, '');
const from = message.author.split('@')[0];
const fromName = message.senderName;
@ -174,7 +196,7 @@ export class WhatsappDirectLine extends GBService {
await e.onExchangeData(this.min, 'whatsappMessage', message);
});
const id = req.body.messages[0].chatId.split('@')[0].replace('true_','').replace('false_','');
const id = req.body.messages[0].chatId.split('@')[0].replace('true_', '').replace('false_', '');
const senderName = req.body.messages[0].senderName;
const sec = new SecService();
@ -199,11 +221,12 @@ export class WhatsappDirectLine extends GBService {
buf, locale
);
} else {
await this.sendToDevice(user.userSystemId, `No momento estou apenas conseguindo ler mensagens de texto.`);
await this.sendToDevice(user.userSystemId,
`No momento estou apenas conseguindo ler mensagens de texto.`, null);
}
}
const conversationId = WhatsappDirectLine.conversationIds[from];
const conversationId = WhatsappDirectLine.conversationIds[from + group];
const client = await this.directLineClient;
@ -218,7 +241,7 @@ export class WhatsappDirectLine extends GBService {
if (manualUser === null) {
await sec.updateHumanAgent(id, this.min.instance.instanceId, null);
} else {
const agent = await sec.getUserFromSystemId(user.agentSystemId);
@ -229,28 +252,28 @@ export class WhatsappDirectLine extends GBService {
if (message === null) {
await this.sendToDeviceEx(user.userSystemId, `File ${filename} not found in any .gbkb published. Check the name or publish again the associated .gbkb.`,
locale);
locale, null);
} else {
await this.min.conversationalService.sendMarkdownToMobile(this.min, null, user.userSystemId, message);
}
} else if (text === '/qt') {
// TODO: Transfers only in pt-br for now.
await this.sendToDeviceEx(manualUser.userSystemId,
Messages[this.locale].notify_end_transfer(this.min.instance.botId), locale);
Messages[this.locale].notify_end_transfer(this.min.instance.botId), locale, null);
if (user.agentSystemId.charAt(2) === ":") { // Agent is from Teams.
await this.min.conversationalService['sendOnConversation'](this.min, agent, Messages[this.locale].notify_end_transfer(this.min.instance.botId));
}
else {
await this.sendToDeviceEx(user.agentSystemId,
Messages[this.locale].notify_end_transfer(this.min.instance.botId), locale);
Messages[this.locale].notify_end_transfer(this.min.instance.botId), locale, null);
}
await sec.updateHumanAgent(manualUser.userSystemId, this.min.instance.instanceId, null);
await sec.updateHumanAgent(user.agentSystemId, this.min.instance.instanceId, null);
} else {
GBLog.info(`HUMAN AGENT (${manualUser.agentSystemId}) TO USER ${manualUser.userSystemId}: ${text}`);
await this.sendToDeviceEx(manualUser.userSystemId, `AGENTE: *${text}*`, locale);
await this.sendToDeviceEx(manualUser.userSystemId, `AGENTE: *${text}*`, locale, null);
}
}
@ -259,18 +282,18 @@ export class WhatsappDirectLine extends GBService {
const agent = await sec.getUserFromSystemId(user.agentSystemId);
if (text === '/t') {
await this.sendToDeviceEx(user.userSystemId, `Você já está sendo atendido por ${agent.userSystemId}.`, locale);
await this.sendToDeviceEx(user.userSystemId, `Você já está sendo atendido por ${agent.userSystemId}.`, locale, null);
} else if (text === '/qt' || text === 'Sair' || text === 'Fechar') {
// TODO: Transfers only in pt-br for now.
await this.sendToDeviceEx(id,
Messages[this.locale].notify_end_transfer(this.min.instance.botId), locale);
Messages[this.locale].notify_end_transfer(this.min.instance.botId), locale, null);
if (user.agentSystemId.charAt(2) === ":") { // Agent is from Teams.
await this.min.conversationalService['sendOnConversation'](this.min, agent, Messages[this.locale].notify_end_transfer(this.min.instance.botId));
}
else {
await this.sendToDeviceEx(user.agentSystemId, Messages[this.locale].notify_end_transfer(this.min.instance.botId), locale);
}
if (user.agentSystemId.charAt(2) === ":") { // Agent is from Teams.
await this.min.conversationalService['sendOnConversation'](this.min, agent, Messages[this.locale].notify_end_transfer(this.min.instance.botId));
}
else {
await this.sendToDeviceEx(user.agentSystemId, Messages[this.locale].notify_end_transfer(this.min.instance.botId), locale, null);
}
await sec.updateHumanAgent(id, this.min.instance.instanceId, null);
} else {
@ -280,20 +303,21 @@ export class WhatsappDirectLine extends GBService {
await this.min.conversationalService['sendOnConversation'](this.min, agent, text);
}
else {
await this.sendToDeviceEx(user.agentSystemId, `Bot: ${this.min.instance.botId}\n${id}: ${text}`, locale);
await this.sendToDeviceEx(user.agentSystemId, `Bot: ${this.min.instance.botId}\n${id}: ${text}`, locale, null);
}
}
} else if (user.agentMode === 'bot' || user.agentMode === null || user.agentMode === undefined) {
if (WhatsappDirectLine.conversationIds[from] === undefined) {
if (WhatsappDirectLine.conversationIds[from + group] === undefined) {
GBLog.info(`GBWhatsapp: Starting new conversation on Bot.`);
const response = await client.Conversations.Conversations_StartConversation();
const generatedConversationId = response.obj.conversationId;
WhatsappDirectLine.conversationIds[from] = generatedConversationId;
WhatsappDirectLine.conversationIds[from + group] = generatedConversationId;
WhatsappDirectLine.mobiles[generatedConversationId] = from;
WhatsappDirectLine.chatIds[generatedConversationId] = message.chatId;
this.pollMessages(client, generatedConversationId, from, fromName);
this.inputMessage(client, generatedConversationId, text, from, fromName);
@ -387,7 +411,7 @@ export class WhatsappDirectLine extends GBService {
});
}
await this.sendToDevice(from, output);
await this.sendToDevice(from, output, conversationId);
}
public renderHeroCard(attachment) {
@ -454,7 +478,7 @@ export class WhatsappDirectLine extends GBService {
await this.sendFileToDevice(to, url, 'Audio', msg);
}
public async sendToDevice(to: string, msg: string) {
public async sendToDevice(to: string, msg: string, conversationId ) {
const cmd = '/audio ';
if (msg.startsWith(cmd)) {
@ -463,12 +487,15 @@ export class WhatsappDirectLine extends GBService {
return await this.sendTextAsAudioToDevice(to, msg);
} else {
let chatId = WhatsappDirectLine.chatIds[conversationId];
const options = {
method: 'POST',
url: urlJoin(this.whatsappServiceUrl, 'message'),
qs: {
token: this.whatsappServiceKey,
phone: to,
phone: chatId ? null : to,
chatId: chatId,
body: msg
},
headers: {
@ -488,13 +515,13 @@ export class WhatsappDirectLine extends GBService {
}
}
public async sendToDeviceEx(to, text, locale) {
public async sendToDeviceEx(to, text, locale, conversationId) {
text = await this.min.conversationalService.translate(
this.min,
text,
locale
);
await this.sendToDevice(to, text);
await this.sendToDevice(to, text, conversationId);
}
}