Merge pull request #75 from satelerd/fix/whatsapp-multi-user-sessions

fix(whatsapp): multi-user session isolation and bridge message handling
This commit is contained in:
Teknium 2026-02-27 03:25:54 -08:00 committed by GitHub
commit 80ad6572a3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 26 additions and 6 deletions

View file

@ -623,7 +623,12 @@ class GatewayRunner:
return await self._handle_set_home_command(event) return await self._handle_set_home_command(event)
# Check for pending exec approval responses # Check for pending exec approval responses
session_key_preview = f"agent:main:{source.platform.value}:{source.chat_type}:{source.chat_id}" if source.chat_type != "dm" else f"agent:main:{source.platform.value}:dm" if source.chat_type != "dm":
session_key_preview = f"agent:main:{source.platform.value}:{source.chat_type}:{source.chat_id}"
elif source.platform and source.platform.value == "whatsapp" and source.chat_id:
session_key_preview = f"agent:main:{source.platform.value}:dm:{source.chat_id}"
else:
session_key_preview = f"agent:main:{source.platform.value}:dm"
if session_key_preview in self._pending_approvals: if session_key_preview in self._pending_approvals:
user_text = event.text.strip().lower() user_text = event.text.strip().lower()
if user_text in ("yes", "y", "approve", "ok", "go", "do it"): if user_text in ("yes", "y", "approve", "ok", "go", "do it"):

View file

@ -155,6 +155,12 @@ def build_session_context_prompt(context: SessionContext) -> str:
else: else:
lines.append(f"**Source:** {platform_name} ({context.source.description})") lines.append(f"**Source:** {platform_name} ({context.source.description})")
# User identity (especially useful for WhatsApp where multiple people DM)
if context.source.user_name:
lines.append(f"**User:** {context.source.user_name}")
elif context.source.user_id:
lines.append(f"**User ID:** {context.source.user_id}")
# Connected platforms # Connected platforms
platforms_list = ["local (files on this machine)"] platforms_list = ["local (files on this machine)"]
for p in context.connected_platforms: for p in context.connected_platforms:
@ -327,6 +333,10 @@ class SessionStore:
platform = source.platform.value platform = source.platform.value
if source.chat_type == "dm": if source.chat_type == "dm":
# WhatsApp DMs come from different people, each needs its own session.
# Other platforms (Telegram, Discord) have a single DM with the bot owner.
if platform == "whatsapp" and source.chat_id:
return f"agent:main:{platform}:dm:{source.chat_id}"
return f"agent:main:{platform}:dm" return f"agent:main:{platform}:dm"
else: else:
return f"agent:main:{platform}:{source.chat_type}:{source.chat_id}" return f"agent:main:{platform}:{source.chat_type}:{source.chat_id}"

View file

@ -111,10 +111,15 @@ async function startSocket() {
const senderNumber = senderId.replace(/@.*/, ''); const senderNumber = senderId.replace(/@.*/, '');
// Skip own messages UNLESS it's a self-chat ("Message Yourself") // Skip own messages UNLESS it's a self-chat ("Message Yourself")
// Self-chat JID ends with the user's own number if (msg.key.fromMe) {
if (msg.key.fromMe && !chatId.includes('status') && isGroup) continue; // Always skip in groups and status
// In non-group chats, fromMe means we sent it — skip unless allowed user sent to themselves if (isGroup || chatId.includes('status')) continue;
if (msg.key.fromMe && !isGroup && ALLOWED_USERS.length > 0 && !ALLOWED_USERS.includes(senderNumber)) continue; // In DMs: only allow self-chat (remoteJid matches our own number)
const myNumber = (sock.user?.id || '').replace(/:.*@/, '@').replace(/@.*/, '');
const chatNumber = chatId.replace(/@.*/, '');
const isSelfChat = myNumber && chatNumber === myNumber;
if (!isSelfChat) continue;
}
// Check allowlist for messages from others // Check allowlist for messages from others
if (!msg.key.fromMe && ALLOWED_USERS.length > 0 && !ALLOWED_USERS.includes(senderNumber)) { if (!msg.key.fromMe && ALLOWED_USERS.length > 0 && !ALLOWED_USERS.includes(senderNumber)) {