Skip to content

sherlock-488/xchat-playground

xchat-playground 🧪

Local replay lab for X Activity / XChat webhook development. Debug CRC, signatures, payloads, and schema drift — without burning API calls.

CI Python 3.10+ License: MIT X Developer Forum

Not an official X SDK. This is an independent developer tool — a local harness for testing, replaying, and debugging X Activity API webhooks before touching production.

xchat-playground demo

Local-first by default. Not mock-only: validate the same webhook pipeline against a real X Activity public event via profile.update.bio using an approved X developer app + App Bearer Token.

Current XChat API status

Area Status
X Activity stream / webhook Documented
profile.update.bio public smoke test Documented
chat.received event name Documented
Chat API routes (GET /2/chat/conversations, POST /2/chat/conversations/{id}/messages, etc.) Documented in official migration guide
XAA chat.received encrypted payload fields Official sample / observed
chat-xdk decrypt / encrypt Pending stable public release
Real XChat plaintext decrypt Experimental — requires chat-xdk stable release
Chat media upload routes Coming soon / not yet in prod

Language notes:

  • "chat.received event name is documented" — the event type string itself is official.
  • "chat.received encrypted payload shape is sample-driven / observed" — field-level schema is inferred from the official xchat-bot-python sample, not yet fully documented in docs.x.com.
  • "Real decrypt remains experimental" — chat-xdk has not yet reached a stable public release. Do not rely on plaintext decrypt in production.

What is real vs experimental

Path Status
Local XAA simulation ✅ Supported
CRC / signature debugging ✅ Supported
Replay / diff / repro packs ✅ Supported
Real profile.update.bio public smoke test ✅ Supported
Observed chat.received encrypted payload fixture ⚠️ Observed / sample-driven
Real XChat plaintext decrypt ⚠️ Experimental (chat-xdk not yet stable)

Who this is for

  • Developers building X Activity API webhooks or XChat bots
  • Teams migrating from legacy DM / AAA to XAA + E2EE
  • Anyone debugging CRC failures, signature mismatches, or encrypted payload issues
  • Developers who want to replay and diff payloads as X's event schema evolves

Not for: end users expecting a production-ready bot runtime or complete official SDK.


Why this exists

Building on XChat means dealing with:

  • chat.received events that silently fail CRC validation
  • Encrypted DM payloads that return {} when you look them up via REST
  • dm_events going quiet after E2EE is enabled on a conversation
  • Event format changes that break your handler at 2am

xchat-playground gives you a local harness to reproduce, replay, and diff all of the above before touching production.


Scope and honest limits

Aligned with X Activity API docs and the official XChat migration guide as of 2026-04-21.

Area Status Schema
Webhook CRC + signature validation ✅ Full support
profile.update.bio delivery ✅ Official docs.x.com example docs
chat.received envelope ⚠️ Observed from xchat-bot-python observed
chat.sent / chat.conversation_join ⚠️ Event names official; payload shape provisional demo
Real E2EE decryption (crypto real) ⚠️ Placeholder — awaits chat-xdk stable release
Activity Stream delivery ℹ️ Not in scope — this tool focuses on the webhook path

Can be validated against a real X Activity public event today via profile.update.bio — no private-event OAuth scopes required for the monitored user. You still need an approved X developer app and Bearer Token to register the webhook and subscription.

Schema labels: docs = matches official docs.x.com delivery example. observed = inferred from xchat-bot-python source, not yet in docs.x.com. demo = flat teaching format for local testing only.

Delivery note: X Activity API supports both webhook (HTTP POST) and Activity Stream (long-lived connection). xchat-playground focuses on the webhook path. The official bot template uses Activity Stream. Both are valid — choose based on your architecture.


What's inside

Module CLI What it does
Event Simulator playground simulate Generate chat.received / chat.sent / chat.conversation_join / profile.update.bio fixtures
Webhook Harness playground webhook CRC challenge + HMAC-SHA256 signature validation playground
Replay Lab playground replay Record → scrub PII → replay → diff against your handler
Crypto Sandbox playground crypto Stub or real-key decryption flow walkthrough
Repro Packs playground repro One-click presets for known community bug reports
Web UI playground serve Browser-based event inspector + debug tools
Doctor playground doctor Check your environment is ready

Quickstart (no API key needed)

git clone https://github.com/sherlock-488/xchat-playground
cd xchat-playground
pip install uv && uv sync
uv run playground serve
# → open http://localhost:7474/ui

That's it. The Web UI opens with demo events pre-loaded so you're never staring at a blank screen. No X developer account required for local testing.


CLI Reference

# Start local server + Web UI
uv run playground serve --port 7474

# Check your environment
uv run playground doctor

# Generate event fixtures
uv run playground simulate chat-received --sender-id 123 --recipient-id 456
uv run playground simulate chat-received --no-encrypted  # plaintext mode
uv run playground simulate batch --count 20 --output fixtures/batch.jsonl

# Webhook tools
uv run playground webhook crc <crc_token> --consumer-secret <secret>
uv run playground webhook verify '<payload>' '<x-twitter-webhooks-signature value>'

# Replay
uv run playground replay run fixtures/batch.jsonl --target http://127.0.0.1:8080/webhook
uv run playground replay diff fixtures/batch.jsonl \
  --baseline-url http://127.0.0.1:8080/webhook \
  --candidate-url http://127.0.0.1:8081/webhook

# Crypto sandbox
uv run playground crypto stub "STUB_ENC_SGVsbG8h"
uv run playground crypto real "REAL_PAYLOAD" --state-file state.json

# Repro packs
uv run playground repro list
uv run playground repro run encrypted-lookup-empty --verbose
uv run playground repro run chat-webhook-not-received --verbose
uv run playground repro run legacy-dm-stops-after-e2ee --verbose

Repro Packs

One-click reproductions of the most common XChat API issues reported in the developer community:

Pack ID Issue
chat-webhook-not-received CRC not handled / localhost URL / secret mismatch / subscription missing
encrypted-lookup-empty GET /2/dm_events/{id} returns {} for E2EE conversations
legacy-dm-stops-after-e2ee Legacy DM endpoint stops updating after conversation upgrade
encrypted-chat-decrypt-pending Received chat.received but cannot read plaintext — chat-xdk pending

Run any pack with --verbose for step-by-step explanation and workaround.


Live Webhook Testing

To test with a real X webhook registration, expose your local server publicly:

# Option 1: cloudflared (recommended, free)
npx cloudflared tunnel --url http://localhost:7474

# Option 2: ngrok
ngrok http 7474

Then register the tunnel URL as your webhook in the X Developer Portal.

Note: http://localhost and http://127.0.0.1 are not the same in X's OAuth2 validation. For local OAuth2 callbacks, use http://127.0.0.1 — see Known Gotchas.


Requirements

  • Python 3.10+
  • uv (recommended) or pip
  • X Developer Account (optional — only needed for live webhook testing)

Environment Variables

Copy .env.example to .env and fill in:

# Required for live webhook signature validation
CONSUMER_SECRET=your_app_consumer_secret

# Required for real-key crypto (xchat-bot-python login flow)
# state.json is auto-generated by xchat-bot-python — never commit it

Project Structure

xchat-playground/
├── playground/
│   ├── cli.py              # CLI entry point (typer)
│   ├── simulator/          # Event fixture generator
│   ├── webhook/            # CRC + signature + local server
│   ├── replay/             # Record, replay, diff
│   ├── crypto/             # Stub + real-key decryption
│   ├── repro/              # Known-bug repro packs
│   └── web/                # Browser UI (index.html + app.js) — canonical source
├── tests/                  # pytest test suite
└── docs/                   # Detailed documentation

Status: alpha

This is a pre-1.0 alpha released around XChat's April 2026 launch.

  • CRC, signature, webhook harness, replay, repro packs: stable and tested
  • profile.update.bio: docs schema — matches official docs.x.com delivery example
  • chat.received: observed schema — inferred from xchat-bot-python, not yet in docs.x.com
  • chat.sent / chat.conversation_join: demo schema only — payload shape provisional
  • crypto real: placeholder — will be updated when chat-xdk reaches stable release
  • X's event schema is actively evolving; this tool is designed to help you catch schema drift

If you find a field mismatch between this tool and what X actually sends, open an issue — that's exactly the kind of feedback that makes this useful.


Contributing

Contributions welcome! See CONTRIBUTING.md.

Found a new XChat API bug? Open a Repro Pack issue — if it's reproducible, we'll add it as a preset.

Policy note for bot builders: If you use this playground to build automated bots, note that X's Developer Guidelines require automated accounts to carry an Automated label, disclose the operator in bio, and provide opt-out. AI-generated replies require additional approval. This tool is a testing harness — what you build with it is your responsibility.


Related

Want a production-structured Python starter for your XChat bot?xchat-bot-starter-pro — clean architecture, dual transport (stream + webhook), CLI, Docker, CI, 5 example bots.


Resources


License

MIT — see LICENSE.

About

Local simulator & replay lab for XChat bots — debug webhooks, replay events, test E2EE flows without burning API credits

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors