How to Build a WhatsApp Chatbot for Your Business in 30 Minutes
Reading time: 8 minutes
Target audience: Indian SMB owners, developers, and non-technical founders who want a working WhatsApp chatbot fast
Introduction
WhatsApp has 500 million+ users in India. Your customers are already on it — the question is whether you're talking to them or your competitor is.
In this tutorial, you'll build a working WhatsApp chatbot from scratch using Meta's Cloud API, Python (Flask), and a simple rule-based reply engine. No paid tools. No third-party platforms. Just code.
By the end, you'll have a bot that:
- Replies to customer messages automatically
- Handles FAQs (pricing, hours, location)
- Escalates to a human agent when stuck
- Runs on your own server
Time required: 30 minutes (if you have a Meta Developer account ready)
Cost: ₹0 for development (Meta gives 1,000 free service conversations/month)
Prerequisites
Before starting, make sure you have:
- A Meta Developer account — sign up at developers.facebook.com
- A Facebook Business Manager account — create at business.facebook.com
- A phone number — dedicated to WhatsApp (not your personal number)
- Python 3.8+ installed
- A public HTTPS URL — we'll use ngrok for local development
Step 1: Create a Meta App and Get API Credentials (5 min)
- Go to developers.facebook.com → My Apps → Create App
- Select Business as the app type
- Add the WhatsApp product to your app
- You'll see a temporary access token and your Phone Number ID and WhatsApp Business Account ID
Save these three values — you'll need them:
PHONE_NUMBER_ID=your_phone_number_id
WHATSAPP_BUSINESS_ACCOUNT_ID=your_business_account_id
ACCESS_TOKEN=your_temporary_access_token
Note: The temporary token expires in 24 hours. For production, generate a System User Token that never expires.
Step 2: Set Up Your Python Project (3 min)
Create a new project folder and install dependencies:
mkdir whatsapp-chatbot && cd whatsapp-chatbot
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
pip install flask requests python-dotenv
Create a .env file:
PHONE_NUMBER_ID=your_phone_number_id
ACCESS_TOKEN=your_access_token
VERIFY_TOKEN=my_custom_verify_token_123
Create app.py:
import os
import requests
from flask import Flask, request, jsonify
from dotenv import load_dotenv
load_dotenv()
app = Flask(__name__)
PHONE_NUMBER_ID = os.getenv("PHONE_NUMBER_ID")
ACCESS_TOKEN = os.getenv("ACCESS_TOKEN")
VERIFY_TOKEN = os.getenv("VERIFY_TOKEN")
GRAPH_API_URL = f"https://graph.facebook.com/v21.0/{PHONE_NUMBER_ID}/messages"
def send_whatsapp_message(to, text):
"""Send a text message via WhatsApp Cloud API."""
headers = {
"Authorization": f"Bearer {ACCESS_TOKEN}",
"Content-Type": "application/json",
}
payload = {
"messaging_product": "whatsapp",
"to": to,
"type": "text",
"text": {"body": text},
}
response = requests.post(GRAPH_API_URL, headers=headers, json=payload)
return response.json()
def get_reply(message_text):
"""Simple rule-based reply engine."""
text = message_text.lower().strip()
# FAQ responses
if any(word in text for word in ["price", "cost", "fee", "charge", "rate"]):
return (
"Our pricing:\n"
"• Basic Plan: ₹5,000/month\n"
"• Standard Plan: ₹8,000/month\n"
"• Premium Plan: ₹12,000/month\n\n"
"Want a custom quote? Share your requirements!"
)
if any(word in text for word in ["hour", "time", "open", "close", "timing"]):
return "We're open Monday to Saturday, 9 AM to 7 PM IST."
if any(word in text for word in ["location", "address", "where", "office"]):
return "We're located in Ahmedabad, Gujarat. Here's the map: https://maps.google.com"
if any(word in text for word in ["human", "agent", "person", "call", "talk"]):
return "Connecting you to a human agent. Please hold for 2-3 minutes. You can also call us at +91-XXXX-XXXXXX."
if any(word in text for word in ["hi", "hello", "hey", "namaste"]):
return (
"Hello! Welcome to Our Business. How can I help you today?\n\n"
"Reply with:\n"
"1️⃣ Pricing\n"
"2️⃣ Timings\n"
"3️⃣ Location\n"
"4️⃣ Talk to human"
)
# Default fallback
return (
"I'm not sure I understand. Here's what I can help with:\n\n"
"• Pricing\n"
"• Business hours\n"
"• Location\n"
"• Talk to a human\n\n"
"Or type your question and I'll do my best!"
)
@app.route("/webhook", methods=["GET"])
def verify_webhook():
"""Verify webhook with Meta."""
mode = request.args.get("hub.mode")
token = request.args.get("hub.verify_token")
challenge = request.args.get("hub.challenge")
if mode == "subscribe" and token == VERIFY_TOKEN:
print("Webhook verified!")
return challenge, 200
return "Forbidden", 403
@app.route("/webhook", methods=["POST"])
def handle_message():
"""Handle incoming WhatsApp messages."""
data = request.get_json()
try:
entry = data["entry"][0]
changes = entry["changes"][0]
value = changes["value"]
if "messages" in value:
message = value["messages"][0]
from_number = message["from"]
message_type = message["type"]
if message_type == "text":
incoming_text = message["text"]["body"]
print(f"Message from {from_number}: {incoming_text}")
reply = get_reply(incoming_text)
send_whatsapp_message(from_number, reply)
print(f"Replied: {reply}")
except (KeyError, IndexError) as e:
print(f"Error processing message: {e}")
return jsonify({"status": "ok"}), 200
@app.route("/")
def home():
return "WhatsApp Chatbot is running!"
if __name__ == "__main__":
app.run(port=5000, debug=True)
Step 3: Expose Your Server with ngrok (2 min)
Meta needs a public HTTPS URL to send webhook events. For local development, use ngrok:
# Install ngrok from https://ngrok.com/download
ngrok http 5000
You'll see output like:
Forwarding https://abc123.ngrok-free.app -> http://localhost:5000
Copy the HTTPS URL — you'll use it in the next step.
Step 4: Configure the Webhook (3 min)
- Go to your Meta App → WhatsApp → Configuration
- Under Webhook, click Edit
- Enter:
-
Callback URL:
https://your-ngrok-url.ngrok-free.app/webhook -
Verify Token:
my_custom_verify_token_123(must match your.env)
-
Callback URL:
- Click Verify and Save
Meta will send a GET request to your webhook. If the verify token matches, you're connected.
- Subscribe to the messages event:
- In the webhook configuration, click Manage
- Subscribe to
messages
Step 5: Send a Test Message (2 min)
Add a phone number to your WhatsApp Business Account test numbers:
- Meta App → WhatsApp → API Setup
- Under Test Number, add your personal phone number
- Send a message to your WhatsApp Business number from that phone
Your bot should reply instantly!
Test it:
- Send "hello" → get the welcome menu
- Send "pricing" → get pricing info
- Send "human" → get escalation message
- Send "random text" → get fallback
Step 6: Add Message Templates for Outbound Messages (5 min)
Your bot can reply to customers, but to initiate conversations (order updates, appointment reminders), you need pre-approved message templates.
Create a template via the Graph API:
curl -X POST "https://graph.facebook.com/v21.0/YOUR_BUSINESS_ACCOUNT_ID/message_templates" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "order_confirmation",
"category": "UTILITY",
"language": "en_US",
"components": [
{
"type": "BODY",
"text": "Hi {{1}}, your order #{{2}} has been confirmed! Expected delivery: {{3}}. Track here: {{4}}"
}
]
}'
Template categories and India pricing:
| Category | Rate (India) | Use Case |
|---|---|---|
| Marketing | ₹0.86/message | Promotions, offers |
| Utility | ₹0.115/message | Order updates, reminders |
| Authentication | ₹0.115/message | OTPs, verification |
| Service | Free (24-hr window) | Customer-initiated replies |
Pro tip: Utility messages are 7.5× cheaper than marketing. Classify correctly.
Step 7: Add AI-Powered Responses (Optional, 5 min)
Replace the rule-based get_reply() function with an AI-powered version using OpenAI:
import openai
openai.api_key = os.getenv("OPENAI_API_KEY")
def get_reply(message_text):
"""AI-powered reply using OpenAI."""
response = openai.ChatCompletion.create(
model="gpt-4o-mini",
messages=[
{
"role": "system",
"content": (
"You are a helpful customer support assistant for an Indian business. "
"Keep replies under 100 words. Use simple language. "
"If you don't know something, say 'Let me connect you to a human agent.'"
),
},
{"role": "user", "content": message_text},
],
max_tokens=150,
)
return response.choices[0].message.content
Now your bot can handle any question, not just pre-programmed ones.
Step 8: Deploy to Production (5 min)
For production, you need a real server. Options:
| Platform | Cost | Difficulty |
|---|---|---|
| Railway.app | ₹0 (free tier) | Easy |
| Render.com | ₹0 (free tier) | Easy |
| AWS EC2 | ₹500/month | Medium |
| DigitalOcean | ₹400/month | Medium |
Deploy to Railway (easiest):
# Install Railway CLI
npm install -g @railway/cli
# Login and deploy
railway login
railway init
railway up
Update your webhook URL in Meta App configuration to your production URL.
Common Issues and Fixes
| Problem | Solution |
|---|---|
| Webhook verification fails | Check VERIFY_TOKEN matches exactly in both .env and Meta dashboard |
| Messages not received | Ensure you subscribed to messages event in webhook settings |
| Template rejected | Templates must be in the correct category. No promotional content in UTILITY. |
| Token expired | Generate a System User Token in Meta Business Settings |
| ngrok URL changed | ngrok free tier gives a new URL each session. Update webhook config. |
What You Built
In 30 minutes, you now have:
- ✅ A working WhatsApp chatbot that replies to customers
- ✅ FAQ handling for common questions
- ✅ Human escalation flow
- ✅ Message templates for outbound notifications
- ✅ Optional AI integration for open-ended questions
- ✅ A deployment path to production
Next steps:
- Add a database (SQLite/PostgreSQL) to store conversations
- Integrate with your CRM or Google Sheets
- Add WhatsApp Flows for forms and surveys
- Set up analytics to track response times and resolution rates
Full Source Code
The complete code for this tutorial is available on GitHub:
github.com/DawnofGenX/whatsapp-chatbot-tutorial
Found this helpful? Share it with a fellow developer. Have questions? Drop them in the comments below.
Top comments (0)