Merge branch 'release/1.7.1'

This commit is contained in:
Davidson Gomes 2024-04-03 10:20:09 -03:00
commit 128119d494
5 changed files with 225 additions and 28 deletions

View File

@ -1,3 +1,14 @@
# 1.7.1 (2024-04-03 10:19)
### Fixed
* Correction when sending files with captions on Whatsapp Business
* Correction in receiving messages with response on WhatsApp Business
* Correction when sending a reaction to a message on WhatsApp Business
* Correction of receiving reactions on WhatsApp business
* Removed mandatory description of rows from sendList
* Feature to collect message type in typebot
# 1.7.0 (2024-03-11 18:23)
### Feature

View File

@ -406,7 +406,7 @@ export const listMessageSchema: JSONSchema7 = {
description: { type: 'string' },
rowId: { type: 'string' },
},
required: ['title', 'description', 'rowId'],
required: ['title', 'rowId'],
...isNotEmpty('title', 'description', 'rowId'),
},
},

View File

@ -10,6 +10,7 @@ export class Session {
export class PrefilledVariables {
remoteJid?: string;
pushName?: string;
messageType?: string;
additionalData?: { [key: string]: any };
}

View File

@ -269,19 +269,27 @@ export class TypebotService {
}
private getTypeMessage(msg: any) {
this.logger.verbose('get type message');
this.logger.verbose('get type message');
const types = {
conversation: msg.conversation,
extendedTextMessage: msg.extendedTextMessage?.text,
audioMessage: msg.audioMessage?.url,
imageMessage: msg.imageMessage?.url,
videoMessage: msg.videoMessage?.url,
documentMessage: msg.documentMessage?.fileName,
contactMessage: msg.contactMessage?.displayName,
locationMessage: msg.locationMessage?.degreesLatitude,
viewOnceMessageV2: msg.viewOnceMessageV2?.message?.imageMessage?.url || msg.viewOnceMessageV2?.message?.videoMessage?.url || msg.viewOnceMessageV2?.message?.audioMessage?.url,
listResponseMessage: msg.listResponseMessage?.singleSelectReply?.selectedRowId,
responseRowId: msg.listResponseMessage?.singleSelectReply?.selectedRowId,
};
const types = {
conversation: msg.conversation,
extendedTextMessage: msg.extendedTextMessage?.text,
responseRowId: msg.listResponseMessage?.singleSelectReply?.selectedRowId,
};
this.logger.verbose('type message: ' + types);
return types;
const messageType = Object.keys(types).find(key => types[key] !== undefined) || 'unknown';
this.logger.verbose('Type message: ' + JSON.stringify(types));
return { ...types, messageType };
}
private getMessageContent(types: any) {
this.logger.verbose('get message content');
const typeKey = Object.keys(types).find((key) => types[key] !== undefined);
@ -305,6 +313,101 @@ export class TypebotService {
return messageContent;
}
private getAudioMessageContent(msg: any) {
this.logger.verbose('get audio message content');
const types = this.getTypeMessage(msg);
const audioContent = types.audioMessage;
this.logger.verbose('audio message URL: ' + audioContent);
return audioContent;
}
private getImageMessageContent(msg: any) {
this.logger.verbose('get image message content');
const types = this.getTypeMessage(msg);
const imageContent = types.imageMessage;
this.logger.verbose('image message URL: ' + imageContent);
return imageContent;
}
private getVideoMessageContent(msg: any) {
this.logger.verbose('get video message content');
const types = this.getTypeMessage(msg);
const videoContent = types.videoMessage;
this.logger.verbose('video message URL: ' + videoContent);
return videoContent;
}
private getDocumentMessageContent(msg: any) {
this.logger.verbose('get document message content');
const types = this.getTypeMessage(msg);
const documentContent = types.documentMessage;
this.logger.verbose('document message fileName: ' + documentContent);
return documentContent;
}
private getContactMessageContent(msg: any) {
this.logger.verbose('get contact message content');
const types = this.getTypeMessage(msg);
const contactContent = types.contactMessage;
this.logger.verbose('contact message displayName: ' + contactContent);
return contactContent;
}
private getLocationMessageContent(msg: any) {
this.logger.verbose('get location message content');
const types = this.getTypeMessage(msg);
const locationContent = types.locationMessage;
this.logger.verbose('location message degreesLatitude: ' + locationContent);
return locationContent;
}
private getViewOnceMessageV2Content(msg: any) {
this.logger.verbose('get viewOnceMessageV2 content');
const types = this.getTypeMessage(msg);
const viewOnceContent = types.viewOnceMessageV2;
this.logger.verbose('viewOnceMessageV2 URL: ' + viewOnceContent);
return viewOnceContent;
}
private getListResponseMessageContent(msg: any) {
this.logger.verbose('get listResponseMessage content');
const types = this.getTypeMessage(msg);
const listResponseContent = types.listResponseMessage || types.responseRowId;
this.logger.verbose('listResponseMessage selectedRowId: ' + listResponseContent);
return listResponseContent;
}
public async createNewSession(instance: InstanceDto, data: any) {
if (data.remoteJid === 'status@broadcast') return;
const id = Math.floor(Math.random() * 10000000000).toString();
@ -565,6 +668,7 @@ export class TypebotService {
const delay_message = findTypebot.delay_message;
const unknown_message = findTypebot.unknown_message;
const listening_from_me = findTypebot.listening_from_me;
const messageType = this.getTypeMessage(msg.message).messageType;
const session = sessions.find((session) => session.remoteJid === remoteJid);
@ -687,6 +791,9 @@ export class TypebotService {
sessions: sessions,
remoteJid: remoteJid,
pushName: msg.pushName,
prefilledVariables: {
messageType: messageType,
},
});
await this.sendWAMessage(instance, remoteJid, data.messages, data.input, data.clientSideActions);

View File

@ -183,14 +183,28 @@ export class BusinessStartupService extends WAStartupService {
const message = received.messages[0];
let content: any = message.type + 'Message';
content = { [content]: message[message.type] };
message.context ? (content.extendedTextMessage = { contextInfo: { stanzaId: message.context.id } }) : content;
message.context ? (content = { ...content, contextInfo: { stanzaId: message.context.id } }) : content;
return content;
}
private messageInteractiveJson(received: any) {
const message = received.messages[0];
const content: any = { conversation: message.interactive[message.interactive.type].title };
message.context ? (content.extendedTextMessage = { contextInfo: { stanzaId: message.context.id } }) : content;
let content: any = { conversation: message.interactive[message.interactive.type].title };
message.context ? (content = { ...content, contextInfo: { stanzaId: message.context.id } }) : content;
return content;
}
private messageReactionJson(received: any) {
const message = received.messages[0];
let content: any = {
reactionMessage: {
key: {
id: message.reaction.message_id,
},
text: message.reaction.emoji,
},
};
message.context ? (content = { ...content, contextInfo: { stanzaId: message.context.id } }) : content;
return content;
}
@ -198,18 +212,20 @@ export class BusinessStartupService extends WAStartupService {
let content: any;
const message = received.messages[0];
if (message.from === received.metadata.phone_number_id) {
content = { extendedTextMessage: { text: message.text.body } };
message.context ? (content.extendedTextMessage.contextInfo = { stanzaId: message.context.id }) : content;
content = {
extendedTextMessage: { text: message.text.body },
};
message.context ? (content = { ...content, contextInfo: { stanzaId: message.context.id } }) : content;
} else {
content = { conversation: message.text.body };
message.context ? (content.extendedTextMessage = { contextInfo: { stanzaId: message.context.id } }) : content;
message.context ? (content = { ...content, contextInfo: { stanzaId: message.context.id } }) : content;
}
return content;
}
private messageContactsJson(received: any) {
const message = received.messages[0];
const content: any = {};
let content: any = {};
const vcard = (contact: any) => {
this.logger.verbose('Creating vcard');
@ -264,7 +280,7 @@ export class BusinessStartupService extends WAStartupService {
}),
};
}
message.context ? (content.extendedTextMessage = { contextInfo: { stanzaId: message.context.id } }) : content;
message.context ? (content = { ...content, contextInfo: { stanzaId: message.context.id } }) : content;
return content;
}
@ -287,8 +303,11 @@ export class BusinessStartupService extends WAStartupService {
case 'document':
messageType = 'documentMessage';
break;
case 'template':
messageType = 'conversation';
break;
default:
messageType = 'imageMessage';
messageType = 'conversation';
break;
}
@ -339,6 +358,18 @@ export class BusinessStartupService extends WAStartupService {
owner: this.instance.name,
// source: getDevice(received.key.id),
};
} else if (received?.messages[0].reaction) {
messageRaw = {
key,
pushName,
message: {
...this.messageReactionJson(received),
},
messageType: 'reactionMessage',
messageTimestamp: received.messages[0].timestamp as number,
owner: this.instance.name,
// source: getDevice(received.key.id),
};
} else if (received?.messages[0].contacts) {
messageRaw = {
key,
@ -374,6 +405,7 @@ export class BusinessStartupService extends WAStartupService {
this.logger.log(messageRaw);
this.logger.verbose('Sending data to webhook in event MESSAGES_UPSERT');
this.sendDataWebhook(Events.MESSAGES_UPSERT, messageRaw);
if (this.localChatwoot.enabled) {
@ -540,30 +572,68 @@ export class BusinessStartupService extends WAStartupService {
}
}
private convertMessageToRaw(message: any) {
private convertMessageToRaw(message: any, content: any) {
let convertMessage: any;
if (message?.conversation) {
return message;
if (content?.context?.message_id) {
convertMessage = {
...message,
contextInfo: { stanzaId: content.context.message_id },
};
return convertMessage;
}
convertMessage = message;
return convertMessage;
}
if (message?.mediaType === 'image') {
if (content?.context?.message_id) {
convertMessage = {
imageMessage: message,
contextInfo: { stanzaId: content.context.message_id },
};
return convertMessage;
}
return {
imageMessage: message,
};
}
if (message?.mediaType === 'video') {
if (content?.context?.message_id) {
convertMessage = {
videoMessage: message,
contextInfo: { stanzaId: content.context.message_id },
};
return convertMessage;
}
return {
videoMessage: message,
};
}
if (message?.mediaType === 'audio') {
if (content?.context?.message_id) {
convertMessage = {
audioMessage: message,
contextInfo: { stanzaId: content.context.message_id },
};
return convertMessage;
}
return {
audioMessage: message,
};
}
if (message?.mediaType === 'document') {
if (content?.context?.message_id) {
convertMessage = {
documentMessage: message,
contextInfo: { stanzaId: content.context.message_id },
};
return convertMessage;
}
return {
documentMessage: message,
};
@ -610,7 +680,6 @@ export class BusinessStartupService extends WAStartupService {
message_id: message['reactionMessage']['key']['id'],
emoji: message['reactionMessage']['text'],
},
context: { message_id: quoted.id },
};
quoted ? (content.context = { message_id: quoted.id }) : content;
return await this.post(content, 'messages');
@ -670,6 +739,7 @@ export class BusinessStartupService extends WAStartupService {
[message['mediaType']]: {
[message['type']]: message['id'],
preview_url: linkPreview,
caption: message['caption'],
},
};
quoted ? (content.context = { message_id: quoted.id }) : content;
@ -771,10 +841,17 @@ export class BusinessStartupService extends WAStartupService {
}
})();
if (messageSent?.error?.message) {
this.logger.error(messageSent.error.message);
throw messageSent.error.message.toString();
}
console.log(content);
const messageRaw: MessageRaw = {
key: { fromMe: true, id: messageSent?.messages[0]?.id, remoteJid: this.createJid(number) },
//pushName: messageSent.pushName,
message: this.convertMessageToRaw(message),
message: this.convertMessageToRaw(message, content),
messageType: this.renderMessageType(content.type),
messageTimestamp: (messageSent?.messages[0]?.timestamp as number) || Math.round(new Date().getTime() / 1000),
owner: this.instance.name,
@ -1154,6 +1231,10 @@ export class BusinessStartupService extends WAStartupService {
}
}
public async deleteMessage() {
throw new BadRequestException('Method not available on WhatsApp Business API');
}
// methods not available on WhatsApp Business API
public async mediaSticker() {
throw new BadRequestException('Method not available on WhatsApp Business API');
@ -1176,9 +1257,6 @@ export class BusinessStartupService extends WAStartupService {
public async archiveChat() {
throw new BadRequestException('Method not available on WhatsApp Business API');
}
public async deleteMessage() {
throw new BadRequestException('Method not available on WhatsApp Business API');
}
public async fetchProfile() {
throw new BadRequestException('Method not available on WhatsApp Business API');
}