📲 Generating Valid WhatsApp Numbers with Ruby: A Practical Approach to International Number Parsing

May 30, 2025

Abstract

In a globalized digital world, correctly formatting phone numbers for messaging platforms like WhatsApp is both a usability and technical necessity. This article demonstrates how to build a robust Ruby script that parses international phone numbers, validates them, and generates direct WhatsApp links — combining the power of Phonelib and countries gems.

We will walk through the problem, design, implementation, and challenges encountered, offering a practical solution for developers needing international number normalization.

Get in Touch

Have questions or want to discuss Ruby development?

Connect and Support Development

📌 Introduction

Have you ever needed to:

  • Take a local phone number like 42230345
  • Identify the corresponding country (Brasil) and area code (011)
  • Validate it
  • Convert it into a WhatsApp-compatible format like https://wa.me/551142230345?

If so, you know how complex international number parsing can be — especially with differences in mobile/landline formats, leading zeros, and country-specific rules.


🧠 Problem Overview

The challenge is to:

  1. Accept user input (number, country, and area code)
  2. Normalize and validate the phone number
  3. Produce a valid WhatsApp number (E.164 format)
  4. Return a WhatsApp-compatible link

International phone numbers are tricky because:

  • Local area codes vary per country
  • Numbers may include leading zeros or symbols
  • Mobile and landline numbers are treated differently
  • Some countries require a mobile prefix (like 9 in Argentina)

🧰 Tools & Dependencies

To address this, we use:

  • phonelib: Ruby gem for phone number parsing and validation based on Google’s libphonenumber
  • countries: ISO 3166 standard gem for accessing country data, including country calling codes

Installation:

gem install phonelib countries

🧱 Implementation

Article content
require "phonelib"
require "countries"

def whatsapp_info(number, country: nil, local_code: nil)
  local_number = number.gsub(/\D/, '').sub(/^0+/, '')
  code_country = get_country_code(country) unless country.nil?

  final_number = if number.start_with?('+')
    number.gsub(/\D/, '')
  else
    [code_country, local_code, local_number].compact.join
  end

  phone = Phonelib.parse(final_number)

  if phone.valid?
    whatsapp_number = phone.e164.gsub('+', '')
    link = "https://wa.me/#{whatsapp_number}"
    { valid: true, whatsapp_number: "+#{whatsapp_number}", link: link }
  else
    { valid: false, error: "Invalid number: #{number}" }
  end
end

def get_country_code(country_name)
  country = ISO3166::Country.all.find do |c|
    c.translations.values.map(&:downcase).include?(country_name.downcase) ||
    c.name.downcase == country_name.downcase
  end
  country ? country.country_code : nil
end

🔍 Explanation

  • Input Handling: We strip any non-digits (gsub(/\D/, ”)) and remove leading zeros, which are not used in E.164 format.
  • Country Code Lookup: get_country_code matches country names using both translations and the native country name. This ensures multilingual support.
  • Local Code Integration: If a local (area) code is provided, it’s inserted between the country code and the number.
  • Validation: Using Phonelib.parse, we check whether the constructed number is valid. This includes format checks and mobile/landline distinction.
  • Output: If valid, we format the number for WhatsApp’s direct message link API (https://wa.me/), making it instantly usable.

🧪 Examples

puts whatsapp_info("154192620", country: "Argentina", local_code: "343")
# => { valid: true, whatsapp_number: "+549343154192620", link: "https://wa.me/549343154192620" }

puts whatsapp_info("42230345", country: "Brasil", local_code: "11")
# => { valid: true, whatsapp_number: "+551142230345", link: "https://wa.me/551142230345" }

puts whatsapp_info("+5493434192620")
# => { valid: true, whatsapp_number: "+5493434192620", link: "https://wa.me/5493434192620" }

🧠 Lessons Learned

Article content
  • Phonelib is powerful, but still requires carefully formatted inputs — especially for local numbers and countries with complex numbering schemes (e.g. Argentina or Portugal).
  • Handling localization via translations in the countries gem significantly improves user-friendliness.
  • Leading zeroes, non-digit characters, and wrong area codes are common edge cases.

📈 Use Cases

  • CRM tools or contact importers needing valid WhatsApp links
  • E-commerce systems integrating chat support
  • Mass communication dashboards validating phone inputs
  • Mobile apps targeting global users with country-specific formats

🔚 Conclusion

Phone number formatting is deceptively simple — but a real-world challenge when dealing with international users. By combining Ruby with the Phonelib and countries gems, we can build a robust system for WhatsApp link generation that’s accurate, resilient, and ready for production.


💬 Want the code?

The full script is available upon request or as a GitHub gist. Feel free to connect and share how you’d improve or apply this to your stack.


📣 About the Author

I’m a Ruby developer passionate about solving real-world problems with clean, practical code. I enjoy working with global systems, APIs, and simplifying complex processes through automation and scripting.

Let’s connect on LinkedIn and talk Ruby, automation, and engineering solutions that scale.

Article content

Leave a comment