fix: use sender phone number as userId for WhatsApp group messages (#491)

This commit is contained in:
Cameron
2026-03-05 10:37:06 -08:00
committed by GitHub
parent 9bf19ebab4
commit 7173d2e2c4
3 changed files with 38 additions and 15 deletions

View File

@@ -691,7 +691,7 @@ export class WhatsAppAdapter implements ChannelAdapter {
}
const { body, from, chatId, pushName, senderE164, chatType, isSelfChat: isExtractedSelfChat } = extracted;
const userId = normalizePhoneForStorage(from);
const userId = normalizePhoneForStorage(senderE164 || from);
const isGroup = chatType === "group";
// CRITICAL: Skip messages older than connection time (prevents duplicate responses on reconnect)

View File

@@ -80,12 +80,32 @@ describe('formatMessageEnvelope', () => {
});
describe('sender formatting', () => {
it('uses userName when available', () => {
it('uses userName when available (non-phone channels)', () => {
const msg = createMessage({ userName: 'John Doe' });
const result = formatMessageEnvelope(msg);
expect(result).toContain('**Sender**: John Doe');
});
it('includes phone number alongside name for WhatsApp', () => {
const msg = createMessage({
channel: 'whatsapp',
userName: 'John',
userId: '+15551234567',
});
const result = formatMessageEnvelope(msg);
expect(result).toContain('**Sender**: John (+1 (555) 123-4567)');
});
it('includes phone number alongside name for Signal', () => {
const msg = createMessage({
channel: 'signal',
userName: 'Jane',
userId: '+15559876543',
});
const result = formatMessageEnvelope(msg);
expect(result).toContain('**Sender**: Jane (+1 (555) 987-6543)');
});
it('formats Slack users with @ prefix', () => {
const msg = createMessage({
channel: 'slack',

View File

@@ -87,34 +87,37 @@ function formatPhoneNumber(phone: string): string {
* Format the sender identifier nicely based on channel
*/
function formatSender(msg: InboundMessage): string {
// Use display name if available
if (msg.userName?.trim()) {
return msg.userName.trim();
}
const name = msg.userName?.trim();
// Format based on channel
switch (msg.channel) {
case 'slack':
// Add @ prefix for Slack usernames/IDs
return msg.userHandle ? `@${msg.userHandle}` : `@${msg.userId}`;
return name || (msg.userHandle ? `@${msg.userHandle}` : `@${msg.userId}`);
case 'discord':
// Add @ prefix for Discord usernames/IDs
return msg.userHandle ? `@${msg.userHandle}` : `@${msg.userId}`;
return name || (msg.userHandle ? `@${msg.userHandle}` : `@${msg.userId}`);
case 'whatsapp':
case 'signal':
// Format phone numbers nicely
if (/^\+?\d{10,}$/.test(msg.userId.replace(/\D/g, ''))) {
case 'signal': {
// For phone-based channels, always include the phone number so the agent
// can uniquely identify senders (pushName is user-chosen and not unique).
const isPhone = /^\+?\d{10,}$/.test(msg.userId.replace(/\D/g, ''));
if (name && isPhone) {
return `${name} (${formatPhoneNumber(msg.userId)})`;
}
if (isPhone) {
return formatPhoneNumber(msg.userId);
}
return msg.userId;
return name || msg.userId;
}
case 'telegram':
return msg.userHandle ? `@${msg.userHandle}` : msg.userId;
return name || (msg.userHandle ? `@${msg.userHandle}` : msg.userId);
default:
return msg.userId;
return name || msg.userId;
}
}