DEV Community

Ujjwal Dubey
Ujjwal Dubey

Posted on

Indian Mobile Numbers in a CRM: Normalising +91, Leading Zeros and Spaces Before You Dedupe

If you build automations for Indian small businesses, the first bug you hit is rarely the AI. It is the phone number. The same customer shows up as +91 98xxx xxxxx on WhatsApp, 098xxxxxxxx in the billing software, 98xxx-xxxxx in a Google Sheet and 9198xxxxxxxx in a provider's webhook. Your CRM then has four contacts and no history.

This post is a small normalisation step to run before any dedupe or CRM write. It is the kind of detail I ask for when a business wants to brief an AI automation agency India teams can brief in one sitting: where do numbers come from, and in what shapes?

The target format

Store one canonical form, E.164 without spaces: +919812345678. Keep the original string too, for debugging.

A small normaliser for Indian mobiles

import re

def normalise_in_mobile(raw: str):
    """Return +91XXXXXXXXXX for Indian mobile numbers, else None."""
    if not raw:
        return None
    digits = re.sub(r"\D", "", raw)          # drop spaces, dashes, brackets, plus
    if digits.startswith("0091"):
        digits = digits[4:]
    elif digits.startswith("91") and len(digits) == 12:
        digits = digits[2:]
    elif digits.startswith("0") and len(digits) == 11:
        digits = digits[1:]
    if len(digits) == 10 and digits[0] in "6789":
        return "+91" + digits
    return None                               # landline, foreign, or malformed
Enter fullscreen mode Exit fullscreen mode

Indian mobile numbers are ten digits and currently start with 6, 7, 8 or 9. Anything that does not fit goes to a person or a separate queue, not into the CRM as a guess. If the business has many international customers, use a full library such as phonenumbers instead of a hand-rolled function.

Tests from real shapes

CASES = {
    "+91 98123 45678": "+919812345678",
    "098123-45678": "+919812345678",
    "919812345678": "+919812345678",
    "0091 9812345678": "+919812345678",
    "9812345678": "+919812345678",
    "022 2345 6789": None,        # Mumbai landline
    "+44 7700 900123": None,      # not Indian
}
for raw, want in CASES.items():
    assert normalise_in_mobile(raw) == want, (raw, normalise_in_mobile(raw))
Enter fullscreen mode Exit fullscreen mode

Collect your test cases from the business's real data, with the digits changed. Every system has its own habits.

Where to call it

  • In the WhatsApp webhook handler, before looking up the contact.
  • In any import from sheets or billing exports.
  • In the form handler on the website.

Then dedupe on the canonical number, and keep a list of alternate numbers per contact, because many customers use two phones.

Why this matters for AI later

An assistant that drafts replies with "last time you ordered..." is only as good as the history behind it. If that history is split across four contacts, the AI will confidently tell a regular customer that you have never met.

Disclosure: I run NxFlowAI, an AI automation agency in Mumbai. We integrate with all major CRMs (for example HubSpot, Zoho, Salesforce, Pipedrive and Freshsales, plus custom CRMs or Google Sheets setups) and work with all major WhatsApp Business providers and the official WhatsApp Business API (for example Meta Cloud API, Twilio, Gupshup, Interakt and WATI). Our first audit takes 72 hours for one workflow.

Top comments (0)