Skip to main content

WhatsPlay 🚀

Modern WhatsApp Web automation with Playwright and Python

PyPI version Downloads Python License Tests


✨ Features

  • Stable selectors — attribute-based (data-pre-plain-text, aria-label, data-testid), not minified CSS classes that break on every WA update
  • Multi-language — works with WhatsApp Web in Spanish and English out of the box
  • Voice messages — duration and download support
  • Persistent sessions — scan QR once, reuse the session
  • Unread chat detection — multiple heuristics (badges, font-weight, aria-labels)
  • Message filtering — filter by sender, text, or custom rules
  • File & media support — images, audio, documents
  • Event-driven — on_start, on_message, on_unread_chat, etc.
  • Headless mode — works on servers without GUI
  • 14k+ downloads on PyPI — battle-tested selectors

Quick Start

pip install whatsplay
python -m playwright install chromium
import asyncio
from pathlib import Path
from whatsplay import Client
from whatsplay.auth import LocalProfileAuth

async def main():
    auth = LocalProfileAuth(Path.home() / "whatsapp_session")
    client = Client(auth=auth, headless=False)

    @client.event("on_unread_chat")
    async def on_unread_chat(chat_name, messages):
        await client.send_message(chat_name, "🤖 Automatizado con WhatsPlay!")

    await client.start()

asyncio.run(main())

📦 Installation

From PyPI

pip install whatsplay

After installing, download the Playwright browser:

python -m playwright install chromium

From source

git clone https://github.com/markbus-ai/whatsplay.git
cd whatsplay
pip install -e .
python -m playwright install chromium

📖 Usage Guide

Basic connection

from pathlib import Path
from whatsplay import Client
from whatsplay.auth import LocalProfileAuth

data_dir = Path.home() / "whatsapp_session"
data_dir.mkdir(parents=True, exist_ok=True)

auth = LocalProfileAuth(data_dir)
client = Client(auth=auth, headless=False)

Events

@client.event("on_start")
async def on_start():
    print("✅ Client started")

@client.event("on_auth")
async def on_auth():
    print("📸 Scan the QR code")

@client.event("on_unread_chat")
async def on_unread_chat(chat_name, messages):
    print(f"📩 Unread messages in {chat_name}")
    for msg in messages:
        print(f"  {msg.sender}: {msg.text}")

Sending messages

# By chat name
await client.send_message("Mi Grupo", "Hola!")

# By phone number (with country code)
await client.send_message("+5491123456789", "Mensaje directo")

Voice messages

@client.event("on_unread_chat")
async def handler(chat_name, messages):
    for msg in messages:
        if msg.type == "voice":
            print(f"🎤 Voice message: {msg.duration}s")
            # Download the audio
            audio = await client.download_audio(msg)

📚 Examples

The examples/ directory includes ready-to-run scripts:

File Description
simple_example.py Basic event-driven auto-reply
open_example.py Open a specific chat programmatically
search_example.py Search conversations with detailed results
verify_selectors.py E2E validation of all selectors against live WA Web
investigate_voice.py Live DOM investigation for voice message structure
wsp.py CLI tool for quick message sending

📊 PyPI Stats

Period Downloads
All time 14,700+
Last month 2,300+
Last week 190+

🛠 Development

Setup

pip install -e ".[dev]"
python -m playwright install chromium

Running tests

pytest tests/ -v

34 tests passing with 0 warnings.


🗺 Roadmap

Completed ✅

  • Async event system
  • Persistent session (QR once)
  • Message sending / receiving
  • File & media support
  • Voice message detection & duration
  • Unread chat detection with multiple heuristics
  • Search with fallback strategies
  • Stable attribute-based selectors (no more fragile CSS classes)
  • Multi-language (Spanish / English)
  • Filter system (MessageFilter)
  • Virtualized list support

In progress 🚧

  • Message reactions API
  • Group management API
  • Webhook integration

Planned 🔮

  • Multi-account simultaneous support
  • Monitoring dashboard
  • Native TypeScript definitions

❓ FAQ

Is it safe? It uses WhatsApp Web's official interface — as safe as using WhatsApp in a browser.

Can WhatsApp detect it? There's always risk with automation. Use responsibly.

Does it work headless? Yes, Playwright's headless mode is supported.

Does it work in Spanish? Yes, all selectors handle both Spanish and English WhatsApp Web locales.


🐞 Report a bug

Open an issue with:

  • Problem description
  • Reproduction steps
  • Python version and dependencies
  • Relevant logs

🤝 Contributing

  1. Fork the repo
  2. Create a branch (git checkout -b feature/amazing)
  3. Commit (git commit -am 'Add amazing feature')
  4. Push (git push origin feature/amazing)
  5. Open a Pull Request

📄 License

Apache 2.0


⭐ Star on GitHub if you find it useful

Made with ❤️ by @markbus-ai

Metadata

Release files for whatsplay 2.6.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Built distribution (wheel)

Table of built distributions (wheels) for whatsplay 2.6.0
File Interpreter ABI Platform
whatsplay-2.6.0-py3-none-any.whl Python 3 none any Details

Release files / whatsplay-2.6.0-py3-none-any.whl

Download URL whatsplay-2.6.0-py3-none-any.whl
Size 58.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a979fcde7855aa515c6199aa58e4e2d0f40d15b88a1a7affcb0c5528495bf033
BLAKE2b-256 checksum
How to use checksums
65321b3684443f940feb9f56d3a0dadc4b900a0cd5587cad655283ffcc9f61ff
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.12

Release history Release notifications | RSS feed

2.6.2

2 release files

2.6.1

1 release file

This release

2.6.0 This release

1 release file

2.5.1

2 release files

2.5.0

2 release files

2.4.0

2 release files

2.3.0

2 release files

2.2.1

2 release files

2.2.0

2 release files

2.1.23

2 release files

2.1.22

2 release files

2.1.20

2 release files

2.1.19

2 release files

2.1.18

2 release files

2.1.17

2 release files

2.1.16

2 release files

2.0.16

2 release files

2.0.9

1 release file

2.0.8

1 release file

2.0.7

2 release files

2.0.6

2 release files

2.0.5

1 release file

2.0.1

1 release file

2.0.0

2 release files

1.9.9

2 release files

1.9.8

2 release files

1.9.7

2 release files

1.8.7

2 release files

1.8.6

2 release files

1.8.5

2 release files

1.8.4

2 release files

1.8.3

2 release files

1.8.2

2 release files

1.8.1

2 release files

1.8.0

2 release files

1.7.9

2 release files

1.7.7

2 release files

1.7.6

2 release files

1.7.5

2 release files

1.7.4

2 release files

1.7.3

2 release files

1.7.2

2 release files

1.7.1

2 release files

1.7.0

2 release files

1.6.0

2 release files

1.5.2

2 release files

1.5.1

2 release files

1.5.0

2 release files

1.4.6

2 release files

1.4.5

2 release files

1.3.5

2 release files

1.3.4

2 release files

1.3.3

2 release files

1.2.3

2 release files

1.2.2

2 release files

1.1.2

2 release files

1.1.1

2 release files

1.1.0

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page