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 }>;
|
sendMessage(msg: OutboundMessage): Promise<{ messageId: string }>;
|
||||||
editMessage(chatId: string, messageId: string, text: string): Promise<void>;
|
editMessage(chatId: string, messageId: string, text: string): Promise<void>;
|
||||||
sendTypingIndicator(chatId: string): Promise<void>;
|
sendTypingIndicator(chatId: string): Promise<void>;
|
||||||
|
stopTypingIndicator?(chatId: string): Promise<void>;
|
||||||
|
|
||||||
// Capabilities (optional)
|
// Capabilities (optional)
|
||||||
supportsEditing?(): boolean;
|
supportsEditing?(): boolean;
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ import {
|
|||||||
sendWhatsAppMessage,
|
sendWhatsAppMessage,
|
||||||
sendWhatsAppFile,
|
sendWhatsAppFile,
|
||||||
sendTypingIndicator,
|
sendTypingIndicator,
|
||||||
|
stopTypingIndicator,
|
||||||
sendReadReceipt,
|
sendReadReceipt,
|
||||||
type LidMapper,
|
type LidMapper,
|
||||||
} from "./outbound.js";
|
} from "./outbound.js";
|
||||||
@@ -1017,6 +1018,11 @@ export class WhatsAppAdapter implements ChannelAdapter {
|
|||||||
if (!this.sock) return;
|
if (!this.sock) return;
|
||||||
await sendTypingIndicator(this.sock, chatId);
|
await sendTypingIndicator(this.sock, chatId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async stopTypingIndicator(chatId: string): Promise<void> {
|
||||||
|
if (!this.sock) return;
|
||||||
|
await stopTypingIndicator(this.sock, chatId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Export types and config
|
// 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.
|
* Send read receipt for a message.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -725,6 +725,7 @@ export class LettaBot implements AgentSession {
|
|||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
clearInterval(typingInterval);
|
clearInterval(typingInterval);
|
||||||
|
adapter.stopTypingIndicator?.(msg.chatId)?.catch(() => {});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle no-reply marker
|
// Handle no-reply marker
|
||||||
|
|||||||
Reference in New Issue
Block a user