[core] ChatWoot - fix brazil numbers

fix #1261
This commit is contained in:
devlikepro committed 2025-09-29 09:09:39 +07:00
1 parent 5ce64fd30d
commit 166dae8e27
4 files changed
+107 -4

No files matched your search

+3 -2
View File
@@ -13,6 +13,7 @@ import { isJidCusFormat } from '@waha/utils/wa';
import * as lodash from 'lodash';
import { AttributeKey } from '../const';
import { E164Parser } from '@waha/core/utils/PhoneJidNormalizer';
export interface ContactResponse {
data: generic_id & contact;
@@ -64,8 +65,8 @@ export class ContactAPI {
if (isJidCusFormat(chatId)) {
// Search by phone
let phone_number = chatId.split('@')[0];
phone_number = phone_number.replace('+', '');
const phoneNumberE164 = E164Parser.fromJid(chatId);
const phone_number = phoneNumberE164.replace('+', '');
payload[payload.length - 1].query_operator = 'OR';
payload.push({
attribute_key: 'phone_number',
@@ -15,6 +15,7 @@ import {
isPnUser,
} from '@waha/core/utils/jids';
import { UnknownJIDFormat } from '@waha/apps/chatwoot/errors';
import { E164Parser } from '@waha/core/utils/PhoneJidNormalizer';
/**
* Base WhatsApp contact info class
@@ -68,8 +69,7 @@ class JidContactInfo extends ChatContactInfo {
const contact: any = await this.session.getContact(this.chatId);
const name =
contact?.name || contact?.pushName || contact?.pushname || this.chatId;
const phoneNumber = this.chatId.split('@')[0];
const phoneNumberE164 = '+' + phoneNumber;
const phoneNumberE164 = E164Parser.fromJid(this.chatId);
const result: Contact = {
name: name,
+36
View File
@@ -0,0 +1,36 @@
import { E164Parser } from './PhoneJidNormalizer';
describe('E164Parser.fromJid', () => {
it('parses basic JID to +number', () => {
expect(E164Parser.fromJid('14155552671@s.whatsapp.net')).toBe(
'+14155552671',
);
});
it('returns null for empty or missing local part', () => {
expect(E164Parser.fromJid('')).toBeNull();
expect(E164Parser.fromJid('@s.whatsapp.net')).toBeNull();
});
it('applies Brazil DDD + add-9 rule when local has 8 digits and not starting with 9', () => {
// +55 <DDD:2> <local:8> and local does not start with 9
expect(E164Parser.fromJid('553188888888@s.whatsapp.net')).toBe(
'+5531988888888',
);
});
it('does not add 9 when local already starts with 9 (Brazil)', () => {
expect(E164Parser.fromJid('553198888888@s.whatsapp.net')).toBe(
'+553198888888',
);
expect(E164Parser.fromJid('553199999999@s.whatsapp.net')).toBe(
'+553199999999',
);
});
it('leaves non-Brazil numbers unchanged', () => {
expect(E164Parser.fromJid('447911123456@s.whatsapp.net')).toBe(
'+447911123456',
);
});
});
+66
View File
@@ -0,0 +1,66 @@
type RewriteRule = {
name: string;
re: RegExp;
replace: string;
};
/**
* Convert JID to Phone Number if possible
* Applies some formatting rules
*/
export class PhoneJidNormalizer {
constructor(private rules: RewriteRule[] = []) {}
/**
* jid like "553188888888@s.whatsapp.net" → "+553188888888"
*/
private parseFromJid(jid: string): string | null {
if (!jid) {
return null;
}
const local = jid.split('@', 1)[0] ?? '';
if (!local) {
return null;
}
return `+${local}`;
}
/**
* Apply rewrite rules
*/
private rewrite(number: string): string {
for (const rule of this.rules) {
if (rule.re.test(number)) {
number = number.replace(rule.re, rule.replace);
return number;
}
}
return number;
}
/**
* Converts a JID (Jabber ID) into an E.164 formatted phone number string.
* Applies rules if any
*/
fromJid(jid: string): string | null {
let number = this.parseFromJid(jid);
if (!number) {
return null;
}
number = this.rewrite(number);
return number;
}
}
const RULES = [
// Brazil - add 9 before Direct Distance Dialing
// +55 <DDD:2> <local:8>, not already starting with 9
// +553188888888 => +5531988888888
{
name: 'br-add-9-after-ddd',
re: /^\+55(\d{2})(?!9)(\d{8})$/,
replace: '+55$19$2',
},
];
export const E164Parser = new PhoneJidNormalizer(RULES);