fix(call): correct sanitization logic to preserve valid mobile numbers
Addresses GitHub Copilot critical review feedback from PR #149. ## Problem Fixed: Previous implementation incorrectly removed the last digit from ALL 13-digit numbers starting with '55', which corrupted valid Brazilian mobile numbers. ### Previous Logic (BROKEN): ```typescript if (pn.length === 13 && pn.startsWith('55')) { return pn.slice(0, -1) // ❌ Breaks valid mobiles! } ``` **Impact:** - ✅ Fixed landlines: 5517380255550 → 551738025555 (correct) - ❌ BROKE mobiles: 5515991000000 → 551599100000 (wrong!) ## Solution Implemented: Smart detection using first digit after DDD to distinguish landlines from mobiles. ### Brazilian Phone Format: - **Mobile**: 55 + DD + 9XXXXXXXX (13 digits) - First digit after DDD: 6-9 (mobile indicator) - Example: 5515991000000 (55 + 15 + 991000000) - **Landline**: 55 + DD + XXXXXXXX (12 digits) - First digit after DDD: 2-5 (landline indicator) - Example: 551541410000 (55 + 15 + 41410000) ### New Logic (CORRECT): ```typescript const firstDigitAfterDDD = pn.charAt(4) // Position after 55DD if (pn.length === 13) { if (['2', '3', '4', '5'].includes(firstDigitAfterDDD)) { // Landline with 13 digits = ERROR (should be 12) if (pn.endsWith('0')) { return pn.slice(0, -1) // Remove buggy trailing zero } } if (['6', '7', '8', '9'].includes(firstDigitAfterDDD)) { // Mobile with 13 digits = CORRECT return pn // Don't touch it! } } ``` ## Test Cases: | Input | Type | First Digit | Action | Output | Status | |-------|------|-------------|--------|--------|--------| | `5515991000000` | Mobile | 9 | Preserve | `5515991000000` | ✅ Fixed | | `5511687654321` | Mobile | 6 | Preserve | `5511687654321` | ✅ Fixed | | `551541410000` | Landline | 4 | Preserve | `551541410000` | ✅ OK | | `5517380255550` | Landline+bug | 3 | Sanitize | `551738025555` | ✅ OK | | `5515241410000` | Landline+bug | 2 | Sanitize | `551524141000` | ✅ Fixed | ## Technical Details: **Position Analysis:** ``` 5515991000000 0123456789... └┬┘└┬┘└─────┘ │ │ └─ 9 digits (with '9' prefix) │ └─ DDD (2 digits) └─ Country code (2 digits) Position 4: First digit after DDD - 2-5: Landline (should be 12 digits total) - 6-9: Mobile (should be 13 digits total) ``` **Additional Safety:** - Only sanitizes if trailing zero present (bug pattern) - Logs sanitization with type indicator (landline/mobile) - Preserves non-Brazilian numbers unchanged ## Benefits: - ✅ Fixes decoder bug for Brazilian landlines - ✅ Preserves valid mobile numbers (critical fix) - ✅ More precise detection using first digit rule - ✅ Better logging for debugging (includes type) - ✅ Follows official Brazilian numbering plan ## References: - GitHub Copilot PR #149 review - Brazilian numbering plan: Digits 2-5 = landline, 6-9 = mobile - WhatsApp JID format: 55DDD9XXXXXXXX@s.whatsapp.net https://claude.ai/code/session_01TvSrN9JmHZDdKMZDFWEcUS
This commit is contained in:
+49
-14
@@ -1603,12 +1603,21 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => {
|
||||
/**
|
||||
* Sanitizes caller phone number to fix known decoder bugs
|
||||
*
|
||||
* Issue: Brazilian landline numbers (12 digits) incorrectly get a trailing zero
|
||||
* Example: 551738025555 → 5517380255550 (off-by-one error)
|
||||
* Brazilian Phone Format:
|
||||
* - Mobile: 55 + DD + 9XXXXXXXX (13 digits total)
|
||||
* Example: 5515991000000 (55 + 15 + 991000000)
|
||||
* - Landline: 55 + DD + XXXXXXXX (12 digits total)
|
||||
* Example: 551541410000 (55 + 15 + 41410000)
|
||||
*
|
||||
* This helper removes the trailing zero if:
|
||||
* - Number is 13 digits (incorrect length)
|
||||
* - Starts with '55' (Brazil country code)
|
||||
* Decoder Bug: Landlines incorrectly get trailing zero
|
||||
* Example: 551738025555 → 5517380255550 (should be 12, not 13)
|
||||
*
|
||||
* Detection Logic:
|
||||
* - Extract first digit after DDD (position 4 in string)
|
||||
* - If digit is 2-5: It's a LANDLINE
|
||||
* → 13 digits is ERROR → Remove trailing zero
|
||||
* - If digit is 6-9: It's a MOBILE
|
||||
* → 13 digits is CORRECT → Don't touch!
|
||||
*
|
||||
* @param pn - Raw phone number from caller_pn attribute
|
||||
* @returns Sanitized phone number
|
||||
@@ -1618,15 +1627,41 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => {
|
||||
return undefined
|
||||
}
|
||||
|
||||
// Fix Brazilian landline off-by-one bug
|
||||
// Remove trailing zero if 13 digits and starts with Brazil code
|
||||
if (pn.length === 13 && pn.startsWith('55')) {
|
||||
const sanitized = pn.slice(0, -1)
|
||||
logger.debug(
|
||||
{ original: pn, sanitized },
|
||||
'Call: Sanitized Brazilian landline number (removed trailing zero)'
|
||||
)
|
||||
return sanitized
|
||||
// Only process Brazilian numbers (country code 55)
|
||||
if (!pn.startsWith('55')) {
|
||||
return pn
|
||||
}
|
||||
|
||||
// Check if it's a 13-digit number (potential landline bug)
|
||||
if (pn.length === 13) {
|
||||
// Extract first digit after DDD (position 4)
|
||||
// Format: 55 DD X...
|
||||
// 01 23 4...
|
||||
const firstDigitAfterDDD = pn.charAt(4)
|
||||
|
||||
// Landline: first digit is 2-5
|
||||
// If 13 digits, it's an error (should be 12) - remove trailing zero
|
||||
if (['2', '3', '4', '5'].includes(firstDigitAfterDDD)) {
|
||||
// Extra validation: only sanitize if ends with 0 (the bug pattern)
|
||||
if (pn.endsWith('0')) {
|
||||
const sanitized = pn.slice(0, -1)
|
||||
logger.debug(
|
||||
{ original: pn, sanitized, firstDigit: firstDigitAfterDDD, type: 'landline' },
|
||||
'Call: Sanitized Brazilian landline number (removed trailing zero)'
|
||||
)
|
||||
return sanitized
|
||||
}
|
||||
}
|
||||
|
||||
// Mobile: first digit is 6-9
|
||||
// 13 digits is CORRECT for mobile - don't sanitize!
|
||||
if (['6', '7', '8', '9'].includes(firstDigitAfterDDD)) {
|
||||
logger.trace(
|
||||
{ pn, firstDigit: firstDigitAfterDDD, type: 'mobile' },
|
||||
'Call: Valid Brazilian mobile number (13 digits correct, not sanitizing)'
|
||||
)
|
||||
return pn
|
||||
}
|
||||
}
|
||||
|
||||
return pn
|
||||
|
||||
Reference in New Issue
Block a user