Skip to main content

High-stealth WhatsApp Web automation plugin for CamouChat. WA-JS powered, async-first, multi-account with AES-256 encrypted storage.

Project description

CamouChat WhatsApp 🟢

[!IMPORTANT] 🦊 This is the CamouChat WhatsApp Plugin Repository. If you are looking for the main CamouChat project or full ecosystem documentation, please visit our Central Repository.

High-stealth WhatsApp automation plugin for the CamouChat ecosystem. Built on top of camouchat-browser and WA-JS, providing a structured, API-driven pipeline for multi-account automation with end-to-end encrypted message storage.

PyPI PyPI Downloads GitHub Release

[!WARNING] This package requires a one-time binary fetch for the underlying Camoufox browser engine after installation. See Setup below.

Key Features

  • WA-JS Integration: Uses the internal WhatsApp Web API via wa-js — not fragile DOM selectors.
  • Multi-Account Isolation: Each account runs in a sandboxed profile with isolated cookies, storage, and fingerprints.
  • E2E Encryption: All stored messages are encrypted at rest using AES-256-GCM.
  • Async-First: Fully asyncio-native for high-throughput multi-session workloads.
  • Humanized Behavior: Mouse movements, typing cadence, and delays mimic organic user behavior.

Installation

Using uv (Recommended)

uv add camouchat-whatsapp "camoufox[geoip]"

Using pip

pip install camouchat-whatsapp "camoufox[geoip]"

Setup

[!WARNING] uv sync / pip install alone are not enough. You must fetch the Camoufox browser binary separately.

With uv

uv run python -m camoufox fetch

With pip

python -m camoufox fetch

This downloads the latest hardened Firefox binary used internally by Camoufox.

Quick Start

import asyncio
import base64
import os

from camouchat_browser import BrowserConfig, CamoufoxBrowser, ProfileManager
from camouchat_core import Platform, KeyManager, MessageDecryptor, MediaType
from camouchat_whatsapp import (
    Login,
    WapiSession,
    InteractionController,
    MediaController,
    MessageModelAPI,
    FileTyped,
    RegistryConfig,
    on_newMsg,
)

async def main():
    # 1. Profile
    pm = ProfileManager()
    profile = pm.create_profile(platform=Platform.WHATSAPP, profile_id="work")

    # 2. Browser
    config = BrowserConfig.from_dict({"platform": Platform.WHATSAPP, "headless": False})
    browser = CamoufoxBrowser(config=config, profile=profile)
    page = await browser.get_page()

    # 3. Login (reuses saved session automatically)
    login = Login(page=page, profile=profile)
    await login.login(method=0)

    # 4. API Controllers
    wapi = WapiSession(page=page)
    interaction = InteractionController(page=page, wapi=wapi)
    media = MediaController(page=page, wapi=wapi, profile=profile)

    # 5. Message Hook (Auto-Storage + E2E Encryption)
    registry = RegistryConfig(profile=profile, store=True, encrypt=True)

    @on_newMsg(wapi_session=wapi, config=registry)
    async def handle_message(msg: MessageModelAPI):
        # --- Decrypt message on-the-fly for command processing ---
        plain_body = msg.body
        if msg.encryption_nonce and msg.body:
            key_path = profile.encryption.get("key_file")
            if key_path:
                with open(key_path, "rb") as f:
                    raw_key = KeyManager.decode_key_from_storage(f.read().decode())
                try:
                    nonce_b = base64.b64decode(msg.encryption_nonce)
                    cipher_b = base64.b64decode(msg.body)
                    plain_body = MessageDecryptor(raw_key).decrypt_message(
                        nonce_b, cipher_b, msg.id_serialized or None
                    )
                except Exception as e:
                    print(f"Decryption failed: {e}")

        print(f"\n[+] New Msg from {msg.jid_From}: {plain_body}")

        # --- Command Handling ---
        if plain_body == "!ping":
            # API send (Zero DOM interaction - stealthy)
            await interaction.send_api_text(
                chat_id=msg.jid_From,
                text="🏓 Pong!",
                quoted_msg_id=msg.id_serialized,
            )

        elif plain_body and plain_body.startswith("!echo "):
            # Humanized DOM send (Simulates keyboard typing)
            echo_text = plain_body.replace("!echo ", "")
            await interaction.send_text(
                message=msg,
                text=f"Echo: {echo_text}",
                quote=True,
                send=True,
            )

        elif msg.msgtype in ("image", "video", "document"):
            # Media handling (Save & Re-upload)
            saved_path = await media.save_media(message=msg)
            if saved_path:
                print(f"[✔] Media saved to {saved_path}")

                # Re-upload the same media back
                mtype = MediaType.IMAGE if msg.msgtype == "image" else MediaType.DOCUMENT
                file_obj = FileTyped(uri=saved_path, name=os.path.basename(saved_path), mime_type=msg.mimetype)

                await media.add_media(mtype=mtype, file=file_obj, force=True)

    # 6. Activate listener and wait
    await handle_message()
    print("[\u2714] Hook active. Try sending !ping, !echo <text>, or an image in WhatsApp.")
    await asyncio.Event().wait()

if __name__ == "__main__":
    try:
        asyncio.run(main())
    except KeyboardInterrupt:
        pass

Anti-Ban Best Practices

  • Use residential proxies and enable GeoIP matching.
  • Run only one visible browser (others auto-switch to headless).
  • Respect rate limits — avoid burst-sending messages.
  • Use test accounts before deploying on real numbers.

⚠️ Important Beta Information

[!WARNING] This package is currently in BETA Version. Errors and inconsistencies are expected.

  • It is highly recommended to use test accounts.
  • Start with one browser in headed mode.
  • Avoid using multi-account automation until the full 1.0.0 release.

[!CAUTION] Rate Limiting Patterns

Rate limiting is currently a manual concern. An inbuilt limiter will be added in a future version with Monitor&Metrics insertion.

Until then, ensure you manually rate limit inside your @on_newMsg handler to avoid account bans.

Documentation

Guide Description
WA-JS Integration Bridge architecture, stealth engine, ChatStore sync caveats
Core — Login & UI Config Login (QR + phone code), WebSelectorConfig
Chat API Manager get_chat_list, open_chat, all RAM/DOM methods
Message API Manager get_messages, extract_media, push listener
Controllers InteractionController, MediaController, send_api_text
Event Architecture @on_newMsg, @on_storage, @on_encrypt decorator pipeline
Storage SQLAlchemyStorage, dialect config, Query retrieval layer
API Models ChatModelAPI, MessageModelAPI field reference
Agent Reference 🤖 Full API surface + rules for AI agents / LLM tooling
Core SDK camouchat-core protocol definitions
Browser Plugin ProfileManager, BrowserConfig, CamoufoxBrowser

Real-World Test Scripts

For complete, runnable integration examples see the test directories:

  • E2E Scripts — full end-to-end integration tests covering message events, media, group operations, and command handling.
  • Smoke Tests — lightweight bridge validation script that checks every API surface (messages, chats, groups, media, privacy, labels, newsletters) against a live session.

⚖️ Security & Ethics

CamouChat's strict policy regarding acceptable automation, anti-spam, and stealth disclaimers can be found in our central ecosystem hub:

👉 SECURITY.md


Acknowledgements & Third-Party Code

CamouChat WhatsApp uses portions of the wa-js library developed by the WPPConnect Team.

wa-js provides the internal WhatsApp Web JavaScript bridge that powers reliable, selector-free automation. It is distributed under the Apache License 2.0.

See the NOTICE file for full compliance details.

License

MIT License. See LICENSE for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

camouchat_whatsapp-0.7.3.tar.gz (180.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

camouchat_whatsapp-0.7.3-py3-none-any.whl (193.4 kB view details)

Uploaded Python 3

File details

Details for the file camouchat_whatsapp-0.7.3.tar.gz.

File metadata

  • Download URL: camouchat_whatsapp-0.7.3.tar.gz
  • Upload date:
  • Size: 180.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for camouchat_whatsapp-0.7.3.tar.gz
Algorithm Hash digest
SHA256 70533eb8e2911e3a7d273b1a0bf23c718b5495f270cd4cf2af8f575abc329c2f
MD5 2f38a0430b31f55f5743ddfff75c7f0c
BLAKE2b-256 7d00ca2cf1a2c0e1d0053d3aeeac058b5496ab4f6ee901c09c9bc394ca5803f1

See more details on using hashes here.

Provenance

The following attestation bundles were made for camouchat_whatsapp-0.7.3.tar.gz:

Publisher: publish.yml on CamouChat-Team/camouchat-whatsapp

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file camouchat_whatsapp-0.7.3-py3-none-any.whl.

File metadata

File hashes

Hashes for camouchat_whatsapp-0.7.3-py3-none-any.whl
Algorithm Hash digest
SHA256 9d3cb078417108c508e98a8c102d0ea5d84264394f3d12d2cb71c3f90fbadd66
MD5 f4eb30f5960b1cedc186a12dec537803
BLAKE2b-256 b6c929edc50f2061b892f9302dbf77d1219923d6648a999c6ce9da6a615adb7a

See more details on using hashes here.

Provenance

The following attestation bundles were made for camouchat_whatsapp-0.7.3-py3-none-any.whl:

Publisher: publish.yml on CamouChat-Team/camouchat-whatsapp

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page