Skip to content

Commit 5d92f3c

Browse files
committed
fix group message ignore
1 parent 492d5d4 commit 5d92f3c

File tree

8 files changed

+219
-98
lines changed

8 files changed

+219
-98
lines changed

__tests__/routes/templates.ts

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,15 @@
11
import request from 'supertest'
2+
import { mock } from 'jest-mock-extended'
23

34
import { App } from '../../src/app'
45
import { Incoming } from '../../src/services/incoming'
56
import { Outgoing } from '../../src/services/outgoing'
67
import { getDataStoreFile } from '../../src/services/data_store_file'
7-
import { Response } from '../../src/services/response'
88

99
describe('templates routes', () => {
1010
test('index', async () => {
11-
const incoming: Incoming = {
12-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
13-
async send(_phone: string, _payload: object) {
14-
const r: Response = { ok: { any: '1' }, to: 'dknfsdkf' }
15-
return r
16-
},
17-
}
18-
const outgoing: Outgoing = {
19-
// eslint-disable-next-line @typescript-eslint/no-empty-function, @typescript-eslint/no-unused-vars
20-
sendMany: async function (phone: string, messages: object[]) {},
21-
// eslint-disable-next-line @typescript-eslint/no-empty-function, @typescript-eslint/no-unused-vars
22-
sendOne: async function (phone: string, message: object) {},
23-
// eslint-disable-next-line @typescript-eslint/no-empty-function, @typescript-eslint/no-unused-vars
24-
send: async function (phone: string, message: object) {},
25-
}
11+
const incoming = mock<Incoming>()
12+
const outgoing = mock<Outgoing>()
2613
const app: App = new App(incoming, outgoing, '', getDataStoreFile)
2714
const res = await request(app.server).get('/v15.0/123/message_templates')
2815
expect(res.status).toEqual(200)

__tests__/routes/webook.ts

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,15 @@
11
import request from 'supertest'
2+
import { mock } from 'jest-mock-extended'
23

34
import { App } from '../../src/app'
45
import { Incoming } from '../../src/services/incoming'
56
import { Outgoing } from '../../src/services/outgoing'
67
import { getDataStoreFile } from '../../src/services/data_store_file'
7-
import { Response } from '../../src/services/response'
88

99
describe('webhook routes', () => {
1010
test('whatsapp', async () => {
11-
const incoming: Incoming = {
12-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
13-
async send(_phone: string, _payload: object) {
14-
const r: Response = { ok: { any: '1' }, to: 'dknfsdkf' }
15-
return r
16-
},
17-
}
18-
const outgoing: Outgoing = {
19-
// eslint-disable-next-line @typescript-eslint/no-empty-function, @typescript-eslint/no-unused-vars
20-
sendMany: async function (phone: string, messages: object[]) {},
21-
// eslint-disable-next-line @typescript-eslint/no-empty-function, @typescript-eslint/no-unused-vars
22-
sendOne: async function (phone: string, message: object) {},
23-
// eslint-disable-next-line @typescript-eslint/no-empty-function, @typescript-eslint/no-unused-vars
24-
send: async function (phone: string, message: object) {},
25-
}
11+
const incoming = mock<Incoming>()
12+
const outgoing = mock<Outgoing>()
2613
const app: App = new App(incoming, outgoing, '', getDataStoreFile)
2714
const res = await request(app.server).post('/webhooks/whatsapp/123')
2815
expect(res.status).toEqual(200)

__tests__/services/message_filter.ts

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
import { WAMessageKey } from '@adiwajshing/baileys'
2+
import { ClientConfig, defaultClientConfig } from '../../src/services/client'
3+
import { MessageFilter } from '../../src/services/message_filter'
4+
5+
describe('service message filter', () => {
6+
test('ignore group message', async () => {
7+
const config: ClientConfig = {
8+
...defaultClientConfig,
9+
ignoreGroupMessages: true,
10+
ignoreBroadcastStatuses: false,
11+
ignoreBroadcastMessages: false,
12+
ignoreOwnMessages: false,
13+
}
14+
const filter: MessageFilter = new MessageFilter(config)
15+
const key: WAMessageKey = {
16+
remoteJid: 'akjshdkasdsadhk@g.us',
17+
}
18+
expect(filter.isIgnore({ key })).toBe(true)
19+
})
20+
21+
test('not ignore group message', async () => {
22+
const config: ClientConfig = {
23+
...defaultClientConfig,
24+
ignoreGroupMessages: false,
25+
ignoreBroadcastStatuses: false,
26+
ignoreBroadcastMessages: false,
27+
ignoreOwnMessages: false,
28+
}
29+
const filter: MessageFilter = new MessageFilter(config)
30+
const key: WAMessageKey = {
31+
remoteJid: 'akjshdkasdsadhk@g.us',
32+
}
33+
expect(filter.isIgnore({ key })).toBe(false)
34+
})
35+
36+
test('ignore own message', async () => {
37+
const config: ClientConfig = {
38+
ignoreGroupMessages: false,
39+
ignoreBroadcastStatuses: false,
40+
ignoreBroadcastMessages: false,
41+
ignoreOwnMessages: true,
42+
}
43+
const filter: MessageFilter = new MessageFilter(config)
44+
const key: WAMessageKey = {
45+
fromMe: true,
46+
remoteJid: '456',
47+
}
48+
expect(filter.isIgnore({ key })).toBe(true)
49+
})
50+
51+
test('not ignore own message', async () => {
52+
const config: ClientConfig = {
53+
...defaultClientConfig,
54+
ignoreGroupMessages: false,
55+
ignoreBroadcastStatuses: false,
56+
ignoreBroadcastMessages: false,
57+
ignoreOwnMessages: false,
58+
}
59+
const filter: MessageFilter = new MessageFilter(config)
60+
const key: WAMessageKey = {
61+
fromMe: true,
62+
remoteJid: '123',
63+
}
64+
expect(filter.isIgnore({ key })).toBe(false)
65+
})
66+
67+
test('ignore broadcast status', async () => {
68+
const config: ClientConfig = {
69+
ignoreGroupMessages: false,
70+
ignoreBroadcastStatuses: true,
71+
ignoreBroadcastMessages: false,
72+
ignoreOwnMessages: false,
73+
}
74+
const filter: MessageFilter = new MessageFilter(config)
75+
const key: WAMessageKey = {
76+
remoteJid: 'status@broadcast',
77+
}
78+
expect(filter.isIgnore({ key })).toBe(true)
79+
})
80+
81+
test('not broadcast status', async () => {
82+
const config: ClientConfig = {
83+
...defaultClientConfig,
84+
ignoreGroupMessages: false,
85+
ignoreBroadcastStatuses: false,
86+
ignoreBroadcastMessages: false,
87+
ignoreOwnMessages: false,
88+
}
89+
const filter: MessageFilter = new MessageFilter(config)
90+
const key: WAMessageKey = {
91+
remoteJid: 'status@broadcast',
92+
}
93+
expect(filter.isIgnore({ key })).toBe(false)
94+
})
95+
96+
test('ignore broadcast message', async () => {
97+
const config: ClientConfig = {
98+
ignoreGroupMessages: false,
99+
ignoreBroadcastStatuses: false,
100+
ignoreBroadcastMessages: true,
101+
ignoreOwnMessages: false,
102+
}
103+
const filter: MessageFilter = new MessageFilter(config)
104+
const key: WAMessageKey = {
105+
remoteJid: '456@broadcast',
106+
}
107+
expect(filter.isIgnore({ key })).toBe(true)
108+
})
109+
110+
test('not broadcast message', async () => {
111+
const config: ClientConfig = {
112+
...defaultClientConfig,
113+
ignoreGroupMessages: false,
114+
ignoreBroadcastStatuses: false,
115+
ignoreBroadcastMessages: false,
116+
ignoreOwnMessages: false,
117+
}
118+
const filter: MessageFilter = new MessageFilter(config)
119+
const key: WAMessageKey = {
120+
remoteJid: '789@broadcast',
121+
}
122+
expect(filter.isIgnore({ key })).toBe(false)
123+
})
124+
})

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "unoapi-cloud",
3-
"version": "0.7.3",
3+
"version": "0.7.4",
44
"description": "Unoapi Cloud",
55
"main": "dist/index.js",
66
"types": "dist/index.d.ts",

src/index.ts

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { SessionStoreFile } from './services/session_store_file'
1010
import { SessionStore } from './services/session_store'
1111
import { autoConnect } from './services/auto_connect'
1212
import { ClientConfig, defaultClientConfig } from './services/client'
13+
import { MessageFilter } from './services/message_filter'
1314
const {
1415
WEBHOOK_URL,
1516
WEBHOOK_TOKEN,
@@ -23,12 +24,6 @@ const {
2324
} = process.env
2425
const port: number = parseInt(PORT || '9876')
2526

26-
const cloudApi: Outgoing = new OutgoingCloudApi(
27-
WEBHOOK_URL || `http://localhost:${port}/webhooks/whatsapp`,
28-
WEBHOOK_TOKEN || 'abc123',
29-
WEBHOOK_HEADER || 'Authorization',
30-
)
31-
3227
// eslint-disable-next-line @typescript-eslint/no-explicit-any
3328
const _undefined: any = undefined
3429
const config: ClientConfig = defaultClientConfig
@@ -37,6 +32,15 @@ config.ignoreBroadcastStatuses = IGNORE_BROADCAST_STATUSES === _undefined ? true
3732
config.ignoreBroadcastMessages = IGNORE_BROADCAST_MESSAGES === _undefined ? false : IGNORE_OWN_MESSAGES === 'true'
3833
config.ignoreOwnMessages = IGNORE_OWN_MESSAGES === _undefined ? true : IGNORE_OWN_MESSAGES === 'true'
3934

35+
const filter: MessageFilter = new MessageFilter(config)
36+
37+
const cloudApi: Outgoing = new OutgoingCloudApi(
38+
filter,
39+
WEBHOOK_URL || `http://localhost:${port}/webhooks/whatsapp`,
40+
WEBHOOK_TOKEN || 'abc123',
41+
WEBHOOK_HEADER || 'Authorization',
42+
)
43+
4044
console.debug('ClientConfig', config)
4145

4246
const baileys: Incoming = new IncomingBaileys(cloudApi, config)

src/services/client_baileys.ts

Lines changed: 5 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1-
import { AnyMessageContent, WASocket, WAMessage, isJidStatusBroadcast, isJidGroup, isJidBroadcast, GroupMetadata } from '@adiwajshing/baileys'
1+
import { AnyMessageContent, WASocket, WAMessage, GroupMetadata } from '@adiwajshing/baileys'
22
import { Outgoing } from './outgoing'
33
import { Store, getStore, stores } from './store'
44
import { connect, Connection } from './socket'
5-
import { Client, ConnectionInProgress, ClientConfig, defaultClientConfig } from './client'
5+
import { Client, getClient, ConnectionInProgress, ClientConfig, defaultClientConfig } from './client'
66
import { toBaileysMessageContent, phoneNumberToJid, isIndividualJid, getMessageType, TYPE_MESSAGES_TO_PROCESS_FILE } from './transformer'
77
import { v1 as uuid } from 'uuid'
8-
import { getClient } from './client'
98
import { Response } from './response'
109
import { dataStores } from './data_store'
1110

@@ -32,20 +31,6 @@ export const getClientBaileys: getClient = async (phone: string, outgoing: Outgo
3231
return clients.get(phone) as Client
3332
}
3433

35-
interface IgnoreJid {
36-
(jid: string): boolean
37-
}
38-
39-
interface IgnoreMessage {
40-
(message: WAMessage): boolean
41-
}
42-
43-
const IgnoreOwnMessage: IgnoreMessage = (message: WAMessage) => {
44-
const filter = !message.key.fromMe
45-
console.debug('IgnoreOwnMessage: %s => %s', message.key, filter)
46-
return filter
47-
}
48-
4934
interface GetGroupMetadata {
5035
(message: WAMessage, store: Store, sock: WASocket): Promise<GroupMetadata | undefined>
5136
}
@@ -61,25 +46,12 @@ const getGroupMetadata: GetGroupMetadata = async (message: WAMessage, store: Sto
6146
return undefined
6247
}
6348

64-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
65-
const notIgnoreJid = (_jid: string) => {
66-
console.info('Config to not ignore any jid')
67-
return false
68-
}
69-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
70-
const notIgnoreMessage = (_m: WAMessage) => {
71-
console.info('Config to not ignore any message/update')
72-
return false
73-
}
74-
7549
class ClientBaileys implements Client {
7650
public phone: string
7751
public config: ClientConfig
7852
private sock: WASocket | undefined
7953
private outgoing: Outgoing
8054
private store: Store | undefined
81-
private ignoreJid: IgnoreJid
82-
private ignoreMessage: IgnoreMessage
8355
private getGroupMetadata: GetGroupMetadata
8456

8557
constructor(phone: string, store: Store, outgoing: Outgoing, config: ClientConfig = defaultClientConfig) {
@@ -88,30 +60,6 @@ class ClientBaileys implements Client {
8860
this.outgoing = outgoing
8961
this.config = config
9062

91-
const ignoresJid: IgnoreJid[] = []
92-
const ignoresMessage: IgnoreMessage[] = []
93-
94-
if (config.ignoreGroupMessages) {
95-
console.info('Config to ignore group messages')
96-
ignoresJid.push(isJidGroup as IgnoreJid)
97-
}
98-
if (config.ignoreBroadcastStatuses) {
99-
console.info('Config to ignore broadcast statuses')
100-
ignoresJid.push(isJidStatusBroadcast as IgnoreJid)
101-
}
102-
if (config.ignoreBroadcastMessages) {
103-
console.info('Config to ignore broadcast messages')
104-
ignoresJid.push(isJidBroadcast as IgnoreJid)
105-
}
106-
if (config.ignoreOwnMessages) {
107-
console.info('Config to ignore own messages')
108-
ignoresMessage.push(IgnoreOwnMessage)
109-
}
110-
111-
const ignoreJid = (jid: string) => ignoresJid.reduce((acc, f) => (f(jid) ? ++acc : acc), 0) > 0
112-
this.ignoreJid = ignoresJid.length > 0 ? ignoreJid : notIgnoreJid
113-
const ignoreMessage = (m: WAMessage) => ignoresMessage.reduce((acc, f) => (f(m) ? ++acc : acc), 0) > 0
114-
this.ignoreMessage = ignoresMessage.length > 0 ? ignoreMessage : notIgnoreMessage
11563
this.getGroupMetadata = config.ignoreGroupMessages ? ignoreGetGroupMetadata : getGroupMetadata
11664
}
11765

@@ -305,9 +253,9 @@ class ClientBaileys implements Client {
305253

306254
// eslint-disable-next-line @typescript-eslint/no-explicit-any
307255
async receive(messages: any[], update = true) {
308-
let m = messages.filter((m) => !this.ignoreJid(m?.key?.jid) && !this.ignoreMessage(m))
256+
console.debug(`Receives %s message(s)/update(s)`, messages.length)
309257
if (!update) {
310-
m = await Promise.all(
258+
messages = await Promise.all(
311259
// eslint-disable-next-line @typescript-eslint/no-explicit-any
312260
messages.map(async (m: any) => {
313261
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
@@ -321,7 +269,7 @@ class ClientBaileys implements Client {
321269
}),
322270
)
323271
}
324-
return this.outgoing.sendMany(this.phone, m)
272+
return this.outgoing.sendMany(this.phone, messages)
325273
}
326274

327275
private async toJid(phoneNumber: string) {

0 commit comments

Comments
 (0)