@ihazz/bitrix24 1.1.0 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ihazz/bitrix24",
3
- "version": "1.1.0",
3
+ "version": "1.1.1",
4
4
  "description": "Bitrix24 Messenger channel for OpenClaw",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -142,8 +142,9 @@ export class InboundHandler {
142
142
  }
143
143
  const messageId = String(rawMessageId);
144
144
 
145
- if (this.dedup.isDuplicate(messageId)) {
146
- this.logger.debug(`Fetch: duplicate message ${messageId}, skipping`);
145
+ const dedupKey = `${eventScope}:${messageId}`;
146
+ if (this.dedup.isDuplicate(dedupKey)) {
147
+ this.logger.debug(`Fetch: duplicate message ${messageId} for scope ${eventScope}, skipping`);
147
148
  return true;
148
149
  }
149
150
 
@@ -192,7 +192,7 @@ describe('InboundHandler', () => {
192
192
  });
193
193
  });
194
194
 
195
- it('deduplicates bot and user message events that share one message id', async () => {
195
+ it('processes bot and user message events separately when they share one message id', async () => {
196
196
  const onMessage = vi.fn();
197
197
  handler = new InboundHandler({
198
198
  config: { dmPolicy: 'pairing', agentMode: true },
@@ -269,7 +269,54 @@ describe('InboundHandler', () => {
269
269
  await handler.handleFetchEvent(botEvent as never, fetchCtx);
270
270
  await handler.handleFetchEvent(userEvent as never, fetchCtx);
271
271
 
272
+ expect(onMessage).toHaveBeenCalledTimes(2);
273
+ expect((onMessage.mock.calls[0][0] as B24MsgContext).eventScope).toBe('bot');
274
+ expect((onMessage.mock.calls[1][0] as B24MsgContext).eventScope).toBe('user');
275
+ });
276
+
277
+ it('still deduplicates repeated events within the same scope', async () => {
278
+ const onMessage = vi.fn();
279
+ handler = new InboundHandler({
280
+ config: { dmPolicy: 'pairing', agentMode: true },
281
+ logger: silentLogger,
282
+ onMessage,
283
+ });
284
+
285
+ const botEvent = createFetchMessageEvent({
286
+ message: {
287
+ id: 555002,
288
+ chatId: 520,
289
+ authorId: 77,
290
+ date: '2026-03-19T14:36:03+02:00',
291
+ text: 'same scope duplicate',
292
+ isSystem: false,
293
+ uuid: '',
294
+ forward: null,
295
+ params: {},
296
+ viewedByOthers: false,
297
+ },
298
+ chat: {
299
+ id: 520,
300
+ dialogId: 'chat520',
301
+ type: 'chat',
302
+ name: 'Group Chat',
303
+ entityType: '',
304
+ owner: 1,
305
+ avatar: '',
306
+ color: '#ab7761',
307
+ },
308
+ user: {
309
+ ...baseUser,
310
+ id: 77,
311
+ name: 'Sergey',
312
+ },
313
+ });
314
+
315
+ await handler.handleFetchEvent(botEvent as never, fetchCtx);
316
+ await handler.handleFetchEvent(botEvent as never, fetchCtx);
317
+
272
318
  expect(onMessage).toHaveBeenCalledTimes(1);
319
+ expect((onMessage.mock.calls[0][0] as B24MsgContext).eventScope).toBe('bot');
273
320
  });
274
321
 
275
322
  it('keeps incoming dialogId for direct chats without replacing it by user id', async () => {