diff --git a/README.md b/README.md index 2e88050..905f987 100644 --- a/README.md +++ b/README.md @@ -314,7 +314,10 @@ The `.env` can be save one configm, but on redis use different webhook by sessio { "url": "http://localhost:3000/whatsapp/webhook", "token": "kslflkhlkwq", - "header": "api_access_token" + "header": "api_access_token", + "sendGroupMessages": false, + "sendGroupMessages": false, + "sendNewMessages": false, } ], "ignoreDataStore": false diff --git a/__tests__/services/transformer.ts b/__tests__/services/transformer.ts index ad8d166..a1aa859 100644 --- a/__tests__/services/transformer.ts +++ b/__tests__/services/transformer.ts @@ -13,6 +13,7 @@ import { getNormalizedMessage, isSaveMedia, extractDestinyPhone, + isGroupMessage, } from '../../src/services/transformer' const key = { remoteJid: 'XXXX@s.whatsapp.net', id: 'abc' } @@ -68,6 +69,57 @@ describe('service transformer', () => { expect(extractDestinyPhone(payload)).toBe('x') }) + test('return isGroupMessage false with status', async () => { + const payload = { + entry: [ + { + changes: [ + { + value: { + statuses: [{ recipient_id: 'x' }] + } + } + ] + } + ] + } + expect(isGroupMessage(payload)).toBe(false) + }) + + test('return isGroupMessage false with non group', async () => { + const payload = { + entry: [ + { + changes: [ + { + value: { + contacts: [{ wa_id: 'y' }], + }, + }, + ], + }, + ], + } + expect(isGroupMessage(payload)).toBe(false) + }) + + test('return isGroupMessage true', async () => { + const payload = { + entry: [ + { + changes: [ + { + value: { + contacts: [{ group_id: 'y' }], + }, + }, + ], + }, + ], + } + expect(isGroupMessage(payload)).toBe(true) + }) + test('return empty extractDestinyPhone from api payload', async () => { expect(extractDestinyPhone({ to: 'y' })).toBe('y') }) diff --git a/package.json b/package.json index ac814e1..f97bf47 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "unoapi-cloud", - "version": "1.19.2", + "version": "1.20.0", "description": "Unoapi Cloud", "exports": "./dist/index.js", "types": "./dist/index.d.ts", diff --git a/src/services/config.ts b/src/services/config.ts index 1621ae7..c29a553 100644 --- a/src/services/config.ts +++ b/src/services/config.ts @@ -20,6 +20,7 @@ export type Webhook = { header: string timeoutMs: number sendNewMessages: boolean + sendGroupMessages: boolean } export type Config = { @@ -92,6 +93,7 @@ export const defaultConfig: Config = { header: '', timeoutMs: 5_000, sendNewMessages: false, + sendGroupMessages: true, }, ], getMessageMetadata: getMessageMetadataDefault, diff --git a/src/services/outgoing_cloud_api.ts b/src/services/outgoing_cloud_api.ts index 2981d9b..a87a431 100644 --- a/src/services/outgoing_cloud_api.ts +++ b/src/services/outgoing_cloud_api.ts @@ -2,7 +2,7 @@ import { Outgoing } from './outgoing' import fetch, { Response, RequestInit } from 'node-fetch' import { Webhook, getConfig } from './config' import logger from './logger' -import { completeCloudApiWebHook } from './transformer' +import { completeCloudApiWebHook, isGroupMessage } from './transformer' import { isInBlacklist } from './blacklist' import { EnqueueOption } from '../amqp' @@ -32,6 +32,10 @@ export class OutgoingCloudApi implements Outgoing { logger.info(`Session phone %s webhook %s and destiny phone %s are in blacklist`, phone, webhook.id, destinyPhone) return } + if (!webhook.sendGroupMessages && isGroupMessage(message)) { + logger.info(`Session phone %s webhook %s configured to not send group message for this webhook`, phone, webhook.id) + return + } const body = JSON.stringify(message) const headers = { 'Content-Type': 'application/json; charset=utf-8', diff --git a/src/services/transformer.ts b/src/services/transformer.ts index c9fb177..53f4e42 100644 --- a/src/services/transformer.ts +++ b/src/services/transformer.ts @@ -337,6 +337,26 @@ export const extractDestinyPhone = (payload: object) => { return number } +export const isGroupMessage = (payload: object) => { + const data = payload as any + return !!( + ( + data.entry + && data.entry[0] + && data.entry[0].changes + && data.entry[0].changes[0] + && data.entry[0].changes[0].value + ) && ( + ( + data.entry[0].changes[0].value.contacts + && data.entry[0].changes[0].value.contacts[0] + && data.entry[0].changes[0].value.contacts[0].group_id + ) + ) + ) +} + + // eslint-disable-next-line @typescript-eslint/no-explicit-any export const jidToPhoneNumber = (value: any, plus = '+', retry = true): string => { const number = (value || '').split('@')[0].split(':')[0].replace('+', '')