Skip to content

WhatsApp: Brazilian phone numbers not normalized (9th digit issue) #20187

Description

@thiarlesw

Problem

When sending messages via openclaw message send or scheduling with openclaw cron add --to, Brazilian phone numbers are sent as-is without normalization. This causes silent delivery failures for Brazilian users.

Background

Brazilian mobile numbers have two formats:

  • Carrier format (14 digits): +55 DD 9XXXX XXXX — used by contacts, phone books, and carriers
  • WhatsApp internal format (13 digits): +55 DD XXXX XXXX — used by WhatsApp protocol (Baileys JID)

In 2010, ANATEL added a 9th digit prefix to all Brazilian mobile numbers. However, WhatsApp internally registers numbers without this extra 9 for most area codes outside SP/RJ/ES (DDDs other than 11-28).

Current behavior

openclaw message send --channel whatsapp --target +5547984178525 --message "hello"
# Gateway reports: ✅ Sent via gateway. Message ID: 3EB0...
# WhatsApp actually sends to: 5547984178525@s.whatsapp.net (WRONG - 14 digits)
# Message is never delivered (number doesn't exist in this format)

The gateway returns success because it handed off to WhatsApp, but the number doesn't resolve on WhatsApp's side. No error is surfaced — it's a silent failure.

Expected behavior

The number should be normalized to WhatsApp format before sending:

  • +5547984178525 (14 digits) → +554784178525 (13 digits, 9th digit removed)

Affected commands

  • openclaw message send --target
  • openclaw cron add --to (delivery destination)
  • Any outbound WhatsApp message where the user provides a Brazilian number

Suggested solutions

Option A — Use Baileys onWhatsApp() validation:
Baileys already has sock.onWhatsApp(jid) which checks if a number exists and returns the correct JID. This would handle Brazil, Mexico, and any other country with format discrepancies.

Option B — Add BR/MX normalization to normalizeE164():
In src/whatsapp/normalize.ts, add country-specific rules:

function normalizeBrazilPhone(phone: string): string {
  // Brazilian WhatsApp: remove 9th digit for DDDs outside 11-28
  // +55DDXXXXXXXXX (14 digits) → +55DDXXXXXXXX (13 digits)
  if (phone.startsWith('+55') && phone.length === 14 && phone[5] === '9') {
    return phone.slice(0, 5) + phone.slice(6);
  }
  return phone;
}

Option C — Configuration-based normalization:
Add a whatsapp.phoneNormalization config option (e.g., "region": "BR") so users can opt-in to country-specific normalization.

Workaround

We created a wrapper script (send_msg.py) that normalizes the number before calling openclaw message send. This works for direct messages but doesn't help with cron --to delivery.

Environment

  • OpenClaw: 2026.2.17
  • WhatsApp: QR code connection (personal)
  • Country: Brazil (DDD 47 — Santa Catarina)

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    staleMarked as stale due to inactivity

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions