Skip to content

Commit 3b440e5

Browse files
committed
Merge branch 'develop' of https://github.com/neocol83/evolution-api into develop
2 parents 7f6553e + 0239638 commit 3b440e5

36 files changed

Lines changed: 4059 additions & 9015 deletions

.env.example

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ SERVER_PORT=8080
33
# Server URL - Set your application url
44
SERVER_URL=http://localhost:8080
55

6+
SSL_CONF_PRIVKEY=/path/to/cert.key
7+
SSL_CONF_FULLCHAIN=/path/to/cert.crt
8+
69
SENTRY_DSN=
710

811
# Cors - * for all or set separate by commas - ex.: 'yourdomain1.com, yourdomain2.com'
@@ -176,6 +179,15 @@ WEBHOOK_EVENTS_TYPEBOT_CHANGE_STATUS=false
176179
WEBHOOK_EVENTS_ERRORS=false
177180
WEBHOOK_EVENTS_ERRORS_WEBHOOK=
178181

182+
WEBHOOK_REQUEST_TIMEOUT_MS=60000
183+
WEBHOOK_RETRY_MAX_ATTEMPTS=10
184+
WEBHOOK_RETRY_INITIAL_DELAY_SECONDS=5
185+
WEBHOOK_RETRY_USE_EXPONENTIAL_BACKOFF=true
186+
WEBHOOK_RETRY_MAX_DELAY_SECONDS=300
187+
WEBHOOK_RETRY_JITTER_FACTOR=0.2
188+
# Comma separated list of HTTP status codes that should not trigger retries
189+
WEBHOOK_RETRY_NON_RETRYABLE_STATUS_CODES=400,401,403,404,422
190+
179191
# Name that will be displayed on smartphone connection
180192
CONFIG_SESSION_PHONE_CLIENT=Evolution API
181193
# Browser Name = Chrome | Firefox | Edge | Opera | Safari
@@ -275,4 +287,4 @@ LANGUAGE=en
275287
# PROXY_PORT=80
276288
# PROXY_PROTOCOL=http
277289
# PROXY_USERNAME=
278-
# PROXY_PASSWORD=
290+
# PROXY_PASSWORD=

src/api/integrations/channel/evolution/evolution.channel.service.ts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -165,11 +165,7 @@ export class EvolutionStartupService extends ChannelStartupService {
165165
openAiDefaultSettings.speechToText &&
166166
received?.message?.audioMessage
167167
) {
168-
messageRaw.message.speechToText = await this.openaiService.speechToText(
169-
openAiDefaultSettings.OpenaiCreds,
170-
received,
171-
this.client.updateMediaMessage,
172-
);
168+
messageRaw.message.speechToText = await this.openaiService.speechToText(received);
173169
}
174170
}
175171

src/api/integrations/channel/meta/whatsapp.business.service.ts

Lines changed: 76 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -192,38 +192,63 @@ export class BusinessStartupService extends ChannelStartupService {
192192
}
193193

194194
private messageTextJson(received: any) {
195-
// Verificar que received y received.messages existen
196-
if (!received || !received.messages || received.messages.length === 0) {
197-
this.logger.error('Error: received object or messages array is undefined or empty');
198-
return null;
199-
}
195+
// Verificar que received y received.messages existen
196+
if (!received || !received.messages || received.messages.length === 0) {
197+
this.logger.error('Error: received object or messages array is undefined or empty');
198+
return null;
199+
}
200200

201-
const message = received.messages[0];
202-
let content: any;
203-
204-
// Verificar si es un mensaje de tipo sticker, location u otro tipo que no tiene text
205-
if (!message.text) {
206-
// Si no hay texto, manejamos diferente según el tipo de mensaje
207-
if (message.type === 'sticker') {
208-
content = { stickerMessage: {} };
209-
} else if (message.type === 'location') {
210-
content = { locationMessage: {
211-
degreesLatitude: message.location?.latitude,
212-
degreesLongitude: message.location?.longitude,
213-
name: message.location?.name,
214-
address: message.location?.address,
215-
}};
216-
} else {
217-
// Para otros tipos de mensajes sin texto, creamos un contenido genérico
218-
this.logger.log(`Mensaje de tipo ${message.type} sin campo text`);
219-
content = { [message.type + 'Message']: message[message.type] || {} };
201+
const message = received.messages[0];
202+
let content: any;
203+
204+
// Verificar si es un mensaje de tipo sticker, location u otro tipo que no tiene text
205+
if (!message.text) {
206+
// Si no hay texto, manejamos diferente según el tipo de mensaje
207+
if (message.type === 'sticker') {
208+
content = { stickerMessage: {} };
209+
} else if (message.type === 'location') {
210+
content = {
211+
locationMessage: {
212+
degreesLatitude: message.location?.latitude,
213+
degreesLongitude: message.location?.longitude,
214+
name: message.location?.name,
215+
address: message.location?.address,
216+
},
217+
};
218+
} else {
219+
// Para otros tipos de mensajes sin texto, creamos un contenido genérico
220+
this.logger.log(`Mensaje de tipo ${message.type} sin campo text`);
221+
content = { [message.type + 'Message']: message[message.type] || {} };
222+
}
223+
224+
// Añadir contexto si existe
225+
if (message.context) {
226+
content = { ...content, contextInfo: { stanzaId: message.context.id } };
227+
}
228+
229+
return content;
220230
}
221-
222-
// Añadir contexto si existe
223-
if (message.context) {
224-
content = { ...content, contextInfo: { stanzaId: message.context.id } };
231+
232+
// Si el mensaje tiene texto, procesamos normalmente
233+
if (!received.metadata || !received.metadata.phone_number_id) {
234+
this.logger.error('Error: metadata or phone_number_id is undefined');
235+
return null;
236+
}
237+
238+
if (message.from === received.metadata.phone_number_id) {
239+
content = {
240+
extendedTextMessage: { text: message.text.body },
241+
};
242+
if (message.context) {
243+
content = { ...content, contextInfo: { stanzaId: message.context.id } };
244+
}
245+
} else {
246+
content = { conversation: message.text.body };
247+
if (message.context) {
248+
content = { ...content, contextInfo: { stanzaId: message.context.id } };
249+
}
225250
}
226-
251+
227252
return content;
228253
}
229254

@@ -350,13 +375,11 @@ export class BusinessStartupService extends ChannelStartupService {
350375

351376
if (received.messages) {
352377
const message = received.messages[0]; // Añadir esta línea para definir message
353-
354378
const key = {
355379
id: message.id,
356380
remoteJid: this.phoneNumber,
357381
fromMe: message.from === received.metadata.phone_number_id,
358382
};
359-
360383
if (message.type === 'sticker') {
361384
this.logger.log('Procesando mensaje de tipo sticker');
362385
messageRaw = {
@@ -371,7 +394,6 @@ export class BusinessStartupService extends ChannelStartupService {
371394
instanceId: this.instanceId,
372395
};
373396
} else if (this.isMediaMessage(message)) {
374-
375397
messageRaw = {
376398
key,
377399
pushName,
@@ -540,16 +562,12 @@ export class BusinessStartupService extends ChannelStartupService {
540562
openAiDefaultSettings.speechToText &&
541563
audioMessage
542564
) {
543-
messageRaw.message.speechToText = await this.openaiService.speechToText(
544-
openAiDefaultSettings.OpenaiCreds,
545-
{
546-
message: {
547-
mediaUrl: messageRaw.message.mediaUrl,
548-
...messageRaw,
549-
},
565+
messageRaw.message.speechToText = await this.openaiService.speechToText(openAiDefaultSettings.OpenaiCreds, {
566+
message: {
567+
mediaUrl: messageRaw.message.mediaUrl,
568+
...messageRaw,
550569
},
551-
() => {},
552-
);
570+
});
553571
}
554572
}
555573

@@ -785,28 +803,29 @@ export class BusinessStartupService extends ChannelStartupService {
785803
// Registro para depuración
786804
this.logger.log('Contenido recibido en eventHandler:');
787805
this.logger.log(JSON.stringify(content, null, 2));
788-
806+
789807
const database = this.configService.get<Database>('DATABASE');
790808
const settings = await this.findSettings();
791-
809+
792810
// Si hay mensajes, verificar primero el tipo
793811
if (content.messages && content.messages.length > 0) {
794812
const message = content.messages[0];
795813
this.logger.log(`Tipo de mensaje recibido: ${message.type}`);
796-
814+
797815
// Verificamos el tipo de mensaje antes de procesarlo
798-
if (message.type === 'text' ||
799-
message.type === 'image' ||
800-
message.type === 'video' ||
801-
message.type === 'audio' ||
802-
message.type === 'document' ||
803-
message.type === 'sticker' ||
804-
message.type === 'location' ||
805-
message.type === 'contacts' ||
806-
message.type === 'interactive' ||
807-
message.type === 'button' ||
808-
message.type === 'reaction') {
809-
816+
if (
817+
message.type === 'text' ||
818+
message.type === 'image' ||
819+
message.type === 'video' ||
820+
message.type === 'audio' ||
821+
message.type === 'document' ||
822+
message.type === 'sticker' ||
823+
message.type === 'location' ||
824+
message.type === 'contacts' ||
825+
message.type === 'interactive' ||
826+
message.type === 'button' ||
827+
message.type === 'reaction'
828+
) {
810829
// Procesar el mensaje normalmente
811830
this.messageHandle(content, database, settings);
812831
} else {
@@ -912,7 +931,7 @@ export class BusinessStartupService extends ChannelStartupService {
912931
to: number.replace(/\D/g, ''),
913932
[message['mediaType']]: {
914933
[message['type']]: message['id'],
915-
preview_url: linkPreview,
934+
preview_url: Boolean(options?.linkPreview),
916935
...(message['fileName'] && !isImage && { filename: message['fileName'] }),
917936
caption: message['caption'],
918937
},
@@ -1081,7 +1100,6 @@ export class BusinessStartupService extends ChannelStartupService {
10811100

10821101
private async getIdMedia(mediaMessage: any) {
10831102
const formData = new FormData();
1084-
10851103
const fileStream = createReadStream(mediaMessage.media);
10861104

10871105
formData.append('file', fileStream, { filename: 'media', contentType: mediaMessage.mimetype });

0 commit comments

Comments
 (0)