mirror of
https://github.com/EvolutionAPI/evolution-api.git
synced 2025-07-18 13:06:32 -06:00
Merge branch 'develop' of github.com:EvolutionAPI/evolution-api into develop
This commit is contained in:
commit
af7a5d3248
13
CHANGELOG.md
13
CHANGELOG.md
@ -3,6 +3,10 @@
|
|||||||
### Features
|
### Features
|
||||||
|
|
||||||
* Added messages.delete event
|
* Added messages.delete event
|
||||||
|
* Added restart instance endpoint
|
||||||
|
* Created automation for creating instances in the chatwoot bot with the command '#inbox_whatsapp:<INSTANCE_NAME>'
|
||||||
|
* Change Baileys version to: 6.4.0
|
||||||
|
* Send contact in chatwoot
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
@ -12,7 +16,14 @@
|
|||||||
* Added validations in create instance
|
* Added validations in create instance
|
||||||
* Removed link preview endpoint, now it's done automatically from sending conventional text
|
* Removed link preview endpoint, now it's done automatically from sending conventional text
|
||||||
* Added group membership validation before sending message to groups
|
* Added group membership validation before sending message to groups
|
||||||
* Adjusts in Dockerfile
|
* Adjusts in docker files
|
||||||
|
* Adjusts in returns in endpoints chatwoot and webhook
|
||||||
|
* Fixed ghost mentions in send text message
|
||||||
|
* Fixed bug that saved contacts from groups came without number in chatwoot
|
||||||
|
* Fixed problem to receive csat in chatwoot
|
||||||
|
* Fixed require fileName for document only in base64 for send media message
|
||||||
|
* Bug fix when sending mobile message change contact name to number in chatwoot
|
||||||
|
* Bug fix when connecting whatsapp does not send confirmation message
|
||||||
|
|
||||||
# 1.2.2 (2023-07-15 09:36)
|
# 1.2.2 (2023-07-15 09:36)
|
||||||
|
|
||||||
|
@ -37,6 +37,5 @@ volumes:
|
|||||||
|
|
||||||
networks:
|
networks:
|
||||||
evolution-net:
|
evolution-net:
|
||||||
name: evolution-net
|
|
||||||
external: true
|
external: true
|
||||||
|
|
@ -25,5 +25,4 @@ volumes:
|
|||||||
|
|
||||||
networks:
|
networks:
|
||||||
evolution-net:
|
evolution-net:
|
||||||
name: evolution-net
|
|
||||||
external: true
|
external: true
|
||||||
|
@ -1,73 +0,0 @@
|
|||||||
version: '3.3'
|
|
||||||
|
|
||||||
services:
|
|
||||||
redis:
|
|
||||||
image: redis:latest
|
|
||||||
container_name: redis
|
|
||||||
ports:
|
|
||||||
- 6379:6379
|
|
||||||
|
|
||||||
rebrow:
|
|
||||||
image: marian/rebrow
|
|
||||||
ports:
|
|
||||||
- 5001:5001
|
|
||||||
links:
|
|
||||||
- redis
|
|
||||||
|
|
||||||
mongodb:
|
|
||||||
container_name: mongodb
|
|
||||||
image: mongo
|
|
||||||
restart: always
|
|
||||||
volumes:
|
|
||||||
- evolution_mongodb_data:/data/db
|
|
||||||
- evolution_mongodb_configdb:/data/configdb
|
|
||||||
ports:
|
|
||||||
- 27017:27017
|
|
||||||
environment:
|
|
||||||
MONGO_INITDB_ROOT_USERNAME: root
|
|
||||||
MONGO_INITDB_ROOT_PASSWORD: root
|
|
||||||
expose:
|
|
||||||
- 27017
|
|
||||||
|
|
||||||
mongo-express:
|
|
||||||
image: mongo-express
|
|
||||||
environment:
|
|
||||||
ME_CONFIG_BASICAUTH_USERNAME: root
|
|
||||||
ME_CONFIG_BASICAUTH_PASSWORD: root
|
|
||||||
ME_CONFIG_MONGODB_SERVER: mongodb
|
|
||||||
ME_CONFIG_MONGODB_ADMINUSERNAME: root
|
|
||||||
ME_CONFIG_MONGODB_ADMINPASSWORD: root
|
|
||||||
ports:
|
|
||||||
- 8081:8081
|
|
||||||
links:
|
|
||||||
- mongodb
|
|
||||||
api:
|
|
||||||
container_name: evolution_api
|
|
||||||
image: evolution/api:local
|
|
||||||
restart: always
|
|
||||||
ports:
|
|
||||||
- 8080:8080
|
|
||||||
volumes:
|
|
||||||
- evolution_instances:/evolution/instances
|
|
||||||
- evolution_store:/evolution/store
|
|
||||||
env_file:
|
|
||||||
- ./Docker/.env
|
|
||||||
command: ['node', './dist/src/main.js']
|
|
||||||
expose:
|
|
||||||
- 8080
|
|
||||||
links:
|
|
||||||
- mongodb
|
|
||||||
- redis
|
|
||||||
|
|
||||||
volumes:
|
|
||||||
evolution_instances:
|
|
||||||
evolution_store:
|
|
||||||
evolution_mongodb_data:
|
|
||||||
evolution_mongodb_configdb:
|
|
||||||
evolution_redis:
|
|
||||||
|
|
||||||
networks:
|
|
||||||
default:
|
|
||||||
external:
|
|
||||||
name: evolution-net
|
|
||||||
|
|
@ -22,6 +22,5 @@ volumes:
|
|||||||
|
|
||||||
networks:
|
networks:
|
||||||
evolution-net:
|
evolution-net:
|
||||||
name: evolution-net
|
|
||||||
external: true
|
external: true
|
||||||
|
|
@ -44,7 +44,8 @@
|
|||||||
"@ffmpeg-installer/ffmpeg": "^1.1.0",
|
"@ffmpeg-installer/ffmpeg": "^1.1.0",
|
||||||
"@figuro/chatwoot-sdk": "^1.1.14",
|
"@figuro/chatwoot-sdk": "^1.1.14",
|
||||||
"@hapi/boom": "^10.0.1",
|
"@hapi/boom": "^10.0.1",
|
||||||
"@whiskeysockets/baileys": "github:DavidsonGomes/Baileys",
|
"@sentry/node": "^7.59.2",
|
||||||
|
"@whiskeysockets/baileys": "^6.4.0",
|
||||||
"axios": "^1.3.5",
|
"axios": "^1.3.5",
|
||||||
"class-validator": "^0.13.2",
|
"class-validator": "^0.13.2",
|
||||||
"compression": "^1.7.4",
|
"compression": "^1.7.4",
|
||||||
|
29
src/main.ts
29
src/main.ts
@ -10,6 +10,7 @@ import { waMonitor } from './whatsapp/whatsapp.module';
|
|||||||
import { HttpStatus, router } from './whatsapp/routers/index.router';
|
import { HttpStatus, router } from './whatsapp/routers/index.router';
|
||||||
import 'express-async-errors';
|
import 'express-async-errors';
|
||||||
import { ServerUP } from './utils/server-up';
|
import { ServerUP } from './utils/server-up';
|
||||||
|
import * as Sentry from '@sentry/node';
|
||||||
|
|
||||||
function initWA() {
|
function initWA() {
|
||||||
waMonitor.loadInstance();
|
waMonitor.loadInstance();
|
||||||
@ -19,6 +20,27 @@ function bootstrap() {
|
|||||||
const logger = new Logger('SERVER');
|
const logger = new Logger('SERVER');
|
||||||
const app = express();
|
const app = express();
|
||||||
|
|
||||||
|
// Sentry.init({
|
||||||
|
// dsn: '',
|
||||||
|
// integrations: [
|
||||||
|
// // enable HTTP calls tracing
|
||||||
|
// new Sentry.Integrations.Http({ tracing: true }),
|
||||||
|
// // enable Express.js middleware tracing
|
||||||
|
// new Sentry.Integrations.Express({ app }),
|
||||||
|
// // Automatically instrument Node.js libraries and frameworks
|
||||||
|
// ...Sentry.autoDiscoverNodePerformanceMonitoringIntegrations(),
|
||||||
|
// ],
|
||||||
|
|
||||||
|
// // Set tracesSampleRate to 1.0 to capture 100%
|
||||||
|
// // of transactions for performance monitoring.
|
||||||
|
// // We recommend adjusting this value in production
|
||||||
|
// tracesSampleRate: 1.0,
|
||||||
|
// });
|
||||||
|
|
||||||
|
// app.use(Sentry.Handlers.requestHandler());
|
||||||
|
|
||||||
|
// app.use(Sentry.Handlers.tracingHandler());
|
||||||
|
|
||||||
app.use(
|
app.use(
|
||||||
cors({
|
cors({
|
||||||
origin(requestOrigin, callback) {
|
origin(requestOrigin, callback) {
|
||||||
@ -43,6 +65,13 @@ function bootstrap() {
|
|||||||
|
|
||||||
app.use('/', router);
|
app.use('/', router);
|
||||||
|
|
||||||
|
// app.use(Sentry.Handlers.errorHandler());
|
||||||
|
|
||||||
|
// app.use(function onError(err, req, res, next) {
|
||||||
|
// res.statusCode = 500;
|
||||||
|
// res.end(res.sentry + '\n');
|
||||||
|
// });
|
||||||
|
|
||||||
app.use(
|
app.use(
|
||||||
(err: Error, req: Request, res: Response, next: NextFunction) => {
|
(err: Error, req: Request, res: Response, next: NextFunction) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
|
@ -66,6 +66,18 @@ export class ChatwootController {
|
|||||||
|
|
||||||
const urlServer = this.configService.get<HttpServer>('SERVER').URL;
|
const urlServer = this.configService.get<HttpServer>('SERVER').URL;
|
||||||
|
|
||||||
|
if (Object.keys(result).length === 0) {
|
||||||
|
return {
|
||||||
|
enabled: false,
|
||||||
|
url: '',
|
||||||
|
account_id: '',
|
||||||
|
token: '',
|
||||||
|
sign_msg: false,
|
||||||
|
name_inbox: '',
|
||||||
|
webhook_url: '',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
const response = {
|
const response = {
|
||||||
...result,
|
...result,
|
||||||
webhook_url: `${urlServer}/chatwoot/webhook/${instance.instanceName}`,
|
webhook_url: `${urlServer}/chatwoot/webhook/${instance.instanceName}`,
|
||||||
@ -78,7 +90,7 @@ export class ChatwootController {
|
|||||||
logger.verbose(
|
logger.verbose(
|
||||||
'requested receiveWebhook from ' + instance.instanceName + ' instance',
|
'requested receiveWebhook from ' + instance.instanceName + ' instance',
|
||||||
);
|
);
|
||||||
const chatwootService = new ChatwootService(waMonitor);
|
const chatwootService = new ChatwootService(waMonitor, this.configService);
|
||||||
|
|
||||||
return chatwootService.receiveWebhook(instance, data);
|
return chatwootService.receiveWebhook(instance, data);
|
||||||
}
|
}
|
||||||
|
@ -64,7 +64,10 @@ export class InstanceController {
|
|||||||
this.repository,
|
this.repository,
|
||||||
this.cache,
|
this.cache,
|
||||||
);
|
);
|
||||||
instance.instanceName = instanceName;
|
instance.instanceName = instanceName
|
||||||
|
.toLowerCase()
|
||||||
|
.replace(/[^a-z0-9]/g, '')
|
||||||
|
.replace(' ', '');
|
||||||
this.logger.verbose('instance: ' + instance.instanceName + ' created');
|
this.logger.verbose('instance: ' + instance.instanceName + ' created');
|
||||||
|
|
||||||
this.waMonitor.waInstances[instance.instanceName] = instance;
|
this.waMonitor.waInstances[instance.instanceName] = instance;
|
||||||
@ -191,7 +194,10 @@ export class InstanceController {
|
|||||||
this.repository,
|
this.repository,
|
||||||
this.cache,
|
this.cache,
|
||||||
);
|
);
|
||||||
instance.instanceName = instanceName;
|
instance.instanceName = instanceName
|
||||||
|
.toLowerCase()
|
||||||
|
.replace(/[^a-z0-9]/g, '')
|
||||||
|
.replace(' ', '');
|
||||||
|
|
||||||
this.logger.verbose('instance: ' + instance.instanceName + ' created');
|
this.logger.verbose('instance: ' + instance.instanceName + ' created');
|
||||||
|
|
||||||
@ -357,24 +363,8 @@ export class InstanceController {
|
|||||||
try {
|
try {
|
||||||
this.logger.verbose('requested restartInstance from ' + instanceName + ' instance');
|
this.logger.verbose('requested restartInstance from ' + instanceName + ' instance');
|
||||||
|
|
||||||
this.logger.verbose('deleting instance: ' + instanceName);
|
this.logger.verbose('logging out instance: ' + instanceName);
|
||||||
delete this.waMonitor.waInstances[instanceName];
|
this.waMonitor.waInstances[instanceName]?.client?.ws?.close();
|
||||||
|
|
||||||
this.logger.verbose('creating instance: ' + instanceName);
|
|
||||||
const instance = new WAStartupService(
|
|
||||||
this.configService,
|
|
||||||
this.eventEmitter,
|
|
||||||
this.repository,
|
|
||||||
this.cache,
|
|
||||||
);
|
|
||||||
|
|
||||||
instance.instanceName = instanceName;
|
|
||||||
|
|
||||||
this.logger.verbose('instance: ' + instance.instanceName + ' created');
|
|
||||||
|
|
||||||
this.logger.verbose('connecting instance: ' + instanceName);
|
|
||||||
await instance.connectToWhatsapp();
|
|
||||||
this.waMonitor.waInstances[instance.instanceName] = instance;
|
|
||||||
|
|
||||||
return { error: false, message: 'Instance restarted' };
|
return { error: false, message: 'Instance restarted' };
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
@ -30,9 +30,15 @@ export class SendMessageController {
|
|||||||
|
|
||||||
public async sendMedia({ instanceName }: InstanceDto, data: SendMediaDto) {
|
public async sendMedia({ instanceName }: InstanceDto, data: SendMediaDto) {
|
||||||
logger.verbose('requested sendMedia from ' + instanceName + ' instance');
|
logger.verbose('requested sendMedia from ' + instanceName + ' instance');
|
||||||
if (isBase64(data?.mediaMessage?.media) && !data?.mediaMessage?.fileName) {
|
|
||||||
throw new BadRequestException('For bse64 the file name must be informed.');
|
if (
|
||||||
|
isBase64(data?.mediaMessage?.media) &&
|
||||||
|
!data?.mediaMessage?.fileName &&
|
||||||
|
data?.mediaMessage?.mediatype === 'document'
|
||||||
|
) {
|
||||||
|
throw new BadRequestException('For base64 the file name must be informed.');
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.verbose(
|
logger.verbose(
|
||||||
'isURL: ' +
|
'isURL: ' +
|
||||||
isURL(data?.mediaMessage?.media) +
|
isURL(data?.mediaMessage?.media) +
|
||||||
|
@ -12,6 +12,7 @@ import mimeTypes from 'mime-types';
|
|||||||
import { SendAudioDto } from '../dto/sendMessage.dto';
|
import { SendAudioDto } from '../dto/sendMessage.dto';
|
||||||
import { SendMediaDto } from '../dto/sendMessage.dto';
|
import { SendMediaDto } from '../dto/sendMessage.dto';
|
||||||
import { ROOT_DIR } from '../../config/path.config';
|
import { ROOT_DIR } from '../../config/path.config';
|
||||||
|
import { ConfigService, HttpServer } from '../../config/env.config';
|
||||||
|
|
||||||
export class ChatwootService {
|
export class ChatwootService {
|
||||||
private messageCacheFile: string;
|
private messageCacheFile: string;
|
||||||
@ -21,7 +22,10 @@ export class ChatwootService {
|
|||||||
|
|
||||||
private provider: any;
|
private provider: any;
|
||||||
|
|
||||||
constructor(private readonly waMonitor: WAMonitoringService) {
|
constructor(
|
||||||
|
private readonly waMonitor: WAMonitoringService,
|
||||||
|
private readonly configService: ConfigService,
|
||||||
|
) {
|
||||||
this.messageCache = new Set();
|
this.messageCache = new Set();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -433,7 +437,7 @@ export class ChatwootService {
|
|||||||
instance,
|
instance,
|
||||||
body.key.participant.split('@')[0],
|
body.key.participant.split('@')[0],
|
||||||
filterInbox.id,
|
filterInbox.id,
|
||||||
isGroup,
|
false,
|
||||||
body.pushName,
|
body.pushName,
|
||||||
picture_url.profilePictureUrl || null,
|
picture_url.profilePictureUrl || null,
|
||||||
);
|
);
|
||||||
@ -449,7 +453,9 @@ export class ChatwootService {
|
|||||||
const findContact = await this.findContact(instance, chatId);
|
const findContact = await this.findContact(instance, chatId);
|
||||||
|
|
||||||
let contact: any;
|
let contact: any;
|
||||||
|
if (body.key.fromMe) {
|
||||||
|
contact = findContact;
|
||||||
|
} else {
|
||||||
if (findContact) {
|
if (findContact) {
|
||||||
contact = await this.updateContact(instance, findContact.id, {
|
contact = await this.updateContact(instance, findContact.id, {
|
||||||
name: nameContact,
|
name: nameContact,
|
||||||
@ -465,13 +471,15 @@ export class ChatwootService {
|
|||||||
picture_url.profilePictureUrl || null,
|
picture_url.profilePictureUrl || null,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!contact) {
|
if (!contact) {
|
||||||
this.logger.warn('contact not found');
|
this.logger.warn('contact not found');
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const contactId = contact.payload.id || contact.payload.contact.id;
|
const contactId =
|
||||||
|
contact?.payload?.id || contact?.payload?.contact?.id || contact?.id;
|
||||||
|
|
||||||
if (!body.key.fromMe && contact.name === chatId && nameContact !== chatId) {
|
if (!body.key.fromMe && contact.name === chatId && nameContact !== chatId) {
|
||||||
this.logger.verbose('update contact name in chatwoot');
|
this.logger.verbose('update contact name in chatwoot');
|
||||||
@ -981,6 +989,33 @@ export class ChatwootService {
|
|||||||
await waInstance?.client?.logout('Log out instance: ' + instance.instanceName);
|
await waInstance?.client?.logout('Log out instance: ' + instance.instanceName);
|
||||||
await waInstance?.client?.ws?.close();
|
await waInstance?.client?.ws?.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (command.includes('#inbox_whatsapp')) {
|
||||||
|
const urlServer = this.configService.get<HttpServer>('SERVER').URL;
|
||||||
|
const apiKey = this.configService.get('AUTHENTICATION').API_KEY.KEY;
|
||||||
|
|
||||||
|
const data = {
|
||||||
|
instanceName: command.split(':')[1],
|
||||||
|
qrcode: true,
|
||||||
|
chatwoot_account_id: this.provider.account_id,
|
||||||
|
chatwoot_token: this.provider.token,
|
||||||
|
chatwoot_url: this.provider.url,
|
||||||
|
chatwoot_sign_msg: this.provider.sign_msg,
|
||||||
|
};
|
||||||
|
|
||||||
|
const config = {
|
||||||
|
method: 'post',
|
||||||
|
maxBodyLength: Infinity,
|
||||||
|
url: `${urlServer}/instance/create`,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
apikey: apiKey,
|
||||||
|
},
|
||||||
|
data: data,
|
||||||
|
};
|
||||||
|
|
||||||
|
await axios.request(config);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
@ -1059,7 +1094,11 @@ export class ChatwootService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (body.message_type === 'template' && body.content_type === 'input_csat') {
|
if (
|
||||||
|
body.message_type === 'template' &&
|
||||||
|
body.content_type === 'input_csat' &&
|
||||||
|
body.event === 'message_created'
|
||||||
|
) {
|
||||||
this.logger.verbose('check if is csat');
|
this.logger.verbose('check if is csat');
|
||||||
|
|
||||||
const data: SendTextDto = {
|
const data: SendTextDto = {
|
||||||
@ -1119,6 +1158,7 @@ export class ChatwootService {
|
|||||||
documentWithCaptionMessage:
|
documentWithCaptionMessage:
|
||||||
msg.documentWithCaptionMessage?.message?.documentMessage?.caption,
|
msg.documentWithCaptionMessage?.message?.documentMessage?.caption,
|
||||||
audioMessage: msg.audioMessage?.caption,
|
audioMessage: msg.audioMessage?.caption,
|
||||||
|
contactMessage: msg.contactMessage?.vcard,
|
||||||
};
|
};
|
||||||
|
|
||||||
this.logger.verbose('type message: ' + types);
|
this.logger.verbose('type message: ' + types);
|
||||||
@ -1132,6 +1172,25 @@ export class ChatwootService {
|
|||||||
|
|
||||||
const result = typeKey ? types[typeKey] : undefined;
|
const result = typeKey ? types[typeKey] : undefined;
|
||||||
|
|
||||||
|
if (typeKey === 'contactMessage') {
|
||||||
|
const vCardData = result.split('\n');
|
||||||
|
const contactInfo = {};
|
||||||
|
|
||||||
|
vCardData.forEach((line) => {
|
||||||
|
const [key, value] = line.split(':');
|
||||||
|
if (key && value) {
|
||||||
|
contactInfo[key] = value;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const formattedContact = `**Contact:**
|
||||||
|
**name:** ${contactInfo['FN']}
|
||||||
|
**number:** ${contactInfo['item1.TEL;waid=5511952801378']}`;
|
||||||
|
|
||||||
|
this.logger.verbose('message content: ' + formattedContact);
|
||||||
|
return formattedContact;
|
||||||
|
}
|
||||||
|
|
||||||
this.logger.verbose('message content: ' + result);
|
this.logger.verbose('message content: ' + result);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@ -1142,8 +1201,12 @@ export class ChatwootService {
|
|||||||
|
|
||||||
const types = this.getTypeMessage(msg);
|
const types = this.getTypeMessage(msg);
|
||||||
|
|
||||||
|
console.log('types', types);
|
||||||
|
|
||||||
const messageContent = this.getMessageContent(types);
|
const messageContent = this.getMessageContent(types);
|
||||||
|
|
||||||
|
console.log('messageContent', messageContent);
|
||||||
|
|
||||||
this.logger.verbose('conversation message: ' + messageContent);
|
this.logger.verbose('conversation message: ' + messageContent);
|
||||||
|
|
||||||
return messageContent;
|
return messageContent;
|
||||||
@ -1394,37 +1457,38 @@ export class ChatwootService {
|
|||||||
|
|
||||||
if (event === 'connection.update') {
|
if (event === 'connection.update') {
|
||||||
this.logger.verbose('event connection.update');
|
this.logger.verbose('event connection.update');
|
||||||
if (body.state === 'open') {
|
console.log('connection.update', body);
|
||||||
const msgConnection = `🚀 Conexão realizada com sucesso!`;
|
if (body.status === 'open') {
|
||||||
|
const msgConnection = `🚀 Conexão estabelecida com sucesso!`;
|
||||||
|
|
||||||
this.logger.verbose('send message to chatwoot');
|
this.logger.verbose('send message to chatwoot');
|
||||||
await this.createBotMessage(instance, msgConnection, 'incoming');
|
await this.createBotMessage(instance, msgConnection, 'incoming');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event === 'contacts.update') {
|
// if (event === 'contacts.update') {
|
||||||
this.logger.verbose('event contacts.update');
|
// this.logger.verbose('event contacts.update');
|
||||||
const data = body;
|
// const data = body;
|
||||||
|
|
||||||
if (data.length) {
|
// if (data.length) {
|
||||||
this.logger.verbose('contacts found');
|
// this.logger.verbose('contacts found');
|
||||||
for (const item of data) {
|
// for (const item of data) {
|
||||||
const number = item.id.split('@')[0];
|
// const number = item.id.split('@')[0];
|
||||||
const photo = item.profilePictureUrl || null;
|
// const photo = item.profilePictureUrl || null;
|
||||||
this.logger.verbose('find contact in chatwoot');
|
// this.logger.verbose('find contact in chatwoot');
|
||||||
const find = await this.findContact(instance, number);
|
// const find = await this.findContact(instance, number);
|
||||||
|
|
||||||
if (find) {
|
// if (find) {
|
||||||
this.logger.verbose('contact found');
|
// this.logger.verbose('contact found');
|
||||||
|
|
||||||
this.logger.verbose('update contact in chatwoot');
|
// this.logger.verbose('update contact in chatwoot');
|
||||||
await this.updateContact(instance, find.id, {
|
// await this.updateContact(instance, find.id, {
|
||||||
avatar_url: photo,
|
// avatar_url: photo,
|
||||||
});
|
// });
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
if (event === 'qrcode.updated') {
|
if (event === 'qrcode.updated') {
|
||||||
this.logger.verbose('event qrcode.updated');
|
this.logger.verbose('event qrcode.updated');
|
||||||
|
@ -18,9 +18,17 @@ export class WebhookService {
|
|||||||
public async find(instance: InstanceDto): Promise<WebhookDto> {
|
public async find(instance: InstanceDto): Promise<WebhookDto> {
|
||||||
try {
|
try {
|
||||||
this.logger.verbose('find webhook: ' + instance.instanceName);
|
this.logger.verbose('find webhook: ' + instance.instanceName);
|
||||||
return await this.waMonitor.waInstances[instance.instanceName].findWebhook();
|
const result = await this.waMonitor.waInstances[
|
||||||
|
instance.instanceName
|
||||||
|
].findWebhook();
|
||||||
|
|
||||||
|
if (Object.keys(result).length === 0) {
|
||||||
|
throw new Error('Webhook not found');
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return { enabled: null, url: '' };
|
return { enabled: false, url: '', events: [], webhook_by_events: false };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -149,7 +149,7 @@ export class WAStartupService {
|
|||||||
private endSession = false;
|
private endSession = false;
|
||||||
private logBaileys = this.configService.get<Log>('LOG').BAILEYS;
|
private logBaileys = this.configService.get<Log>('LOG').BAILEYS;
|
||||||
|
|
||||||
private chatwootService = new ChatwootService(waMonitor);
|
private chatwootService = new ChatwootService(waMonitor, this.configService);
|
||||||
|
|
||||||
public set instanceName(name: string) {
|
public set instanceName(name: string) {
|
||||||
this.logger.verbose(`Initializing instance '${name}'`);
|
this.logger.verbose(`Initializing instance '${name}'`);
|
||||||
@ -343,6 +343,7 @@ export class WAStartupService {
|
|||||||
public async sendDataWebhook<T = any>(event: Events, data: T, local = true) {
|
public async sendDataWebhook<T = any>(event: Events, data: T, local = true) {
|
||||||
const webhookGlobal = this.configService.get<Webhook>('WEBHOOK');
|
const webhookGlobal = this.configService.get<Webhook>('WEBHOOK');
|
||||||
const webhookLocal = this.localWebhook.events;
|
const webhookLocal = this.localWebhook.events;
|
||||||
|
const serverUrl = this.configService.get<HttpServer>('SERVER').URL;
|
||||||
const we = event.replace(/[\.-]/gm, '_').toUpperCase();
|
const we = event.replace(/[\.-]/gm, '_').toUpperCase();
|
||||||
const transformedWe = we.replace(/_/gm, '-').toLowerCase();
|
const transformedWe = we.replace(/_/gm, '-').toLowerCase();
|
||||||
const instance = this.configService.get<Auth>('AUTHENTICATION').INSTANCE;
|
const instance = this.configService.get<Auth>('AUTHENTICATION').INSTANCE;
|
||||||
@ -366,6 +367,7 @@ export class WAStartupService {
|
|||||||
instance: this.instance.name,
|
instance: this.instance.name,
|
||||||
data,
|
data,
|
||||||
destination: this.localWebhook.url,
|
destination: this.localWebhook.url,
|
||||||
|
server_url: serverUrl,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -377,6 +379,7 @@ export class WAStartupService {
|
|||||||
instance: this.instance.name,
|
instance: this.instance.name,
|
||||||
data,
|
data,
|
||||||
destination: this.localWebhook.url,
|
destination: this.localWebhook.url,
|
||||||
|
server_url: serverUrl,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -390,6 +393,7 @@ export class WAStartupService {
|
|||||||
stack: error?.stack,
|
stack: error?.stack,
|
||||||
name: error?.name,
|
name: error?.name,
|
||||||
url: baseURL,
|
url: baseURL,
|
||||||
|
server_url: serverUrl,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -424,6 +428,7 @@ export class WAStartupService {
|
|||||||
instance: this.instance.name,
|
instance: this.instance.name,
|
||||||
data,
|
data,
|
||||||
destination: localUrl,
|
destination: localUrl,
|
||||||
|
server_url: serverUrl,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -435,6 +440,7 @@ export class WAStartupService {
|
|||||||
instance: this.instance.name,
|
instance: this.instance.name,
|
||||||
data,
|
data,
|
||||||
destination: localUrl,
|
destination: localUrl,
|
||||||
|
server_url: serverUrl,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -448,6 +454,7 @@ export class WAStartupService {
|
|||||||
stack: error?.stack,
|
stack: error?.stack,
|
||||||
name: error?.name,
|
name: error?.name,
|
||||||
url: globalURL,
|
url: globalURL,
|
||||||
|
server_url: serverUrl,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -617,6 +624,17 @@ export class WAStartupService {
|
|||||||
│ CONNECTED TO WHATSAPP │
|
│ CONNECTED TO WHATSAPP │
|
||||||
└──────────────────────────────┘`.replace(/^ +/gm, ' '),
|
└──────────────────────────────┘`.replace(/^ +/gm, ' '),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (this.localChatwoot.enabled) {
|
||||||
|
this.chatwootService.eventWhatsapp(
|
||||||
|
Events.CONNECTION_UPDATE,
|
||||||
|
{ instanceName: this.instance.name },
|
||||||
|
{
|
||||||
|
instance: this.instance.name,
|
||||||
|
status: 'open',
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1111,7 +1129,6 @@ export class WAStartupService {
|
|||||||
},
|
},
|
||||||
|
|
||||||
'messages.update': async (args: WAMessageUpdate[], database: Database) => {
|
'messages.update': async (args: WAMessageUpdate[], database: Database) => {
|
||||||
console.log(args);
|
|
||||||
this.logger.verbose('Event received: messages.update');
|
this.logger.verbose('Event received: messages.update');
|
||||||
const status: Record<number, wa.StatusMessage> = {
|
const status: Record<number, wa.StatusMessage> = {
|
||||||
0: 'ERROR',
|
0: 'ERROR',
|
||||||
@ -1299,6 +1316,7 @@ export class WAStartupService {
|
|||||||
const regexp = new RegExp(/^(\d{2})(\d{2})\d{1}(\d{8})$/);
|
const regexp = new RegExp(/^(\d{2})(\d{2})\d{1}(\d{8})$/);
|
||||||
if (regexp.test(jid)) {
|
if (regexp.test(jid)) {
|
||||||
const match = regexp.exec(jid);
|
const match = regexp.exec(jid);
|
||||||
|
|
||||||
if (match && (match[1] === '52' || match[1] === '54')) {
|
if (match && (match[1] === '52' || match[1] === '54')) {
|
||||||
const joker = Number.parseInt(match[3][0]);
|
const joker = Number.parseInt(match[3][0]);
|
||||||
const ddd = Number.parseInt(match[2]);
|
const ddd = Number.parseInt(match[2]);
|
||||||
@ -1335,30 +1353,27 @@ export class WAStartupService {
|
|||||||
private createJid(number: string): string {
|
private createJid(number: string): string {
|
||||||
this.logger.verbose('Creating jid with number: ' + number);
|
this.logger.verbose('Creating jid with number: ' + number);
|
||||||
|
|
||||||
const numberReplace = number.replace(/[^0-9]/g, '');
|
if (number.includes('@g.us') || number.includes('@s.whatsapp.net')) {
|
||||||
|
|
||||||
console.log('number', numberReplace);
|
|
||||||
if (numberReplace.includes('@g.us') || numberReplace.includes('@s.whatsapp.net')) {
|
|
||||||
this.logger.verbose('Number already contains @g.us or @s.whatsapp.net');
|
this.logger.verbose('Number already contains @g.us or @s.whatsapp.net');
|
||||||
return numberReplace;
|
return number;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (numberReplace.includes('@broadcast')) {
|
if (number.includes('@broadcast')) {
|
||||||
this.logger.verbose('Number already contains @broadcast');
|
this.logger.verbose('Number already contains @broadcast');
|
||||||
return numberReplace;
|
return number;
|
||||||
}
|
}
|
||||||
|
|
||||||
const formattedBRNumber = this.formatBRNumber(numberReplace);
|
const formattedBRNumber = this.formatBRNumber(number);
|
||||||
if (formattedBRNumber !== numberReplace) {
|
if (formattedBRNumber !== number) {
|
||||||
this.logger.verbose(
|
this.logger.verbose(
|
||||||
'Jid created is whatsapp in format BR: ' + `${formattedBRNumber}@s.whatsapp.net`,
|
'Jid created is whatsapp in format BR: ' + `${formattedBRNumber}@s.whatsapp.net`,
|
||||||
);
|
);
|
||||||
return `${formattedBRNumber}@s.whatsapp.net`;
|
return `${formattedBRNumber}@s.whatsapp.net`;
|
||||||
}
|
}
|
||||||
|
|
||||||
const formattedMXARNumber = this.formatMXOrARNumber(numberReplace);
|
const formattedMXARNumber = this.formatMXOrARNumber(number);
|
||||||
|
|
||||||
if (formattedMXARNumber !== numberReplace) {
|
if (formattedMXARNumber !== number) {
|
||||||
this.logger.verbose(
|
this.logger.verbose(
|
||||||
'Jid created is whatsapp in format MXAR: ' +
|
'Jid created is whatsapp in format MXAR: ' +
|
||||||
`${formattedMXARNumber}@s.whatsapp.net`,
|
`${formattedMXARNumber}@s.whatsapp.net`,
|
||||||
@ -1366,13 +1381,13 @@ export class WAStartupService {
|
|||||||
return `${formattedMXARNumber}@s.whatsapp.net`;
|
return `${formattedMXARNumber}@s.whatsapp.net`;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (numberReplace.includes('-')) {
|
if (number.includes('-')) {
|
||||||
this.logger.verbose('Jid created is group: ' + `${numberReplace}@g.us`);
|
this.logger.verbose('Jid created is group: ' + `${number}@g.us`);
|
||||||
return `${numberReplace}@g.us`;
|
return `${number}@g.us`;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.logger.verbose('Jid created is whatsapp: ' + `${numberReplace}@s.whatsapp.net`);
|
this.logger.verbose('Jid created is whatsapp: ' + `${number}@s.whatsapp.net`);
|
||||||
return `${numberReplace}@s.whatsapp.net`;
|
return `${number}@s.whatsapp.net`;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async profilePicture(number: string) {
|
public async profilePicture(number: string) {
|
||||||
@ -1488,7 +1503,7 @@ export class WAStartupService {
|
|||||||
!message['poll'] &&
|
!message['poll'] &&
|
||||||
!message['sticker'] &&
|
!message['sticker'] &&
|
||||||
!message['conversation'] &&
|
!message['conversation'] &&
|
||||||
!sender.includes('@broadcast')
|
sender !== 'status@broadcast'
|
||||||
) {
|
) {
|
||||||
if (!message['audio']) {
|
if (!message['audio']) {
|
||||||
this.logger.verbose('Sending message');
|
this.logger.verbose('Sending message');
|
||||||
@ -1507,18 +1522,18 @@ export class WAStartupService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (message['conversation']) {
|
if (message['conversation']) {
|
||||||
console.log(message['conversation']);
|
|
||||||
this.logger.verbose('Sending message');
|
this.logger.verbose('Sending message');
|
||||||
return await this.client.sendMessage(
|
return await this.client.sendMessage(
|
||||||
sender,
|
sender,
|
||||||
{
|
{
|
||||||
text: message['conversation'],
|
text: message['conversation'],
|
||||||
|
mentions,
|
||||||
} as unknown as AnyMessageContent,
|
} as unknown as AnyMessageContent,
|
||||||
option as unknown as MiscMessageGenerationOptions,
|
option as unknown as MiscMessageGenerationOptions,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sender.includes('@broadcast')) {
|
if (sender === 'status@broadcast') {
|
||||||
this.logger.verbose('Sending message');
|
this.logger.verbose('Sending message');
|
||||||
return await this.client.sendMessage(
|
return await this.client.sendMessage(
|
||||||
sender,
|
sender,
|
||||||
@ -1865,6 +1880,8 @@ export class WAStartupService {
|
|||||||
this.logger.verbose('Sending media message');
|
this.logger.verbose('Sending media message');
|
||||||
const generate = await this.prepareMediaMessage(data.mediaMessage);
|
const generate = await this.prepareMediaMessage(data.mediaMessage);
|
||||||
|
|
||||||
|
console.log('generate', generate);
|
||||||
|
|
||||||
return await this.sendMessageWithTyping(
|
return await this.sendMessageWithTyping(
|
||||||
data.number,
|
data.number,
|
||||||
{ ...generate.message },
|
{ ...generate.message },
|
||||||
|
@ -72,7 +72,7 @@ const webhookService = new WebhookService(waMonitor);
|
|||||||
|
|
||||||
export const webhookController = new WebhookController(webhookService);
|
export const webhookController = new WebhookController(webhookService);
|
||||||
|
|
||||||
const chatwootService = new ChatwootService(waMonitor);
|
const chatwootService = new ChatwootService(waMonitor, configService);
|
||||||
|
|
||||||
export const chatwootController = new ChatwootController(chatwootService, configService);
|
export const chatwootController = new ChatwootController(chatwootService, configService);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user