mirror of
https://github.com/EvolutionAPI/evolution-api.git
synced 2025-12-18 19:32:21 -06:00
Merge branch 'fix-typebot-error-handle' of https://github.com/gabrielpastori1/ticketme-evolution-api into fix-typebot-error-handle
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -41,6 +41,7 @@ export class InstanceController {
|
||||
instanceName,
|
||||
webhook,
|
||||
webhook_by_events,
|
||||
webhook_base64,
|
||||
events,
|
||||
qrcode,
|
||||
number,
|
||||
@@ -139,6 +140,7 @@ export class InstanceController {
|
||||
url: webhook,
|
||||
events: newEvents,
|
||||
webhook_by_events,
|
||||
webhook_base64,
|
||||
});
|
||||
|
||||
webhookEvents = (await this.webhookService.find(instance)).events;
|
||||
@@ -297,6 +299,7 @@ export class InstanceController {
|
||||
webhook: {
|
||||
webhook,
|
||||
webhook_by_events,
|
||||
webhook_base64,
|
||||
events: webhookEvents,
|
||||
},
|
||||
websocket: {
|
||||
@@ -390,6 +393,7 @@ export class InstanceController {
|
||||
webhook: {
|
||||
webhook,
|
||||
webhook_by_events,
|
||||
webhook_base64,
|
||||
events: webhookEvents,
|
||||
},
|
||||
websocket: {
|
||||
|
||||
@@ -1,15 +1,21 @@
|
||||
import { Request, Response } from 'express';
|
||||
|
||||
import { ConfigService } from '../../config/env.config';
|
||||
import { Auth, ConfigService, HttpServer } from '../../config/env.config';
|
||||
import { HttpStatus } from '../routers/index.router';
|
||||
import { WAMonitoringService } from '../services/monitor.service';
|
||||
|
||||
export class ViewsController {
|
||||
constructor(private readonly waMonit: WAMonitoringService, private readonly configService: ConfigService) {}
|
||||
constructor(private readonly waMonitor: WAMonitoringService, private readonly configService: ConfigService) {}
|
||||
|
||||
public async manager(request: Request, response: Response) {
|
||||
try {
|
||||
return response.status(HttpStatus.OK).render('manager');
|
||||
const token = this.configService.get<Auth>('AUTHENTICATION').API_KEY.KEY;
|
||||
const port = this.configService.get<HttpServer>('SERVER').PORT;
|
||||
|
||||
const instances = await this.waMonitor.instanceInfo();
|
||||
|
||||
console.log('INSTANCES: ', instances);
|
||||
return response.status(HttpStatus.OK).render('manager', { token, port, instances });
|
||||
} catch (error) {
|
||||
console.log('ERROR: ', error);
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ export class InstanceDto {
|
||||
token?: string;
|
||||
webhook?: string;
|
||||
webhook_by_events?: boolean;
|
||||
webhook_base64?: boolean;
|
||||
events?: string[];
|
||||
reject_call?: boolean;
|
||||
msg_call?: string;
|
||||
|
||||
@@ -61,6 +61,7 @@ export class SendPollDto extends Metadata {
|
||||
export type MediaType = 'image' | 'document' | 'video' | 'audio';
|
||||
export class MediaMessage {
|
||||
mediatype: MediaType;
|
||||
mimetype?: string;
|
||||
caption?: string;
|
||||
// for document
|
||||
fileName?: string;
|
||||
|
||||
@@ -3,4 +3,5 @@ export class WebhookDto {
|
||||
url?: string;
|
||||
events?: string[];
|
||||
webhook_by_events?: boolean;
|
||||
webhook_base64?: boolean;
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ const typebotSchema = new Schema<TypebotRaw>({
|
||||
prefilledVariables: {
|
||||
remoteJid: { type: String, required: false },
|
||||
pushName: { type: String, required: false },
|
||||
additionalData: { type: Schema.Types.Mixed, required: false }
|
||||
additionalData: { type: Schema.Types.Mixed, required: false },
|
||||
},
|
||||
},
|
||||
],
|
||||
|
||||
@@ -8,6 +8,7 @@ export class WebhookRaw {
|
||||
enabled?: boolean;
|
||||
events?: string[];
|
||||
webhook_by_events?: boolean;
|
||||
webhook_base64?: boolean;
|
||||
}
|
||||
|
||||
const webhookSchema = new Schema<WebhookRaw>({
|
||||
@@ -16,6 +17,7 @@ const webhookSchema = new Schema<WebhookRaw>({
|
||||
enabled: { type: Boolean, required: true },
|
||||
events: { type: [String], required: true },
|
||||
webhook_by_events: { type: Boolean, required: true },
|
||||
webhook_base64: { type: Boolean, required: true },
|
||||
});
|
||||
|
||||
export const WebhookModel = dbserver?.model(WebhookRaw.name, webhookSchema, 'webhook');
|
||||
|
||||
@@ -914,7 +914,7 @@ export class ChatwootService {
|
||||
},
|
||||
};
|
||||
|
||||
await waInstance?.audioWhatsapp(data);
|
||||
await waInstance?.audioWhatsapp(data, true);
|
||||
|
||||
this.logger.verbose('audio sent');
|
||||
return;
|
||||
@@ -939,7 +939,7 @@ export class ChatwootService {
|
||||
data.mediaMessage.caption = caption;
|
||||
}
|
||||
|
||||
await waInstance?.mediaMessage(data);
|
||||
await waInstance?.mediaMessage(data, true);
|
||||
|
||||
this.logger.verbose('media sent');
|
||||
return;
|
||||
@@ -1074,7 +1074,7 @@ export class ChatwootService {
|
||||
},
|
||||
};
|
||||
|
||||
await waInstance?.textMessage(data);
|
||||
await waInstance?.textMessage(data, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,7 +117,7 @@ export class WAMonitoringService {
|
||||
if (this.configService.get<Auth>('AUTHENTICATION').EXPOSE_IN_FETCH_INSTANCES) {
|
||||
instanceData.instance['serverUrl'] = this.configService.get<HttpServer>('SERVER').URL;
|
||||
|
||||
instanceData.instance['apikey'] = (await this.repository.auth.find(key)).apikey;
|
||||
instanceData.instance['apikey'] = (await this.repository.auth.find(key))?.apikey;
|
||||
|
||||
instanceData.instance['chatwoot'] = chatwoot;
|
||||
}
|
||||
@@ -136,7 +136,7 @@ export class WAMonitoringService {
|
||||
if (this.configService.get<Auth>('AUTHENTICATION').EXPOSE_IN_FETCH_INSTANCES) {
|
||||
instanceData.instance['serverUrl'] = this.configService.get<HttpServer>('SERVER').URL;
|
||||
|
||||
instanceData.instance['apikey'] = (await this.repository.auth.find(key)).apikey;
|
||||
instanceData.instance['apikey'] = (await this.repository.auth.find(key))?.apikey;
|
||||
|
||||
instanceData.instance['chatwoot'] = chatwoot;
|
||||
}
|
||||
|
||||
@@ -320,6 +320,37 @@ export class TypebotService {
|
||||
return sessions;
|
||||
}
|
||||
|
||||
public async clearSessions(instance: InstanceDto, remoteJid: string) {
|
||||
const findTypebot = await this.find(instance);
|
||||
const sessions = (findTypebot.sessions as Session[]) ?? [];
|
||||
|
||||
const sessionWithRemoteJid = sessions.filter((session) => session.remoteJid === remoteJid);
|
||||
|
||||
if (sessionWithRemoteJid.length > 0) {
|
||||
sessionWithRemoteJid.forEach((session) => {
|
||||
sessions.splice(sessions.indexOf(session), 1);
|
||||
});
|
||||
|
||||
const typebotData = {
|
||||
enabled: findTypebot.enabled,
|
||||
url: findTypebot.url,
|
||||
typebot: findTypebot.typebot,
|
||||
expire: findTypebot.expire,
|
||||
keyword_finish: findTypebot.keyword_finish,
|
||||
delay_message: findTypebot.delay_message,
|
||||
unknown_message: findTypebot.unknown_message,
|
||||
listening_from_me: findTypebot.listening_from_me,
|
||||
sessions,
|
||||
};
|
||||
|
||||
this.create(instance, typebotData);
|
||||
|
||||
return sessions;
|
||||
}
|
||||
|
||||
return sessions;
|
||||
}
|
||||
|
||||
public async sendWAMessage(
|
||||
instance: InstanceDto,
|
||||
remoteJid: string,
|
||||
|
||||
@@ -26,7 +26,7 @@ export class WebhookService {
|
||||
|
||||
return result;
|
||||
} catch (error) {
|
||||
return { enabled: false, url: '', events: [], webhook_by_events: false };
|
||||
return { enabled: false, url: '', events: [], webhook_by_events: false, webhook_base64: false };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,9 +128,7 @@ import { Events, MessageSubtype, TypeMediaMessage, wa } from '../types/wa.types'
|
||||
import { waMonitor } from '../whatsapp.module';
|
||||
import { ChamaaiService } from './chamaai.service';
|
||||
import { ChatwootService } from './chatwoot.service';
|
||||
//import { SocksProxyAgent } from './socks-proxy-agent';
|
||||
import { TypebotService } from './typebot.service';
|
||||
|
||||
export class WAStartupService {
|
||||
constructor(
|
||||
private readonly configService: ConfigService,
|
||||
@@ -276,6 +274,9 @@ export class WAStartupService {
|
||||
this.localWebhook.webhook_by_events = data?.webhook_by_events;
|
||||
this.logger.verbose(`Webhook by events: ${this.localWebhook.webhook_by_events}`);
|
||||
|
||||
this.localWebhook.webhook_base64 = data?.webhook_base64;
|
||||
this.logger.verbose(`Webhook by webhook_base64: ${this.localWebhook.webhook_base64}`);
|
||||
|
||||
this.logger.verbose('Webhook loaded');
|
||||
}
|
||||
|
||||
@@ -581,7 +582,7 @@ export class WAStartupService {
|
||||
Object.assign(this.localProxy, data);
|
||||
this.logger.verbose('Proxy set');
|
||||
|
||||
this.client?.ws?.close();
|
||||
this.reloadConnection();
|
||||
}
|
||||
|
||||
public async findProxy() {
|
||||
@@ -1180,17 +1181,28 @@ export class WAStartupService {
|
||||
|
||||
if (this.localProxy.enabled) {
|
||||
this.logger.verbose('Proxy enabled');
|
||||
options = {
|
||||
agent: new ProxyAgent(this.localProxy.proxy as any),
|
||||
fetchAgent: new ProxyAgent(this.localProxy.proxy as any),
|
||||
};
|
||||
|
||||
if (this.localProxy.proxy.includes('proxyscrape')) {
|
||||
const response = await axios.get(this.localProxy.proxy);
|
||||
const text = response.data;
|
||||
const proxyUrls = text.split('\r\n');
|
||||
const rand = Math.floor(Math.random() * Math.floor(proxyUrls.length));
|
||||
const proxyUrl = 'http://' + proxyUrls[rand];
|
||||
options = {
|
||||
agent: new ProxyAgent(proxyUrl as any),
|
||||
};
|
||||
} else {
|
||||
options = {
|
||||
agent: new ProxyAgent(this.localProxy.proxy as any),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
const socketConfig: UserFacingSocketConfig = {
|
||||
...options,
|
||||
auth: {
|
||||
creds: this.instance.authState.state.creds,
|
||||
keys: makeCacheableSignalKeyStore(this.instance.authState.state.keys, P({ level: 'error' })),
|
||||
keys: makeCacheableSignalKeyStore(this.instance.authState.state.keys, P({ level: 'error' }) as any),
|
||||
},
|
||||
logger: P({ level: this.logBaileys }),
|
||||
printQRInTerminal: false,
|
||||
@@ -1270,7 +1282,7 @@ export class WAStartupService {
|
||||
...options,
|
||||
auth: {
|
||||
creds: this.instance.authState.state.creds,
|
||||
keys: makeCacheableSignalKeyStore(this.instance.authState.state.keys, P({ level: 'error' })),
|
||||
keys: makeCacheableSignalKeyStore(this.instance.authState.state.keys, P({ level: 'error' }) as any),
|
||||
},
|
||||
logger: P({ level: this.logBaileys }),
|
||||
printQRInTerminal: false,
|
||||
@@ -1508,11 +1520,12 @@ export class WAStartupService {
|
||||
this.logger.verbose('Event received: messages.upsert');
|
||||
const received = messages[0];
|
||||
|
||||
console.log(received, type);
|
||||
if (
|
||||
type !== 'notify' ||
|
||||
!received?.message ||
|
||||
received.message?.protocolMessage ||
|
||||
received.message.senderKeyDistributionMessage ||
|
||||
// received.message.senderKeyDistributionMessage ||
|
||||
received.message?.pollUpdateMessage
|
||||
) {
|
||||
this.logger.verbose('message rejected');
|
||||
@@ -1528,15 +1541,44 @@ export class WAStartupService {
|
||||
return;
|
||||
}
|
||||
|
||||
const messageRaw: MessageRaw = {
|
||||
key: received.key,
|
||||
pushName: received.pushName,
|
||||
message: { ...received.message },
|
||||
messageType: getContentType(received.message),
|
||||
messageTimestamp: received.messageTimestamp as number,
|
||||
owner: this.instance.name,
|
||||
source: getDevice(received.key.id),
|
||||
};
|
||||
let messageRaw: MessageRaw;
|
||||
|
||||
if (
|
||||
(this.localWebhook.webhook_base64 === true && received?.message.documentMessage) ||
|
||||
received?.message.imageMessage
|
||||
) {
|
||||
const buffer = await downloadMediaMessage(
|
||||
{ key: received.key, message: received?.message },
|
||||
'buffer',
|
||||
{},
|
||||
{
|
||||
logger: P({ level: 'error' }) as any,
|
||||
reuploadRequest: this.client.updateMediaMessage,
|
||||
},
|
||||
);
|
||||
messageRaw = {
|
||||
key: received.key,
|
||||
pushName: received.pushName,
|
||||
message: {
|
||||
...received.message,
|
||||
base64: buffer ? buffer.toString('base64') : undefined,
|
||||
},
|
||||
messageType: getContentType(received.message),
|
||||
messageTimestamp: received.messageTimestamp as number,
|
||||
owner: this.instance.name,
|
||||
source: getDevice(received.key.id),
|
||||
};
|
||||
} else {
|
||||
messageRaw = {
|
||||
key: received.key,
|
||||
pushName: received.pushName,
|
||||
message: { ...received.message },
|
||||
messageType: getContentType(received.message),
|
||||
messageTimestamp: received.messageTimestamp as number,
|
||||
owner: this.instance.name,
|
||||
source: getDevice(received.key.id),
|
||||
};
|
||||
}
|
||||
|
||||
if (this.localSettings.read_messages && received.key.id !== 'status@broadcast') {
|
||||
await this.client.readMessages([received.key]);
|
||||
@@ -1559,7 +1601,11 @@ export class WAStartupService {
|
||||
);
|
||||
}
|
||||
|
||||
if (this.localTypebot.enabled) {
|
||||
const typebotSessionRemoteJid = this.localTypebot.sessions?.find(
|
||||
(session) => session.remoteJid === received.key.remoteJid,
|
||||
);
|
||||
|
||||
if (this.localTypebot.enabled || typebotSessionRemoteJid) {
|
||||
if (!(this.localTypebot.listening_from_me === false && messageRaw.key.fromMe === true)) {
|
||||
await this.typebotService.sendTypebot(
|
||||
{ instanceName: this.instance.name },
|
||||
@@ -1901,8 +1947,8 @@ export class WAStartupService {
|
||||
private createJid(number: string): string {
|
||||
this.logger.verbose('Creating jid with number: ' + number);
|
||||
|
||||
if (number.includes('@g.us') || number.includes('@s.whatsapp.net')) {
|
||||
this.logger.verbose('Number already contains @g.us or @s.whatsapp.net');
|
||||
if (number.includes('@g.us') || number.includes('@s.whatsapp.net') || number.includes('@lid')) {
|
||||
this.logger.verbose('Number already contains @g.us or @s.whatsapp.net or @lid');
|
||||
return number;
|
||||
}
|
||||
|
||||
@@ -2028,7 +2074,12 @@ export class WAStartupService {
|
||||
}
|
||||
}
|
||||
|
||||
private async sendMessageWithTyping<T = proto.IMessage>(number: string, message: T, options?: Options) {
|
||||
private async sendMessageWithTyping<T = proto.IMessage>(
|
||||
number: string,
|
||||
message: T,
|
||||
options?: Options,
|
||||
isChatwoot = false,
|
||||
) {
|
||||
this.logger.verbose('Sending message with typing');
|
||||
|
||||
this.logger.verbose(`Check if number "${number}" is WhatsApp`);
|
||||
@@ -2186,7 +2237,7 @@ export class WAStartupService {
|
||||
this.logger.verbose('Sending data to webhook in event SEND_MESSAGE');
|
||||
await this.sendDataWebhook(Events.SEND_MESSAGE, messageRaw);
|
||||
|
||||
if (this.localChatwoot.enabled) {
|
||||
if (this.localChatwoot.enabled && !isChatwoot) {
|
||||
this.chatwootService.eventWhatsapp(Events.SEND_MESSAGE, { instanceName: this.instance.name }, messageRaw);
|
||||
}
|
||||
|
||||
@@ -2211,7 +2262,7 @@ export class WAStartupService {
|
||||
}
|
||||
|
||||
// Send Message Controller
|
||||
public async textMessage(data: SendTextDto) {
|
||||
public async textMessage(data: SendTextDto, isChatwoot = false) {
|
||||
this.logger.verbose('Sending text message');
|
||||
return await this.sendMessageWithTyping(
|
||||
data.number,
|
||||
@@ -2219,6 +2270,7 @@ export class WAStartupService {
|
||||
conversation: data.textMessage.text,
|
||||
},
|
||||
data?.options,
|
||||
isChatwoot,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2384,7 +2436,6 @@ export class WAStartupService {
|
||||
mediaMessage.fileName = arrayMatch[1];
|
||||
this.logger.verbose('File name: ' + mediaMessage.fileName);
|
||||
}
|
||||
let mimetype: string;
|
||||
|
||||
if (mediaMessage.mediatype === 'image' && !mediaMessage.fileName) {
|
||||
mediaMessage.fileName = 'image.png';
|
||||
@@ -2394,10 +2445,16 @@ export class WAStartupService {
|
||||
mediaMessage.fileName = 'video.mp4';
|
||||
}
|
||||
|
||||
if (isURL(mediaMessage.media)) {
|
||||
mimetype = getMIMEType(mediaMessage.media);
|
||||
let mimetype: string;
|
||||
|
||||
if (mediaMessage.mimetype) {
|
||||
mimetype = mediaMessage.mimetype;
|
||||
} else {
|
||||
mimetype = getMIMEType(mediaMessage.fileName);
|
||||
if (isURL(mediaMessage.media)) {
|
||||
mimetype = getMIMEType(mediaMessage.media);
|
||||
} else {
|
||||
mimetype = getMIMEType(mediaMessage.fileName);
|
||||
}
|
||||
}
|
||||
|
||||
this.logger.verbose('Mimetype: ' + mimetype);
|
||||
@@ -2494,11 +2551,11 @@ export class WAStartupService {
|
||||
return result;
|
||||
}
|
||||
|
||||
public async mediaMessage(data: SendMediaDto) {
|
||||
public async mediaMessage(data: SendMediaDto, isChatwoot = false) {
|
||||
this.logger.verbose('Sending media message');
|
||||
const generate = await this.prepareMediaMessage(data.mediaMessage);
|
||||
|
||||
return await this.sendMessageWithTyping(data.number, { ...generate.message }, data?.options);
|
||||
return await this.sendMessageWithTyping(data.number, { ...generate.message }, data?.options, isChatwoot);
|
||||
}
|
||||
|
||||
public async processAudio(audio: string, number: string) {
|
||||
@@ -2555,7 +2612,7 @@ export class WAStartupService {
|
||||
});
|
||||
}
|
||||
|
||||
public async audioWhatsapp(data: SendAudioDto) {
|
||||
public async audioWhatsapp(data: SendAudioDto, isChatwoot = false) {
|
||||
this.logger.verbose('Sending audio whatsapp');
|
||||
|
||||
if (!data.options?.encoding && data.options?.encoding !== false) {
|
||||
@@ -2574,6 +2631,7 @@ export class WAStartupService {
|
||||
mimetype: 'audio/mp4',
|
||||
},
|
||||
{ presence: 'recording', delay: data?.options?.delay },
|
||||
isChatwoot,
|
||||
);
|
||||
|
||||
fs.unlinkSync(convert);
|
||||
@@ -2595,6 +2653,7 @@ export class WAStartupService {
|
||||
mimetype: 'audio/ogg; codecs=opus',
|
||||
},
|
||||
{ presence: 'recording', delay: data?.options?.delay },
|
||||
isChatwoot,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2905,7 +2964,7 @@ export class WAStartupService {
|
||||
'buffer',
|
||||
{},
|
||||
{
|
||||
logger: P({ level: 'error' }),
|
||||
logger: P({ level: 'error' }) as any,
|
||||
reuploadRequest: this.client.updateMediaMessage,
|
||||
},
|
||||
);
|
||||
@@ -3044,7 +3103,7 @@ export class WAStartupService {
|
||||
await this.client.updateGroupsAddPrivacy(settings.privacySettings.groupadd);
|
||||
this.logger.verbose('Groups add privacy updated');
|
||||
|
||||
this.client?.ws?.close();
|
||||
this.reloadConnection();
|
||||
|
||||
return {
|
||||
update: 'success',
|
||||
|
||||
@@ -50,6 +50,7 @@ export declare namespace wa {
|
||||
url?: string;
|
||||
events?: string[];
|
||||
webhook_by_events?: boolean;
|
||||
webhook_base64?: boolean;
|
||||
};
|
||||
|
||||
export type LocalChatwoot = {
|
||||
|
||||
Reference in New Issue
Block a user