WhatsApp Automation with Python
- How to work with WhatsApp API using Python;
- Integration with Whapi.Cloud for automating various tasks;
- Using webhooks to handle and auto-respond to messages;
- Connecting your WhatsApp bot to ChatGPT for AI-powered conversations;

To make your work easier, you can use our ready-made Python bot scripts published on GitHub. These projects provide detailed setup and testing instructions, and the code contains useful comments. It’s an excellent starting point for beginner developers.
Getting Ready to Develop a Bot
- Python. Install Python if you haven’t already. Download the latest version (3.6 or above recommended) from the official site and follow the installation instructions.
- Flask. Flask is a lightweight Python web framework that we’ll use to set up a server and handle webhooks. Install Flask using the command: pip install Flask.
- API Token. Register on Whapi.Cloud to get an API token. This token allows your bot to interact with messenger through the API. After registration, you’ll receive a free channel with limited features, sufficient for testing your development. Whapi.Cloud stands out for its stability, low cost, and wide range of features. We’ll provide instructions on obtaining the token below.
- Configured Webhook. To enable your bot to process incoming updates and events from WhatsApp, you’ll need a server URL (local or external) to handle notifications from messenger. This article will explain in detail how to set it up and where to get such a link.
Obtaining an API Token
Registration and Connecting a Number
- 1. Go to the dashboard and open the Default Channel page that’s already created for you.
- 2. At the first step, you’ll see a QR code with instructions.
- 3. Open WhatsApp on your device, go to Settings → Linked Devices → Link a Device → Scan QR Code.
- 4. After successful connection, name the channel (e.g., "My Chatbot") for easier management in the future.




Getting an API Token

Tools for Working with the API
- User-Friendly Developer Hub: A specialized platform with documentation and examples provides code snippets for all endpoints in various programming languages.
- Postman Collection: Ready-made requests for testing the API through Postman.
- Swagger File: A detailed description of all API methods, with testing capabilities directly from the channel page.
What is a Webhook and How to Set It Up?
What is a Webhook?
- Instant notifications. All events are processed almost in real-time.
- High throughput. Notification speed is only limited by your server's performance.
- Flexibility. You can receive only the events you truly need, such as: Personal and Group messages; Message status changes; Group participant changes; Missed call notifications; Channel statuses, and much more.
How and Where to Get a Webhook URL?
- 1) Download Ngrok from the official website and extract it. Open the terminal and navigate to the folder where Ngrok is stored.
- 2) Run ./ngrok http PORT_NUMBER, replacing PORT_NUMBER with the port your Flask server is running on locally (e.g., 80).
- 3) You should now have a public URL that you can use as the webhook URL. Copy it for further use.


Setting Up a Hook on a Channel
- Go to the channel settings. On the channel page, click the settings button (top right corner).
- Configure the webhook. Enter your URL in the webhook section using preselected settings. You can set up multiple webhooks for different events if necessary. These settings can also be adjusted via the API.
- Save the changes. From now on, all notifications about WhatsApp events will be sent to the server you specified.
Creating the Basics of a WhatsApp Bot in Python
Flask==3.0.0
requests==2.27.1
requests-toolbelt==0.9.1
python-dotenv==0.20.0
pip install -r requirements.txt
API_TOKEN=8FjpwmyFUulh7emXOprrET3xKrwJ984O # API token from your channel
API_URL=https://gate.whapi.cloud # API endpoint URL
PORT=80 # example, 80 or 443
#URL_LINK= The Webhook link to your server {link to server}/hook.
from dotenv import load_dotenv
import os
load_dotenv()
api_token = os.getenv("API_TOKEN")
Sending a Text Message
import requests
# URL for sending text messages. Can be pulled from .env
url = "https://gate.whapi.cloud/messages/text"
# Data for sending a message
payload = {
"to": "919984351847", # Enter the recipient's number in international format
"body": "Hello! This is a test message." # Text of message
}
# Headers, including authorization token
headers = {
"accept": "application/json",
"content-type": "application/json",
"authorization": f"Bearer {api_token}" # Use the token from the .env file
}
# Sending a POST request
response = requests.post(url, json=payload, headers=headers)
# Output server response
print(response.status_code)
print(response.text)
Receiving Messages via Flask Webhook
from flask import Flask, request, jsonify
app = Flask(__name__)
# Route for processing incoming messages
@app.route('/hook', methods=['POST'])
def webhook():
# Retrieving data from a request
data = request.json
# Logging an incoming message
print("Received message:", data)
# Example of incoming message processing
if "messages" in data:
for message in data["messages"]:
sender = message["from"] # Sender's number
text = message.get("body", "") # Text of message
print(f"Message from {sender}: {text}")
# Logic for replying to a message
# Check out our examples on GitHub, where we use more branching on commands for the bot
if text.lower() == "hello":
send_response(sender, "Hi there! How can I help you?")
elif text.lower() == "bye":
send_response(sender, "Goodbye!")
return jsonify({"status": "success"}), 200
# Function for sending a reply
def send_response(to, body):
import requests
url = "https://gate.whapi.cloud/messages/text"
payload = {
"to": to,
"body": body
}
headers = {
"accept": "application/json",
"content-type": "application/json",
"authorization": f"Bearer {api_token}" # Use the token from the .env file
}
response = requests.post(url, json=payload, headers=headers)
print(f"Response to {to}: {response.status_code}, {response.text}")
if __name__ == '__main__':
app.run(host='0.0.0.0', port=80)
Advanced Features
Sending an Image
import requests
url = "https://gate.whapi.cloud/messages/image"
payload = {
"to": "919984351847",
"media": "https://upload.wikimedia.org/wikipedia/en/a/a9/Example.jpg",
"caption": "An example image"
}
headers = {
"accept": "application/json",
"content-type": "application/json",
"authorization": "Bearer Your_Token"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)
Sending a File
import requests
url = "https://gate.whapi.cloud/messages/document"
payload = {
"to": "919984351847",
"media": "data:application/pdf;base64,JVBERi0xLjQKJdPr6eEKMSAwIG9iago8PC9UaXRsZSAoVGVybXMgb2YgU2VydmljZSBXaGFwaS5DbG91ZCkKL0NyZWF0b3IgKE1vemlsbGEvNS4wIFwoV2luZG93cyBOVCAxMC4wOyBXaW42NDsgeDY0XCkgQXBwbGVXZWJLaXQvNTM3LjM2IFwoS0h............",
"filename": "Terms of Service Whapi.Cloud.pdf",
"caption": "Hello, I am attaching an important file to my message"
}
headers = {
"accept": "application/json",
"content-type": "application/json",
"authorization": "Bearer Your_Token"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)
Creating a WhatsApp Group in Python
import requests
url = "https://gate.whapi.cloud/groups"
payload = {
"participants": ["919984351847", "919984351848", "919984351849"],
"subject": "Group Subject 3"
}
headers = {
"accept": "application/json",
"content-type": "application/json",
"authorization": "Bearer Your_Token"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)
Integration with ChatGPT: AI for your WhatsApp bot
Step 1: Add ChatGPT Dependencies
openai>=1.91.0,<2.0.0
httpx>=0.28.1,<1.0.0
httpcore>=1.0.9,<2.0.0
- openai - the official SDK to send requests to OpenAI and get ChatGPT responses.
- httpx - a modern, asynchronous HTTP client library that openai depends on internally for making API calls.
- httpcore - a low-level network transport library used by httpx. It needs to be pinned explicitly to avoid version conflicts.
pip install -r requirements.txt
Step 2: Get Your OpenAI API Key
OPENAI_API_KEY=your_api_key_here
Step 3: Add the AI Logic to Your Bot
- - receives incoming webhook events from Whapi.Cloud,
- - detects whether the message starts with /ai,
- - sends the user's request to ChatGPT via the OpenAI API,
- - returns the AI-generated response to the user in WhatsApp.
# Import necessary libraries for web server, HTTP requests, OpenAI API, environment variables, and .env file loading
from flask import Flask, request, jsonify # Flask is used to create the web server and handle HTTP requests
import requests # Used to send HTTP requests to the WhatsApp API
from openai import OpenAI # OpenAI client for interacting with ChatGPT
import os # For accessing environment variables
from dotenv import load_dotenv # For loading variables from a .env file
# Load environment variables from a .env file into the environment
load_dotenv()
# Create a Flask web application instance
app = Flask(__name__)
# Retrieve required configuration values from environment variables
API_TOKEN = os.getenv("API_TOKEN") # Token for authenticating with WhatsApp API
API_URL = os.getenv("API_URL") # Base URL for WhatsApp API
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY") # API key for OpenAI
# Ensure all required environment variables are set, otherwise stop the program with an error
if not API_TOKEN or not API_URL or not OPENAI_API_KEY:
raise RuntimeError("Missing required environment variables: API_TOKEN, API_URL, or OPENAI_API_KEY")
# Initialize the OpenAI client with the provided API key
openai_client = OpenAI(api_key=OPENAI_API_KEY)
# Function to send a prompt to ChatGPT and get a response
# Takes a string prompt and returns the model's reply as a string
def ask_openai(prompt):
response = openai_client.chat.completions.create(
model="gpt-3.5-turbo", # Specify which OpenAI model to use
messages=[{"role": "user", "content": prompt}] # Provide the user's message to the model
)
# Extract and return the text of the model's reply
return response.choices[0].message.content.strip()
# Function to send a text message to a WhatsApp user via the WhatsApp API
# 'to' is the recipient's chat ID, 'body' is the message text
def send_message(to, body):
headers = {
"Authorization": f"Bearer {API_TOKEN}", # Add authentication token to the request
"Content-Type": "application/json" # Specify that we're sending JSON data
}
payload = {"to": to, "body": body} # Prepare the message data
# Send the message to the WhatsApp API endpoint
response = requests.post(f"{API_URL}/messages/text", json=payload, headers=headers)
print("Whapi response:", response.status_code, response.text) # Log the API response for debugging
# Define a webhook endpoint to receive incoming WhatsApp messages
@app.route("/hook/messages", methods=["POST"])
def webhook():
data = request.json # Parse the incoming JSON data
print("Incoming:", data) # Log the incoming data for debugging
# Loop through all received messages (could be more than one in a single webhook call)
for msg in data.get("messages", []):
if msg.get("from_me"):
continue # Skip messages sent by the bot itself
sender = msg.get("chat_id") # Get the sender's chat ID
# Safely extract the message text, handling cases where 'text' might be missing
text = (msg.get("text") or {}).get("body", "").strip()
# If the message starts with '/ai ', treat it as a prompt for ChatGPT
if text.lower().startswith("/ai "):
prompt = text[4:].strip() # Extract the user's prompt after '/ai '
if not prompt:
send_message(sender, "Please provide a prompt after /ai.") # Ask user to provide a prompt
else:
try:
reply = ask_openai(prompt) # Get response from ChatGPT
send_message(sender, reply) # Send the response back to the user
except Exception as e:
send_message(sender, f"Error: {e}") # Inform user if something went wrong
else:
# If the message doesn't start with '/ai ', send instructions to the user
send_message(sender, "Hi! To ask me something, type:\n/ai your question")
# Respond to WhatsApp API to confirm receipt of the webhook
return jsonify({"status": "received"})
# Optional: health check endpoint to verify the bot is running
@app.route("/", methods=["GET"])
def index():
return "Bot is running"
# Function to register the webhook URL with the WhatsApp API
def register_webhook():
if os.getenv("BOT_URL"):
headers = {"Authorization": f"Bearer {API_TOKEN}"}
payload = {
"webhooks": [
{
"url": os.getenv("BOT_URL"), # The public URL where Whapi should send messages
"events": [{"type": "messages", "method": "post"}], # Listen for message events
"mode": "method"
}
]
}
# Register the webhook
response = requests.patch(f"{API_URL}/settings", json=payload, headers=headers)
print("Webhook setup:", response.status_code, response.text) # Log the result
# If this script is run directly (not imported), start the bot
if __name__ == "__main__":
register_webhook() # Optionally register the webhook on startup
port = int(os.getenv("PORT", 80)) # Use the PORT environment variable or default to 80
app.run(host="0.0.0.0", port=port) # Start the Flask web server, accessible from any network interface
Troubleshooting
The Bot Does Not Respond to Incoming Messages
- Ensure you are sending messages to the number on which the bot is running from a different phone. The bot will not be able to respond to messages sent from the same number.
- If the bot does not respond to messages from other numbers, check the operation of webhooks. Use services to simulate webhooks, for example, Webhook.site, to ensure which path the callback requests are coming through. Afterwards, check if the path matches the one you have configured. Also, ensure your server responds with 200Ok.
The Bot Sends Messages Non-Stop
The Bot Works in Some Chats, But Not in Others
Deployment and Using Servers
Firebase
- Create a project in Firebase Console;
- Install Firebase CLI, following the instructions;
- Initialize Firebase in your project directory with the command firebase init;
- Deploy your bot using the command firebase deploy --only functions.
AWS (Amazon Web Services)
- Register or log in to AWS Management Console;
- Create a new Lambda function through the AWS console, selecting API Gateway as the trigger;
- Upload your bot's code into the Lambda function;
- Configure the API Gateway to interact with your bot and the outside world.
Heroku
- Create an account on Heroku;
- Install Heroku CLI and log in;
- Create a new Heroku app through the console or using the command heroku create;
- Link your Git repository to Heroku and perform deployment with the commands git push heroku master;
- Set the webhook URL provided by Heroku.