From 6f2e10f0c3b4dab8dbca87590e87b5c865548651 Mon Sep 17 00:00:00 2001 From: Gavriel Cohen Date: Sat, 14 Feb 2026 14:25:29 +0200 Subject: [PATCH] fix: typing indicator now shows on every message, not just the first Two issues fixed: - Use 'paused' instead of 'available' to stop typing. Baileys' sendPresenceUpdate('available') sends a global stanza and ignores the JID, so chatstate never left 'composing' and WhatsApp suppressed duplicate composing notifications per XEP-0085. - Add setTyping call when piping messages to an already-running container. Previously only the first message (which spawns a new container) triggered the typing indicator. Co-Authored-By: Claude Opus 4.6 --- src/channels/whatsapp.test.ts | 4 ++-- src/channels/whatsapp.ts | 4 +++- src/index.ts | 2 ++ 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/channels/whatsapp.test.ts b/src/channels/whatsapp.test.ts index bacba46..1ed11ea 100644 --- a/src/channels/whatsapp.test.ts +++ b/src/channels/whatsapp.test.ts @@ -823,14 +823,14 @@ describe('WhatsAppChannel', () => { expect(fakeSocket.sendPresenceUpdate).toHaveBeenCalledWith('composing', 'test@g.us'); }); - it('sends available presence when stopping', async () => { + it('sends paused presence when stopping', async () => { const opts = createTestOpts(); const channel = new WhatsAppChannel(opts); await connectChannel(channel); await channel.setTyping('test@g.us', false); - expect(fakeSocket.sendPresenceUpdate).toHaveBeenCalledWith('available', 'test@g.us'); + expect(fakeSocket.sendPresenceUpdate).toHaveBeenCalledWith('paused', 'test@g.us'); }); it('handles typing indicator failure gracefully', async () => { diff --git a/src/channels/whatsapp.ts b/src/channels/whatsapp.ts index 17c9b72..1269d88 100644 --- a/src/channels/whatsapp.ts +++ b/src/channels/whatsapp.ts @@ -218,7 +218,9 @@ export class WhatsAppChannel implements Channel { async setTyping(jid: string, isTyping: boolean): Promise { try { - await this.sock.sendPresenceUpdate(isTyping ? 'composing' : 'available', jid); + const status = isTyping ? 'composing' : 'paused'; + logger.debug({ jid, status }, 'Sending presence update'); + await this.sock.sendPresenceUpdate(status, jid); } catch (err) { logger.debug({ jid, err }, 'Failed to update typing status'); } diff --git a/src/index.ts b/src/index.ts index 999cf97..a385bb0 100644 --- a/src/index.ts +++ b/src/index.ts @@ -360,6 +360,8 @@ async function startMessageLoop(): Promise { lastAgentTimestamp[chatJid] = messagesToSend[messagesToSend.length - 1].timestamp; saveState(); + // Show typing indicator while the container processes the piped message + whatsapp.setTyping(chatJid, true); } else { // No active container — enqueue for a new one queue.enqueueMessageCheck(chatJid);