diff --git a/CHANGELOG.md b/CHANGELOG.md index 7429fddc8..315ee04d8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +# 1.4.3 (2023-07-25 10:51) + +### Fixed + +* Adjusts in settings with options always_online, read_messages and read_status +* Fixed send webhook for event CALL +* Create instance with settings + # 1.4.2 (2023-07-24 20:52) ### Fixed diff --git a/Docker/.env.example b/Docker/.env.example index c3dbe5058..f4e8291d7 100644 --- a/Docker/.env.example +++ b/Docker/.env.example @@ -73,6 +73,7 @@ WEBHOOK_EVENTS_GROUPS_UPSERT=true WEBHOOK_EVENTS_GROUPS_UPDATE=true WEBHOOK_EVENTS_GROUP_PARTICIPANTS_UPDATE=true WEBHOOK_EVENTS_CONNECTION_UPDATE=true +WEBHOOK_EVENTS_CALL=true # This event fires every time a new token is requested via the refresh route WEBHOOK_EVENTS_NEW_JWT_TOKEN=false diff --git a/Dockerfile b/Dockerfile index 93fa60c45..0b3ac9506 100644 --- a/Dockerfile +++ b/Dockerfile @@ -74,6 +74,7 @@ ENV WEBHOOK_EVENTS_GROUPS_UPSERT=true ENV WEBHOOK_EVENTS_GROUPS_UPDATE=true ENV WEBHOOK_EVENTS_GROUP_PARTICIPANTS_UPDATE=true ENV WEBHOOK_EVENTS_CONNECTION_UPDATE=true +ENV WEBHOOK_EVENTS_CALL=true ENV WEBHOOK_EVENTS_NEW_JWT_TOKEN=false diff --git a/package.json b/package.json index 6489b86c5..716aeec47 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "evolution-api", - "version": "1.4.2", + "version": "1.4.3", "description": "Rest api for communication with WhatsApp", "main": "./dist/src/main.js", "scripts": { diff --git a/src/config/env.config.ts b/src/config/env.config.ts index 88b718de7..78c90ec9c 100644 --- a/src/config/env.config.ts +++ b/src/config/env.config.ts @@ -89,6 +89,7 @@ export type EventsWebhook = { GROUPS_UPSERT: boolean; GROUP_UPDATE: boolean; GROUP_PARTICIPANTS_UPDATE: boolean; + CALL: boolean; NEW_JWT_TOKEN: boolean; }; @@ -245,6 +246,7 @@ export class ConfigService { GROUP_UPDATE: process.env?.WEBHOOK_EVENTS_GROUPS_UPDATE === 'true', GROUP_PARTICIPANTS_UPDATE: process.env?.WEBHOOK_EVENTS_GROUP_PARTICIPANTS_UPDATE === 'true', + CALL: process.env?.WEBHOOK_EVENTS_CALL === 'true', NEW_JWT_TOKEN: process.env?.WEBHOOK_EVENTS_NEW_JWT_TOKEN === 'true', }, }, diff --git a/src/dev-env.yml b/src/dev-env.yml index 41368ea40..b45d3201a 100644 --- a/src/dev-env.yml +++ b/src/dev-env.yml @@ -110,6 +110,7 @@ WEBHOOK: GROUP_UPDATE: true GROUP_PARTICIPANTS_UPDATE: true CONNECTION_UPDATE: true + CALL: true # This event fires every time a new token is requested via the refresh route NEW_JWT_TOKEN: false diff --git a/src/validate/validate.schema.ts b/src/validate/validate.schema.ts index 3c1f8d0a6..62b7e41cc 100644 --- a/src/validate/validate.schema.ts +++ b/src/validate/validate.schema.ts @@ -53,6 +53,7 @@ export const instanceNameSchema: JSONSchema7 = { 'GROUP_UPDATE', 'GROUP_PARTICIPANTS_UPDATE', 'CONNECTION_UPDATE', + 'CALL', 'NEW_JWT_TOKEN', ], }, @@ -455,7 +456,7 @@ export const readMessageSchema: JSONSchema7 = { $id: v4(), type: 'object', properties: { - readMessages: { + read_messages: { type: 'array', minItems: 1, uniqueItems: true, @@ -470,7 +471,7 @@ export const readMessageSchema: JSONSchema7 = { }, }, }, - required: ['readMessages'], + required: ['read_messages'], }; export const privacySettingsSchema: JSONSchema7 = { @@ -854,6 +855,7 @@ export const webhookSchema: JSONSchema7 = { 'GROUP_UPDATE', 'GROUP_PARTICIPANTS_UPDATE', 'CONNECTION_UPDATE', + 'CALL', 'NEW_JWT_TOKEN', ], }, @@ -884,7 +886,22 @@ export const settingsSchema: JSONSchema7 = { reject_call: { type: 'boolean', enum: [true, false] }, msg_call: { type: 'string' }, groups_ignore: { type: 'boolean', enum: [true, false] }, - }, - required: ['reject_call'], - ...isNotEmpty('reject_call'), + always_online: { type: 'boolean', enum: [true, false] }, + read_messages: { type: 'boolean', enum: [true, false] }, + read_status: { type: 'boolean', enum: [true, false] }, + }, + required: [ + 'reject_call', + 'groups_ignore', + 'always_online', + 'read_messages', + 'read_status', + ], + ...isNotEmpty( + 'reject_call', + 'groups_ignore', + 'always_online', + 'read_messages', + 'read_status', + ), }; diff --git a/src/whatsapp/controllers/instance.controller.ts b/src/whatsapp/controllers/instance.controller.ts index e9e690b3c..9be6ab5d9 100644 --- a/src/whatsapp/controllers/instance.controller.ts +++ b/src/whatsapp/controllers/instance.controller.ts @@ -13,6 +13,7 @@ import { Logger } from '../../config/logger.config'; import { wa } from '../types/wa.types'; import { RedisCache } from '../../db/redis.client'; import { isURL } from 'class-validator'; +import { SettingsService } from '../services/settings.service'; export class InstanceController { constructor( @@ -23,6 +24,7 @@ export class InstanceController { private readonly authService: AuthService, private readonly webhookService: WebhookService, private readonly chatwootService: ChatwootService, + private readonly settingsService: SettingsService, private readonly cache: RedisCache, ) {} @@ -40,6 +42,12 @@ export class InstanceController { chatwoot_token, chatwoot_url, chatwoot_sign_msg, + reject_call, + msg_call, + groups_ignore, + always_online, + read_messages, + read_status, }: InstanceDto) { try { this.logger.verbose('requested createInstance from ' + instanceName + ' instance'); @@ -102,6 +110,20 @@ export class InstanceController { } } + this.logger.verbose('creating settings'); + const settings: wa.LocalSettings = { + reject_call: reject_call || false, + msg_call: msg_call || '', + groups_ignore: groups_ignore || false, + always_online: always_online || false, + read_messages: read_messages || false, + read_status: read_status || false, + }; + + this.logger.verbose('settings: ' + JSON.stringify(settings)); + + this.settingsService.create(instance, settings); + if (!chatwoot_account_id || !chatwoot_token || !chatwoot_url) { let getQrcode: wa.QrCode; @@ -121,6 +143,7 @@ export class InstanceController { webhook, webhook_by_events, events: getEvents, + settings, qrcode: getQrcode, }; @@ -179,6 +202,7 @@ export class InstanceController { webhook, webhook_by_events, events: getEvents, + settings, chatwoot: { enabled: true, account_id: chatwoot_account_id, diff --git a/src/whatsapp/dto/chat.dto.ts b/src/whatsapp/dto/chat.dto.ts index 5af66a5ee..4681ef76b 100644 --- a/src/whatsapp/dto/chat.dto.ts +++ b/src/whatsapp/dto/chat.dto.ts @@ -59,7 +59,7 @@ class Key { remoteJid: string; } export class ReadMessageDto { - readMessages: Key[]; + read_messages: Key[]; } class LastMessage { diff --git a/src/whatsapp/dto/instance.dto.ts b/src/whatsapp/dto/instance.dto.ts index 9e8a7ec3c..ca88a7295 100644 --- a/src/whatsapp/dto/instance.dto.ts +++ b/src/whatsapp/dto/instance.dto.ts @@ -1,11 +1,17 @@ export class InstanceDto { instanceName: string; - webhook?: string; - webhook_by_events?: boolean; - events?: string[]; qrcode?: boolean; number?: string; token?: string; + webhook?: string; + webhook_by_events?: boolean; + events?: string[]; + reject_call?: boolean; + msg_call?: string; + groups_ignore?: boolean; + always_online?: boolean; + read_messages?: boolean; + read_status?: boolean; chatwoot_account_id?: string; chatwoot_token?: string; chatwoot_url?: string; diff --git a/src/whatsapp/dto/settings.dto.ts b/src/whatsapp/dto/settings.dto.ts index 20a6cba05..594ab3a4c 100644 --- a/src/whatsapp/dto/settings.dto.ts +++ b/src/whatsapp/dto/settings.dto.ts @@ -2,4 +2,7 @@ export class SettingsDto { reject_call?: boolean; msg_call?: string; groups_ignore?: boolean; + always_online?: boolean; + read_messages?: boolean; + read_status?: boolean; } diff --git a/src/whatsapp/models/settings.model.ts b/src/whatsapp/models/settings.model.ts index b5eb7fe76..b6d2488da 100644 --- a/src/whatsapp/models/settings.model.ts +++ b/src/whatsapp/models/settings.model.ts @@ -6,6 +6,9 @@ export class SettingsRaw { reject_call?: boolean; msg_call?: string; groups_ignore?: boolean; + always_online?: boolean; + read_messages?: boolean; + read_status?: boolean; } const settingsSchema = new Schema({ @@ -13,6 +16,9 @@ const settingsSchema = new Schema({ reject_call: { type: Boolean, required: true }, msg_call: { type: String, required: true }, groups_ignore: { type: Boolean, required: true }, + always_online: { type: Boolean, required: true }, + read_messages: { type: Boolean, required: true }, + read_status: { type: Boolean, required: true }, }); export const SettingsModel = dbserver?.model( diff --git a/src/whatsapp/services/whatsapp.service.ts b/src/whatsapp/services/whatsapp.service.ts index ff6fdd71c..8959197ef 100644 --- a/src/whatsapp/services/whatsapp.service.ts +++ b/src/whatsapp/services/whatsapp.service.ts @@ -362,6 +362,15 @@ export class WAStartupService { this.localSettings.groups_ignore = data?.groups_ignore; this.logger.verbose(`Settings groups_ignore: ${this.localSettings.groups_ignore}`); + this.localSettings.always_online = data?.always_online; + this.logger.verbose(`Settings always_online: ${this.localSettings.always_online}`); + + this.localSettings.read_messages = data?.read_messages; + this.logger.verbose(`Settings read_messages: ${this.localSettings.read_messages}`); + + this.localSettings.read_status = data?.read_status; + this.logger.verbose(`Settings read_status: ${this.localSettings.read_status}`); + this.logger.verbose('Settings loaded'); } @@ -371,8 +380,13 @@ export class WAStartupService { this.logger.verbose(`Settings reject_call: ${data.reject_call}`); this.logger.verbose(`Settings msg_call: ${data.msg_call}`); this.logger.verbose(`Settings groups_ignore: ${data.groups_ignore}`); + this.logger.verbose(`Settings always_online: ${data.always_online}`); + this.logger.verbose(`Settings read_messages: ${data.read_messages}`); + this.logger.verbose(`Settings read_status: ${data.read_status}`); Object.assign(this.localSettings, data); this.logger.verbose('Settings set'); + + this.client?.ws?.close(); } public async findSettings() { @@ -387,6 +401,9 @@ export class WAStartupService { this.logger.verbose(`Settings url: ${data.reject_call}`); this.logger.verbose(`Settings msg_call: ${data.msg_call}`); this.logger.verbose(`Settings groups_ignore: ${data.groups_ignore}`); + this.logger.verbose(`Settings always_online: ${data.always_online}`); + this.logger.verbose(`Settings read_messages: ${data.read_messages}`); + this.logger.verbose(`Settings read_status: ${data.read_status}`); return data; } @@ -847,6 +864,7 @@ export class WAStartupService { printQRInTerminal: false, browser, version, + markOnlineOnConnect: this.localSettings.always_online, connectTimeoutMs: 60_000, qrTimeout: 40_000, defaultQueryTimeoutMs: undefined, @@ -1143,6 +1161,14 @@ export class WAStartupService { source: getDevice(received.key.id), }; + if (this.localSettings.read_messages && received.key.id !== 'status@broadcast') { + await this.client.readMessages([received.key]); + } + + if (this.localSettings.read_status && received.key.id === 'status@broadcast') { + await this.client.readMessages([received.key]); + } + this.logger.log(messageRaw); this.logger.verbose('Sending data to webhook in event MESSAGES_UPSERT'); @@ -1362,11 +1388,15 @@ export class WAStartupService { text: settings.msg_call, }); + this.logger.verbose('Sending data to event messages.upsert'); this.client.ev.emit('messages.upsert', { messages: [msg], type: 'notify', }); } + + this.logger.verbose('Sending data to webhook in event CALL'); + this.sendDataWebhook(Events.CALL, call); } if (events['connection.update']) { @@ -2400,7 +2430,7 @@ export class WAStartupService { this.logger.verbose('Marking message as read'); try { const keys: proto.IMessageKey[] = []; - data.readMessages.forEach((read) => { + data.read_messages.forEach((read) => { if (isJidGroup(read.remoteJid) || isJidUser(read.remoteJid)) { keys.push({ remoteJid: read.remoteJid, @@ -2640,7 +2670,6 @@ export class WAStartupService { await this.client.updateGroupsAddPrivacy(settings.privacySettings.groupadd); this.logger.verbose('Groups add privacy updated'); - // reinicia a instancia this.client?.ws?.close(); return { diff --git a/src/whatsapp/types/wa.types.ts b/src/whatsapp/types/wa.types.ts index d0c5f80cd..80aede986 100644 --- a/src/whatsapp/types/wa.types.ts +++ b/src/whatsapp/types/wa.types.ts @@ -22,6 +22,7 @@ export enum Events { GROUPS_UPSERT = 'groups.upsert', GROUPS_UPDATE = 'groups.update', GROUP_PARTICIPANTS_UPDATE = 'group-participants.update', + CALL = 'call', } export declare namespace wa { @@ -61,6 +62,9 @@ export declare namespace wa { reject_call?: boolean; msg_call?: string; groups_ignore?: boolean; + always_online?: boolean; + read_messages?: boolean; + read_status?: boolean; }; export type StateConnection = { diff --git a/src/whatsapp/whatsapp.module.ts b/src/whatsapp/whatsapp.module.ts index 9f2fed007..b8f3b1ad4 100644 --- a/src/whatsapp/whatsapp.module.ts +++ b/src/whatsapp/whatsapp.module.ts @@ -94,6 +94,7 @@ export const instanceController = new InstanceController( authService, webhookService, chatwootService, + settingsService, cache, ); export const viewsController = new ViewsController(waMonitor, configService);