Skip to content

Commit aef3495

Browse files
committed
Merge branch 'develop' of github.com:EvolutionAPI/evolution-api into develop
2 parents da341a9 + f0a0cb7 commit aef3495

File tree

10 files changed

+175
-41
lines changed

10 files changed

+175
-41
lines changed

src/utils/translations/en.json

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,24 @@
22
"qrgeneratedsuccesfully": "QRCode successfully generated!",
33
"scanqr": "Scan this QR code within the next 40 seconds.",
44
"qrlimitreached": "QRCode generation limit reached, to generate a new QRCode, send the 'init' message again.",
5-
"numbernotinwhatsapp": "The message was not sent as the contact is not a valid Whatsapp number."
5+
"numbernotinwhatsapp": "The message was not sent as the contact is not a valid Whatsapp number.",
6+
"cw.inbox.connected": "🚀 Connection successfully established!",
7+
"cw.inbox.disconnect": "🚨 Disconnecting WhatsApp from inbox *{{inboxName}}*.",
8+
"cw.inbox.alreadyConnected": "🚨 {{inboxName}} instance is connected.",
9+
"cw.inbox.clearCache": "✅ {{inboxName}} instance cache cleared.",
10+
"cw.inbox.notFound": "⚠️ {{inboxName}} instance not found.",
11+
"cw.inbox.status": "⚠️ {{inboxName}} instance status: *{{state}}*.",
12+
"cw.import.startImport": "💬 Starting to import messages. Please wait...",
13+
"cw.import.importingMessages": "💬 Importing messages. More one moment...",
14+
"cw.import.messagesImported": "💬 {{totalMessagesImported}} messages imported. Refresh page to see the new messages.",
15+
"cw.import.messagesException": "💬 Something went wrong in importing messages.",
16+
"cw.locationMessage.location": "Location",
17+
"cw.locationMessage.latitude": "Latitude",
18+
"cw.locationMessage.longitude": "Longitude",
19+
"cw.locationMessage.locationName": "Name",
20+
"cw.locationMessage.locationAddress": "Address",
21+
"cw.locationMessage.locationUrl": "URL",
22+
"cw.contactMessage.contact": "Contact",
23+
"cw.contactMessage.name": "Name",
24+
"cw.contactMessage.number": "Number"
625
}

src/utils/translations/pt-BR.json

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,25 @@
11
{
22
"qrgeneratedsuccesfully": "QRCode gerado com sucesso!",
3-
"scanqr": "Escanei o QRCode com o Whatsapp nos próximos 40 segundos.",
3+
"scanqr": "Escaneie o QRCode com o WhatsApp nos próximos 40 segundos.",
44
"qrlimitreached": "Limite de geração de QRCode atingido! Para gerar um novo QRCode, envie o texto 'init' nesta conversa.",
5-
"numbernotinwhatsapp": "A mensagem não foi enviada, pois o contato não é um número válido do Whatsapp."
5+
"numbernotinwhatsapp": "A mensagem não foi enviada, pois o contato não é um número válido do WhatsApp.",
6+
"cw.inbox.connected": "🚀 Conectado com sucesso!",
7+
"cw.inbox.disconnect": "🚨 Instância *{{inboxName}}* desconectada do WhatsApp.",
8+
"cw.inbox.alreadyConnected": "🚨 Instância *{{inboxName}}* já está conectada.",
9+
"cw.inbox.clearCache": "✅ Instância *{{inboxName}}* cache removido.",
10+
"cw.inbox.notFound": "⚠️ Instância *{{inboxName}}* não encontrada.",
11+
"cw.inbox.status": "⚠️ Status da instância {{inboxName}}: *{{state}}*.",
12+
"cw.import.startImport": "💬 Iniciando importação de mensagens. Por favor, aguarde...",
13+
"cw.import.importingMessages": "💬 Importando mensagens. Mais um momento...",
14+
"cw.import.messagesImported": "💬 {{totalMessagesImported}} mensagens importadas. Atualize a página para ver as novas mensagens.",
15+
"cw.import.messagesException": "💬 Não foi possível importar as mensagens.",
16+
"cw.locationMessage.location": "Localização",
17+
"cw.locationMessage.latitude": "Latitude",
18+
"cw.locationMessage.longitude": "Longitude",
19+
"cw.locationMessage.locationName": "Nome",
20+
"cw.locationMessage.locationAddress": "Endereço",
21+
"cw.locationMessage.locationUrl": "URL",
22+
"cw.contactMessage.contact": "Contato",
23+
"cw.contactMessage.name": "Nome",
24+
"cw.contactMessage.number": "Número"
625
}

src/validate/validate.schema.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -539,6 +539,17 @@ export const privacySettingsSchema: JSONSchema7 = {
539539
required: ['privacySettings'],
540540
};
541541

542+
export const blockUserSchema: JSONSchema7 = {
543+
$id: v4(),
544+
type: 'object',
545+
properties: {
546+
number: { type: 'string' },
547+
status: { type: 'string', enum: ['block', 'unblock'] },
548+
},
549+
required: ['number', 'status'],
550+
...isNotEmpty('number', 'status'),
551+
};
552+
542553
export const archiveChatSchema: JSONSchema7 = {
543554
$id: v4(),
544555
type: 'object',

src/whatsapp/controllers/chat.controller.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { Logger } from '../../config/logger.config';
22
import {
33
ArchiveChatDto,
4+
BlockUserDto,
45
DeleteMessage,
56
getBase64FromMediaMessageDto,
67
NumberDto,
@@ -123,4 +124,9 @@ export class ChatController {
123124
logger.verbose('requested updateMessage from ' + instanceName + ' instance');
124125
return await this.waMonitor.waInstances[instanceName].updateMessage(data);
125126
}
127+
128+
public async blockUser({ instanceName }: InstanceDto, data: BlockUserDto) {
129+
logger.verbose('requested blockUser from ' + instanceName + ' instance');
130+
return await this.waMonitor.waInstances[instanceName].blockUser(data);
131+
}
126132
}

src/whatsapp/dto/chat.dto.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,3 +115,8 @@ export class UpdateMessageDto extends Metadata {
115115
key: proto.IMessageKey;
116116
text: string;
117117
}
118+
119+
export class BlockUserDto {
120+
number: string;
121+
status: 'block' | 'unblock';
122+
}

src/whatsapp/routers/chat.router.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { RequestHandler, Router } from 'express';
33
import { Logger } from '../../config/logger.config';
44
import {
55
archiveChatSchema,
6+
blockUserSchema,
67
contactValidateSchema,
78
deleteMessageSchema,
89
messageUpSchema,
@@ -20,6 +21,7 @@ import {
2021
import { RouterBroker } from '../abstract/abstract.router';
2122
import {
2223
ArchiveChatDto,
24+
BlockUserDto,
2325
DeleteMessage,
2426
getBase64FromMediaMessageDto,
2527
NumberDto,
@@ -384,6 +386,23 @@ export class ChatRouter extends RouterBroker {
384386
});
385387

386388
return res.status(HttpStatus.OK).json(response);
389+
})
390+
.put(this.routerPath('updateBlockStatus'), ...guards, async (req, res) => {
391+
logger.verbose('request received in updateBlockStatus');
392+
logger.verbose('request body: ');
393+
logger.verbose(req.body);
394+
395+
logger.verbose('request query: ');
396+
logger.verbose(req.query);
397+
398+
const response = await this.dataValidate<BlockUserDto>({
399+
request: req,
400+
schema: blockUserSchema,
401+
ClassRef: BlockUserDto,
402+
execute: (instance, data) => chatController.blockUser(instance, data),
403+
});
404+
405+
return res.status(HttpStatus.CREATED).json(response);
387406
});
388407
}
389408

src/whatsapp/services/chatwoot.service.ts

Lines changed: 61 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1191,14 +1191,26 @@ export class ChatwootService {
11911191
await waInstance.connectToWhatsapp(number);
11921192
} else {
11931193
this.logger.verbose('whatsapp already connected');
1194-
await this.createBotMessage(instance, `🚨 ${body.inbox.name} instance is connected.`, 'incoming');
1194+
await this.createBotMessage(
1195+
instance,
1196+
i18next.t('cw.inbox.alreadyConnected', {
1197+
inboxName: body.inbox.name,
1198+
}),
1199+
'incoming',
1200+
);
11951201
}
11961202
}
11971203

11981204
if (command === 'clearcache') {
11991205
this.logger.verbose('command clearcache found');
12001206
waInstance.clearCacheChatwoot();
1201-
await this.createBotMessage(instance, `✅ ${body.inbox.name} instance cache cleared.`, 'incoming');
1207+
await this.createBotMessage(
1208+
instance,
1209+
i18next.t('cw.inbox.clearCache', {
1210+
inboxName: body.inbox.name,
1211+
}),
1212+
'incoming',
1213+
);
12021214
}
12031215

12041216
if (command === 'status') {
@@ -1208,19 +1220,34 @@ export class ChatwootService {
12081220

12091221
if (!state) {
12101222
this.logger.verbose('state not found');
1211-
await this.createBotMessage(instance, `⚠️ ${body.inbox.name} instance not found.`, 'incoming');
1223+
await this.createBotMessage(
1224+
instance,
1225+
i18next.t('cw.inbox.notFound', {
1226+
inboxName: body.inbox.name,
1227+
}),
1228+
'incoming',
1229+
);
12121230
}
12131231

12141232
if (state) {
12151233
this.logger.verbose('state: ' + state + ' found');
1216-
await this.createBotMessage(instance, `⚠️ ${body.inbox.name} instance status: *${state}*`, 'incoming');
1234+
await this.createBotMessage(
1235+
instance,
1236+
i18next.t('cw.inbox.status', {
1237+
inboxName: body.inbox.name,
1238+
state: state,
1239+
}),
1240+
'incoming',
1241+
);
12171242
}
12181243
}
12191244

12201245
if (command === 'disconnect' || command === 'desconectar') {
12211246
this.logger.verbose('command disconnect found');
12221247

1223-
const msgLogout = `🚨 Disconnecting Whatsapp from inbox *${body.inbox.name}*: `;
1248+
const msgLogout = i18next.t('cw.inbox.disconnect', {
1249+
inboxName: body.inbox.name,
1250+
});
12241251

12251252
this.logger.verbose('send message to chatwoot');
12261253
await this.createBotMessage(instance, msgLogout, 'incoming');
@@ -1509,27 +1536,17 @@ export class ChatwootService {
15091536
const latitude = result.degreesLatitude;
15101537
const longitude = result.degreesLongitude;
15111538

1512-
const locationName = result?.name || 'Unknown';
1513-
const locationAddress = result?.address || 'Unknown';
1539+
const locationName = result?.name;
1540+
const locationAddress = result?.address;
15141541

15151542
const formattedLocation =
1516-
'*Localização:*\n\n' +
1517-
'_Latitude:_ ' +
1518-
latitude +
1519-
'\n' +
1520-
'_Longitude:_ ' +
1521-
longitude +
1522-
'\n' +
1523-
'_Nome:_ ' +
1524-
locationName +
1525-
'\n' +
1526-
'_Endereço:_ ' +
1527-
locationAddress +
1528-
'\n' +
1529-
'_Url:_ https://www.google.com/maps/search/?api=1&query=' +
1530-
latitude +
1531-
',' +
1532-
longitude;
1543+
`*${i18next.t('cw.locationMessage.location')}:*\n\n` +
1544+
`_${i18next.t('cw.locationMessage.latitude')}:_ ${latitude} \n` +
1545+
`_${i18next.t('cw.locationMessage.longitude')}:_ ${longitude} \n` +
1546+
(locationName ? `_${i18next.t('cw.locationMessage.locationName')}:_ ${locationName}\n` : '') +
1547+
(locationAddress ? `_${i18next.t('cw.locationMessage.locationAddress')}:_ ${locationAddress} \n` : '') +
1548+
`_${i18next.t('cw.locationMessage.locationUrl')}:_ ` +
1549+
`https://www.google.com/maps/search/?api=1&query=${latitude},${longitude}`;
15331550

15341551
this.logger.verbose('message content: ' + formattedLocation);
15351552

@@ -1547,17 +1564,19 @@ export class ChatwootService {
15471564
}
15481565
});
15491566

1550-
let formattedContact = '*Contact:*\n\n' + '_Name:_ ' + contactInfo['FN'];
1567+
let formattedContact =
1568+
`*${i18next.t('cw.contactMessage.contact')}:*\n\n` +
1569+
`_${i18next.t('cw.contactMessage.name')}:_ ${contactInfo['FN']}`;
15511570

15521571
let numberCount = 1;
15531572
Object.keys(contactInfo).forEach((key) => {
15541573
if (key.startsWith('item') && key.includes('TEL')) {
15551574
const phoneNumber = contactInfo[key];
1556-
formattedContact += '\n_Number (' + numberCount + '):_ ' + phoneNumber;
1575+
formattedContact += `\n_${i18next.t('cw.contactMessage.number')} (${numberCount}):_ ${phoneNumber}`;
15571576
numberCount++;
15581577
} else if (key.includes('TEL')) {
15591578
const phoneNumber = contactInfo[key];
1560-
formattedContact += '\n_Number (' + numberCount + '):_ ' + phoneNumber;
1579+
formattedContact += `\n_${i18next.t('cw.contactMessage.number')} (${numberCount}):_ ${phoneNumber}`;
15611580
numberCount++;
15621581
}
15631582
});
@@ -1578,17 +1597,19 @@ export class ChatwootService {
15781597
}
15791598
});
15801599

1581-
let formattedContact = '*Contact:*\n\n' + '_Name:_ ' + contact.displayName;
1600+
let formattedContact = `*${i18next.t('cw.contactMessage.contact')}:*\n\n_${i18next.t(
1601+
'cw.contactMessage.name',
1602+
)}:_ ${contact.displayName}`;
15821603

15831604
let numberCount = 1;
15841605
Object.keys(contactInfo).forEach((key) => {
15851606
if (key.startsWith('item') && key.includes('TEL')) {
15861607
const phoneNumber = contactInfo[key];
1587-
formattedContact += '\n_Number (' + numberCount + '):_ ' + phoneNumber;
1608+
formattedContact += `\n_${i18next.t('cw.contactMessage.number')} (${numberCount}):_ ${phoneNumber}`;
15881609
numberCount++;
15891610
} else if (key.includes('TEL')) {
15901611
const phoneNumber = contactInfo[key];
1591-
formattedContact += '\n_Number (' + numberCount + '):_ ' + phoneNumber;
1612+
formattedContact += `\n_${i18next.t('cw.contactMessage.number')} (${numberCount}):_ ${phoneNumber}`;
15921613
numberCount++;
15931614
}
15941615
});
@@ -2074,7 +2095,10 @@ export class ChatwootService {
20742095
return;
20752096
}
20762097

2077-
const msgStatus = `⚡️ Instance status ${inbox.name}: ${data.status}`;
2098+
const msgStatus = i18next.t('cw.inbox.status', {
2099+
inboxName: inbox.name,
2100+
state: data.status,
2101+
});
20782102

20792103
this.logger.verbose('send message to chatwoot');
20802104
await this.createBotMessage(instance, msgStatus, 'incoming');
@@ -2086,7 +2110,7 @@ export class ChatwootService {
20862110
if (body.status === 'open') {
20872111
// if we have qrcode count then we understand that a new connection was established
20882112
if (this.waMonitor.waInstances[instance.instanceName].qrCode.count > 0) {
2089-
const msgConnection = `🚀 Connection successfully established!`;
2113+
const msgConnection = i18next.t('cw.inbox.connected');
20902114
this.logger.verbose('send message to chatwoot');
20912115
await this.createBotMessage(instance, msgConnection, 'incoming');
20922116
this.waMonitor.waInstances[instance.instanceName].qrCode.count = 0;
@@ -2147,7 +2171,7 @@ export class ChatwootService {
21472171
return;
21482172
}
21492173

2150-
this.createBotMessage(instance, `💬 Starting to import messages. Please wait...`, 'incoming');
2174+
this.createBotMessage(instance, i18next.t('cw.import.startImport'), 'incoming');
21512175
}
21522176

21532177
public isImportHistoryAvailable() {
@@ -2180,7 +2204,7 @@ export class ChatwootService {
21802204
return;
21812205
}
21822206

2183-
this.createBotMessage(instance, '💬 Importing messages. More one moment...', 'incoming');
2207+
this.createBotMessage(instance, i18next.t('cw.import.importingMessages'), 'incoming');
21842208

21852209
const totalMessagesImported = await chatwootImport.importHistoryMessages(
21862210
instance,
@@ -2191,10 +2215,10 @@ export class ChatwootService {
21912215
this.updateContactAvatarInRecentConversations(instance);
21922216

21932217
const msg = Number.isInteger(totalMessagesImported)
2194-
? `${totalMessagesImported} messages imported. Refresh page to see the new messages`
2195-
: `Something went wrong in importing messages`;
2218+
? i18next.t('cw.import.messagesImported', { totalMessagesImported })
2219+
: i18next.t('cw.import.messagesException');
21962220

2197-
this.createBotMessage(instance, `💬 ${msg}`, 'incoming');
2221+
this.createBotMessage(instance, msg, 'incoming');
21982222

21992223
return totalMessagesImported;
22002224
}

src/whatsapp/services/whatsapp.baileys.service.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ import { useMultiFileAuthStateDb } from '../../utils/use-multi-file-auth-state-d
6464
import { useMultiFileAuthStateRedisDb } from '../../utils/use-multi-file-auth-state-redis-db';
6565
import {
6666
ArchiveChatDto,
67+
BlockUserDto,
6768
DeleteMessage,
6869
getBase64FromMediaMessageDto,
6970
LastMessage,
@@ -2817,6 +2818,29 @@ export class BaileysStartupService extends WAStartupService {
28172818
}
28182819
}
28192820

2821+
public async blockUser(data: BlockUserDto) {
2822+
this.logger.verbose('Blocking user: ' + data.number);
2823+
try {
2824+
const { number } = data;
2825+
2826+
this.logger.verbose(`Check if number "${number}" is WhatsApp`);
2827+
const isWA = (await this.whatsappNumber({ numbers: [number] }))?.shift();
2828+
2829+
this.logger.verbose(`Exists: "${isWA.exists}" | jid: ${isWA.jid}`);
2830+
if (!isWA.exists && !isJidGroup(isWA.jid) && !isWA.jid.includes('@broadcast')) {
2831+
throw new BadRequestException(isWA);
2832+
}
2833+
2834+
const sender = isWA.jid;
2835+
2836+
await this.client.updateBlockStatus(sender, data.status);
2837+
2838+
return { block: 'success' };
2839+
} catch (error) {
2840+
throw new InternalServerErrorException('Error blocking user', error.toString());
2841+
}
2842+
}
2843+
28202844
public async updateMessage(data: UpdateMessageDto) {
28212845
try {
28222846
const jid = this.createJid(data.number);

src/whatsapp/services/whatsapp.business.service.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1159,6 +1159,9 @@ export class BusinessStartupService extends WAStartupService {
11591159
public async removeProfilePicture() {
11601160
throw new BadRequestException('Method not available on WhatsApp Business API');
11611161
}
1162+
public async blockUser() {
1163+
throw new BadRequestException('Method not available on WhatsApp Business API');
1164+
}
11621165
public async updateMessage() {
11631166
throw new BadRequestException('Method not available on WhatsApp Business API');
11641167
}

0 commit comments

Comments
 (0)