Send automated WhatsApp messages using Python and Selenium. After a one-time QR code scan, the script can send messages without any manual intervention. Supports scheduled messaging to multiple contacts throughout the day.
- β One-time QR code scanning - session is saved for future use
- β Send messages by contact name or phone number
- β Character-by-character typing to avoid WhatsApp Web issues
- β Handles page refreshes and dynamic loading
- β Persistent login session
- β Scheduled messaging - send messages at specific times
- β Bulk messaging - send to multiple contacts from a JSON file
- β Timezone support - uses BogotΓ‘ time (UTC-5)
- Python 3.7 or higher
- Firefox browser installed
- GeckoDriver (Firefox WebDriver)
Windows:
- Download GeckoDriver from GitHub Releases
- Extract the
geckodriver.exefile - Add the folder to your system PATH, or place it in the same folder as your script
macOS:
brew install geckodriverLinux (Ubuntu/Debian):
sudo apt update
sudo apt install firefox-geckodriverLinux (Fedora):
sudo dnf -y install firefox-geckodriverLinux (Other distributions):
Download from GitHub and place in /usr/local/bin/
Open your terminal/command prompt and navigate to your project directory:
# Create virtual environment
python -m venv venvWindows:
venv\Scripts\activatemacOS/Linux:
source venv/bin/activateYou should see (venv) at the beginning of your terminal prompt.
With the virtual environment activated:
pip install -r requirements.txtRename your file contacts_sample.json to contacts.json in your project directory with your contacts and schedule
JSON Structure:
name: Contact's name (for reference only)phone: Phone number with country code (no + or spaces)message: Custom message for this contact (supports emojis and line breaks with\n)schedule_time: Time to send in 24-hour format "HH:MM" (BogotΓ‘ timezone UTC-5)
- Make sure your virtual environment is activated
- Run the script:
python whatsapp_auto_sender.py- Firefox will open automatically
- Scan the QR code with your phone's WhatsApp
- The script will save your session
- Done! Your session is now saved
Send messages to multiple contacts at scheduled times:
python whatsapp_auto_sender.pyThe script will:
- Load all contacts from
contacts.json - Display a schedule overview
- Wait until each scheduled time
- Send messages automatically one by one
Example Output:
============================================================
SCHEDULED MESSAGES OVERVIEW
============================================================
Current time in BogotΓ‘: 08:45:23
Total contacts: 3
Schedule:
09:00 - Juan (+573001234567)
10:30 - John (+573007654321)
14:00 - Maria (+573009876543)
============================================================
π Processing contact 1/3
Name: Juan
Phone: +573001234567
β° Scheduled for 09:00 (BogotΓ‘ time)
β³ Waiting 14 minutes and 37 seconds...
Edit the script and add the single message section:
# Option 1: Send single message immediately
sender.send_message_by_phone(
phone_number="573001234567",
message="Hi Juan, this is an automated message test :)"
)Then run:
python whatsapp_auto_sender.pyThe default behavior needs the contacts.json. Make sure the Python code is using the following line:
sender.send_scheduled_messages("contacts.json")and then run the script:
python whatsapp_auto_sender.pyFeatures:
- Automatically waits until scheduled time for each contact
- Processes contacts in chronological order
- Skips messages scheduled in the past
- Shows progress and status for each message
Works even if the contact is not saved. Include country code without + or spaces:
sender.send_message_by_phone(
phone_number="573001234567",
message="Hello!"
)The contact must be saved in your phone's contacts:
sender.send_message(
contact_name="John Doe",
message="Hello John!"
)- Timezone: America/Bogota (UTC-5)
- Format: 24-hour format "HH:MM"
- Examples:
- Morning:
"09:00","09:30" - Afternoon:
"14:00","15:45" - Evening:
"18:00","20:30" - Night:
"23:00","23:59"
- Morning:
Important: The script uses BogotΓ‘ time (Colombia). If you're in a different timezone, the messages will still be sent at the specified BogotΓ‘ time.
Include country code without + or spaces:
Examples:
- π¨π΄ Colombia:
573001234567(57 + phone number) - πΊπΈ USA:
15551234567(1 + phone number) - π¬π§ UK:
447911123456(44 + phone number) - πͺπΈ Spain:
34612345678(34 + phone number) - π²π½ Mexico:
525512345678(52 + phone number) - π¦π· Argentina:
5491112345678(54 + phone number)
Uncomment line 43 in the script:
options.add_argument("--headless")Note: First-time QR code scanning requires a visible browser window.
By default, the session is saved in whatsapp_profile folder. To change it:
sender = WhatsAppSender(profile_dir="my_custom_folder")Modify the sleep times in the script to type faster or slower:
- Line 124: Search box typing speed (default: 0.1 seconds per character)
- Line 172: Message typing speed (default: 0.05 seconds per character)
Lower values = faster typing, but may be detected by WhatsApp.
Specify a different JSON file path:
sender.send_scheduled_messages("path/to/my_contacts.json")Use \n in your JSON messages for line breaks:
{
"message": "Hello!\n\nThis is a multi-line message.\n\nBest regards,\nYour Name"
}- Make sure GeckoDriver is installed and in your PATH
- Try placing
geckodriver.exein the same folder as your script
- Make sure you installed pytz:
pip install pytz - Verify your virtual environment is activated
- Delete the
whatsapp_profilefolder - Run the script again to create a new session
- Make sure the phone number includes the country code
- Verify the contact name is spelled exactly as it appears in WhatsApp
- Check that WhatsApp Web is not open in another browser
- Ensure the scheduled time hasn't already passed
- The script will automatically create an example file
- Edit the example with your contacts and times
- Make sure the JSON file is in the same directory as the script
- Verify you're using 24-hour format:
"14:00"not"2:00 PM" - The timezone is set to BogotΓ‘ (UTC-5)
- Check your system time is correct
- This is intentional for debugging
- Check what's displayed on screen
- Close manually or press Ctrl+C in terminal
In the script, this is enabled by default:
sender.send_scheduled_messages("contacts.json")Comment out Mode 1 and uncomment this:
sender.send_message_by_phone(
phone_number="573001234567",
message="Hi Steffy, this is an automated message test :)"
)- Test First: Send a test message to yourself before scheduling bulk messages
- Realistic Timing: Space out messages by at least 15-30 minutes to appear more natural
- Personalize Messages: Use different messages for each contact
- Keep Session Active: Run the script at least once a week to keep WhatsApp session alive
- Backup contacts.json: Keep a backup of your contacts file
- Monitor First Run: Watch the first scheduled run to ensure everything works correctly
- Use Descriptive Names: In contacts.json, use clear names for easy reference
{
"contacts": [
{
"name": "Client 1",
"phone": "573001234567",
"message": "Good morning! Have a great day! βοΈ",
"schedule_time": "08:00"
}
]
}{
"contacts": [
{
"name": "Friend",
"phone": "573001234567",
"message": "Happy Birthday! ππ Wishing you an amazing day!",
"schedule_time": "09:00"
}
]
}{
"contacts": [
{
"name": "Patient 1",
"phone": "573001234567",
"message": "Reminder: You have an appointment tomorrow at 3 PM. See you then! π¨ββοΈ",
"schedule_time": "18:00"
}
]
}When you're done:
deactivateyour-project/
βββ whatsapp_auto_sender.py # Main script
βββ contacts.json # Your contacts (git-ignored)
βββ contacts_sample.json # Rename this file as contacts.json
βββ whatsapp_profile/ # Saved WhatsApp session (git-ignored)
βββ venv/ # Virtual environment (git-ignored)
βββ .gitignore # Git ignore file
βββ requirements.txt # Python packages to install
βββ README.md # This file
- Keep
contacts.jsonprivate - it contains phone numbers and messages - Keep
whatsapp_profile/secure - it contains your WhatsApp Web login session - Add both to
.gitignore- never commit these to version control - Don't share your session folder - anyone with access can use your WhatsApp
- WhatsApp may limit bulk messaging to prevent spam
- Session expires if inactive for extended periods
- Requires Firefox browser to be installed
- Cannot send media files (images, videos, documents)
- Works only with text messages
- The script types messages character by character to avoid WhatsApp Web detection
- Your WhatsApp session is saved locally in the
whatsapp_profilefolder - The script works with personal WhatsApp accounts (no business API needed)
- Messages are sent in chronological order based on schedule_time
- Past scheduled times are automatically skipped
This is a personal automation tool. Use responsibly and in accordance with WhatsApp's Terms of Service.
Happy automating! π
