Skip to content

About

A free, self-hostable, passwordless authentication system that delivers 6-digit OTPs directly via WhatsApp without third-party SMS fees.

Topics

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

ย 

History

5 Commits

Folders and files

NameName
Last commit message
Last commit date
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

WhatsApp OTP logo

WhatsApp OTP โ€” Passwordless Authentication

Send one-time passcodes instantly via WhatsApp. No SMS fees, no Twilio, no paid gateway.

License: MIT Node.js Self-hostable

Caution

DISCLAIMER: NOT PRODUCTION-READY This project uses an unofficial, reverse-engineered WhatsApp Web socket client (@whiskeysockets/baileys).

  • High Risk of Phone Number Ban: WhatsApp strictly prohibits the use of unofficial clients and automated bots. Linking your number carries a severe risk of permanent suspension/ban by WhatsApp.
  • Educational & Testing Use Only: This software is provided "as is" without warranty. It is designed for educational purposes, personal study, prototyping, and local testing. It is not recommended or suitable for production environments. Use at your own risk.

What is this?

WhatsApp OTP is a free, open-source, self-hostable authentication system that delivers 6-digit OTP codes directly to a user's WhatsApp โ€” powered by a spare phone number you already own.

By merging the web UI frontend, database storage endpoints, and WhatsApp socket listener into a single, self-contained Node.js Express application, you can run the entire service under a single process and port. No Vercel configurations or complex setups required.


Features

Feature Detail
๐Ÿ’ฌ WhatsApp Delivery Sends OTPs via your own WhatsApp number using Baileys
๐Ÿ–ฅ๏ธ Live Bot Profile Shows the dispatcher's profile picture & name in the UI
๐ŸŒ Country Selector Dropdown with flag emojis + per-country number validation
๐Ÿ” Redis or Local Cache Upstash Redis in production; auto-falls back to local file for dev
๐Ÿ“ฑ Mobile-First Fully responsive โ€” works great on phone and desktop
๐ŸŽจ Premium Dark UI Monochrome black-and-white theme, smooth micro-animations
๐Ÿ” Anti-Spam Rotation Randomised OTP message templates to avoid WhatsApp detection
โฑ๏ธ 5-Minute TTL OTP expires automatically; resend cooldown of 30 seconds
๐Ÿš€ One-Command Run npm run dev starts the entire app (UI + APIs + WhatsApp socket)

Table of Contents

  1. Prerequisites
  2. Project Structure
  3. Configuration
  4. Running Locally
  5. Deploying to Production
  6. Integrating into Your Own Website
  7. API Reference
  8. Environment Variables Reference
  9. Supported Countries
  10. Security Notes
  11. Contributing
  12. FAQ
  13. License

Prerequisites

Before you begin, make sure you have:

  • Node.js 18+ โ†’ Download here
  • npm (comes with Node.js)
  • A spare WhatsApp-registered phone number โ€” this will be the OTP sender. Do not use your primary number.
  • (For production) A free Upstash account (for Redis storage).

Project Structure

whatsapp-otp/
โ”œโ”€โ”€ server.js              # Express app hosting all APIs and WhatsApp socket
โ”œโ”€โ”€ index.html             # Main authentication UI (served by server.js)
โ”œโ”€โ”€ style.css              # Custom styling (monochrome dark theme)
โ”œโ”€โ”€ script.js              # Client validation, polling, and verification
โ”œโ”€โ”€ package.json           # Scripts and dependencies
โ”œโ”€โ”€ .env.example           # Template for configuration settings
โ”œโ”€โ”€ .env                   # Local configuration (created by you, gitignored)
โ”œโ”€โ”€ CONTRIBUTING.md        # Contribution guidelines
โ”œโ”€โ”€ LICENSE                # MIT License
โ””โ”€โ”€ README.md              # Project documentation

Configuration

This project requires only a single .env configuration file at the root level.

Important: .env files are never committed to git (they are listed in .gitignore). You create them yourself by copying the provided .env.example template.


Step 1 โ€” Clone and install

git clone https://github.com/your-username/whatsapp-otp.git
cd whatsapp-otp

# Install dependencies
npm install

Step 2 โ€” Configure environment

Create the .env file by copying the example:

# On Linux / macOS
cp .env.example .env

# On Windows (PowerShell)
Copy-Item .env.example .env

Now open .env and set your values. Here is the template (same as .env.example):

# The port the unified Express server will listen on (defaults to 3000)
PORT=3000

# ==============================================================================
# UPSTASH REDIS CONFIGURATION (OPTIONAL for local development)
# ==============================================================================
# For LOCAL development:
#   Leave these commented out. The application will automatically fall back to
#   a local JSON cache file (.otp-cache.json) to store pending OTPs.
#
# For PRODUCTION deployments (Render, Railway, Fly.io):
#   Production servers are stateless. You must configure a cloud Redis cache
#   to persist OTP codes securely. Get these from https://console.upstash.com
#
# UPSTASH_REDIS_REST_URL="https://your-db-name.upstash.io"
# UPSTASH_REDIS_REST_TOKEN="your_upstash_token_here"

Running Locally

To start the unified server, run:

npm run dev

This boots the Express server on http://localhost:3000.

First-time setup โ€” Link your WhatsApp number:

  1. Open http://localhost:3000 in your browser.
  2. A QR code overlay will appear on the screen.
  3. On your phone: Open WhatsApp โ†’ Settings โ†’ Linked Devices โ†’ Link a Device.
  4. Scan the QR code displayed on your screen or printed in your terminal.
  5. Once scanned, the overlay disappears and your profile picture/name will load into the status bar.

๐Ÿ” The session is saved in auth_info_baileys/ at the root level. On subsequent starts, the server reconnects automatically without requiring you to scan again.


Deploying to Production

Because this project runs as a standard Node.js Express server on a single port, you can deploy it in one click to any persistent node host:

Option A: Railway (Recommended)

  1. Link your GitHub repository to Railway.
  2. Create a new service from the repository.
  3. Set your environment variables in the settings tab (UPSTASH_REDIS_REST_URL, UPSTASH_REDIS_REST_TOKEN).
  4. Important: Add a Persistent Volume mounted at /app/auth_info_baileys to keep your WhatsApp connection active between builds/restarts.

Option B: Render

  1. Create a new Web Service on Render and connect your Git repository.
  2. Choose the Node runtime and set the start command to npm start.
  3. Add your environment variables in the dashboard.
  4. Important: Add a Persistent Disk mounted at /opt/render/project/src/auth_info_baileys (or equivalent path) to persist the WhatsApp pairing state.

Integrating into Your Own Website

Want to add WhatsApp OTP verification to your existing site? You can call the API endpoints directly from any frontend or backend.

Your site's form โ†’ POST /api/send-otp โ†’ WhatsApp message sent to user
User enters OTP  โ†’ POST /api/verify-otp โ†’ โœ… Verified / โŒ Rejected

Step 1 โ€” Send an OTP

Make a POST request to /api/send-otp:

const response = await fetch('https://your-deployed-app.com/api/send-otp', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    name: 'John Doe',         // User's name (used in the WhatsApp message greeting)
    mobile: '+919876543210'   // Full international number with country code
  })
});

const data = await response.json();
// { success: true, message: "OTP dispatched via WhatsApp successfully." }

Request body:

Field Type Required Description
name string โœ… User's display name (shown in the OTP message)
mobile string โœ… Phone number in international format, e.g. +919876543210

Success response (200):

{
  "success": true,
  "message": "OTP dispatched via WhatsApp successfully.",
  "mobile": "+919876543210"
}

Step 2 โ€” Verify the OTP

Once the user enters the code they received, verify it:

const response = await fetch('https://your-deployed-app.com/api/verify-otp', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    mobile: '+919876543210',  // Same number used in send-otp
    otp: '482931'             // The 6-digit code the user entered
  })
});

const data = await response.json();

if (data.success) {
  // โœ… OTP is correct โ€” log the user in, redirect, etc.
} else {
  // โŒ Wrong OTP or expired โ€” show error
  console.error(data.message);
}

Request body:

Field Type Required Description
mobile string โœ… Same number used in the send step
otp string โœ… The 6-digit code entered by the user

Success response (200):

{
  "success": true,
  "message": "OTP verified successfully."
}

API Reference

Endpoint Method Description
POST /api/send-otp POST Generate and send an OTP via WhatsApp
POST /api/verify-otp POST Verify a submitted OTP code
GET /api/profile-pic GET Get a WhatsApp user's profile picture URL (uses query param ?mobile=NUMBER)
GET /api/bot-status GET Check WhatsApp bot connection status + QR

Environment Variables Reference

Variable Description Example / Format
PORT Local port for Express (defaults to 3000) 3000
UPSTASH_REDIS_REST_URL Upstash Redis REST database URL https://your-db-name.upstash.io
UPSTASH_REDIS_REST_TOKEN Upstash Redis REST token your_upstash_token_here

Supported Countries

The built-in UI supports validation for:

๐Ÿ‡ฎ๐Ÿ‡ณ India ยท ๐Ÿ‡บ๐Ÿ‡ธ United States ยท ๐Ÿ‡ฌ๐Ÿ‡ง United Kingdom ยท ๐Ÿ‡ฆ๐Ÿ‡ช UAE ยท ๐Ÿ‡ธ๐Ÿ‡ฆ Saudi Arabia ยท ๐Ÿ‡ถ๐Ÿ‡ฆ Qatar ยท ๐Ÿ‡จ๐Ÿ‡ฆ Canada ยท ๐Ÿ‡ฆ๐Ÿ‡บ Australia ยท ๐Ÿ‡ฉ๐Ÿ‡ช Germany

To add/edit countries, modify the COUNTRIES array in script.js.


Security Notes

  • OTP auto-deletes โ€” After successful verification, the OTP is deleted from the cache immediately (prevents replay attacks).
  • 5-minute TTL โ€” OTPs expire automatically even if never verified.
  • Session files โ€” auth_info_baileys/ contains your WhatsApp session tokens. These are in .gitignore and must never be committed.
  • .env files are gitignored โ€” Only .env.example is committed. Never commit .env.

FAQ

Q: Is this against WhatsApp's Terms of Service, and is it production-ready?
A: Yes, it violates WhatsApp's Terms of Service and carries a severe risk of your number being permanently banned. Because of this, this project is NOT production-ready. It is intended strictly for educational, hobby, and testing purposes. For production authentication setups, you should use official WhatsApp Business API platforms (such as Twilio).

Q: My profile picture isn't showing.
A: WhatsApp privacy settings may block picture access for non-contacts. The UI gracefully shows your name initial instead.

Q: Can the sender and receiver be the same number?
A: Yes โ€” useful for testing. The bot can send a code to itself.


License

MIT โ€” free to use, modify, and distribute.


Made with โค๏ธ โ€” Built on Baileys ยท Caches via Upstash

About

A free, self-hostable, passwordless authentication system that delivers 6-digit OTPs directly via WhatsApp without third-party SMS fees.

Topics

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages