fix: clear WhatsApp typing indicator after response (#243)
WhatsApp's "typing..." indicator lingers for 15-25 seconds after the bot
finishes responding because there was no way to clear it. This adds
stopTypingIndicator() which sends a "paused" presence update to
immediately dismiss it.
- stopTypingIndicator?() added to ChannelAdapter interface (optional)
- WhatsApp adapter implements it via sendPresenceUpdate("paused")
- bot.ts calls it in the finally block after stream processing
Written by Cameron ◯ Letta Code
"First, solve the problem. Then, write the code." - John Johnson
This commit is contained in:
@@ -22,6 +22,7 @@ export interface ChannelAdapter {
|
||||
sendMessage(msg: OutboundMessage): Promise<{ messageId: string }>;
|
||||
editMessage(chatId: string, messageId: string, text: string): Promise<void>;
|
||||
sendTypingIndicator(chatId: string): Promise<void>;
|
||||
stopTypingIndicator?(chatId: string): Promise<void>;
|
||||
|
||||
// Capabilities (optional)
|
||||
supportsEditing?(): boolean;
|
||||
|
||||
@@ -47,6 +47,7 @@ import {
|
||||
sendWhatsAppMessage,
|
||||
sendWhatsAppFile,
|
||||
sendTypingIndicator,
|
||||
stopTypingIndicator,
|
||||
sendReadReceipt,
|
||||
type LidMapper,
|
||||
} from "./outbound.js";
|
||||
@@ -1017,6 +1018,11 @@ export class WhatsAppAdapter implements ChannelAdapter {
|
||||
if (!this.sock) return;
|
||||
await sendTypingIndicator(this.sock, chatId);
|
||||
}
|
||||
|
||||
async stopTypingIndicator(chatId: string): Promise<void> {
|
||||
if (!this.sock) return;
|
||||
await stopTypingIndicator(this.sock, chatId);
|
||||
}
|
||||
}
|
||||
|
||||
// Export types and config
|
||||
|
||||
@@ -168,6 +168,24 @@ export async function sendTypingIndicator(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop typing indicator for a chat.
|
||||
* Sends "paused" presence to immediately clear the "typing..." indicator
|
||||
* instead of waiting for WhatsApp's built-in timeout (~15-25s).
|
||||
*/
|
||||
export async function stopTypingIndicator(
|
||||
sock: import("@whiskeysockets/baileys").WASocket,
|
||||
chatId: string
|
||||
): Promise<void> {
|
||||
if (!sock) return;
|
||||
|
||||
try {
|
||||
await sock.sendPresenceUpdate("paused", chatId);
|
||||
} catch {
|
||||
// Ignore presence errors
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send read receipt for a message.
|
||||
*
|
||||
|
||||
@@ -725,6 +725,7 @@ export class LettaBot implements AgentSession {
|
||||
}
|
||||
} finally {
|
||||
clearInterval(typingInterval);
|
||||
adapter.stopTypingIndicator?.(msg.chatId)?.catch(() => {});
|
||||
}
|
||||
|
||||
// Handle no-reply marker
|
||||
|
||||
Reference in New Issue
Block a user