Skip to main content

wechatanybot-sdk — Python SDK

WeChat iLink Bot SDK for Python — async, typed, production-grade.

Install

pip install wechatanybot-sdk

Requires Python ≥ 3.9. Dependencies: aiohttp, cryptography.

Quick Start

from wechatanybot import WeChatAnyBot

bot = WeChatAnyBot()

@bot.on_message
async def handle(msg):
    await bot.send_typing(msg.user_id)
    await bot.reply(msg, f"Echo: {msg.text}")

bot.run()  # login + start in one call

Or with async control:

import asyncio
from wechatanybot import WeChatAnyBot

async def main():
    bot = WeChatAnyBot()
    await bot.login()

    @bot.on_message
    async def handle(msg):
        await bot.reply(msg, f"Echo: {msg.text}")

    await bot.start()

asyncio.run(main())

Configuration

bot = WeChatAnyBot(
    base_url="https://ilinkai.weixin.qq.com",   # default
    cred_path="~/.wechatanybot/credentials.json", # default
    on_qr_url=lambda url: print(f"Scan: {url}"),
    on_scanned=lambda: print("Scanned!"),
    on_expired=lambda: print("Expired..."),
    on_error=lambda err: print(f"Error: {err}"),
)

API Reference

Method Description
await bot.login(force=False) QR login (auto-skips if creds exist)
await bot.start() Start long-poll loop
bot.run() Sync: login + start
bot.stop() Stop gracefully
bot.on_message(handler) Register handler (also works as decorator)
await bot.reply(msg, text) Reply (auto context_token + stop typing)
await bot.send(user_id, text) Send to user (needs prior context)
await bot.send_typing(user_id) Show "typing..." indicator
await bot.stop_typing(user_id) Cancel typing indicator
await bot.reply_media(msg, content) Reply with media (image, file, video)
await bot.send_media(user_id, content) Send media to user (needs prior context)
await bot.download(msg) Download media from incoming message
await bot.download_raw(media, aeskey) Download and decrypt a raw CDN media reference
await bot.upload(data, user_id, media_type) Upload file to CDN (does not send)

Media Operations

Sending Media

# Reply with an image
await bot.reply_media(msg, {"image": png_bytes})

# Reply with a file
await bot.reply_media(msg, {"file": data, "file_name": "report.pdf"})

# Reply with a video
await bot.reply_media(msg, {"video": mp4_bytes, "caption": "Check this"})

# Send media proactively (needs prior context_token)
await bot.send_media(user_id, {"image": png_bytes})

Downloading Media

@bot.on_message
async def handle(msg):
    # Auto-detect and download (priority: image > file > video > voice)
    media = await bot.download(msg)
    if media:
        print(f"Type: {media.type}, Size: {len(media.data)} bytes")
        if media.file_name:
            print(f"Filename: {media.file_name}")

    # Or download a raw CDN reference directly
    if msg.images:
        raw = await bot.download_raw(msg.images[0].media, msg.images[0].aes_key)

Uploading to CDN

# Upload without sending — returns UploadResult with CDN metadata
result = await bot.upload(file_bytes, user_id, media_type=3)

Message Types

@dataclass
class IncomingMessage:
    user_id: str
    text: str
    type: Literal["text", "image", "voice", "file", "video"]
    timestamp: datetime
    images: list[ImageContent]
    voices: list[VoiceContent]
    files: list[FileContent]
    videos: list[VideoContent]
    quoted_message: QuotedMessage | None
    raw: dict

AES-128-ECB Crypto

from wechatanybot import (
    generate_aes_key, encrypt_aes_ecb, decrypt_aes_ecb, decode_aes_key
)

key = generate_aes_key()
ct = encrypt_aes_ecb(b"Hello", key)
pt = decrypt_aes_ecb(ct, key)

# Decode protocol key (all 3 formats)
k = decode_aes_key("ABEiM0RVZneImaq7zN3u/w==")       # base64(raw)
k = decode_aes_key("00112233445566778899aabbccddeeff") # hex

Project Structure

python/
├── wechatanybot/
│   ├── __init__.py      ← Public exports
│   ├── client.py        ← WeChatAnyBot (login, start, reply, send)
│   ├── protocol.py      ← Raw iLink API calls
│   ├── auth.py          ← QR login + credential persistence
│   ├── types.py         ← All types (dataclasses)
│   ├── errors.py        ← Error hierarchy
│   └── crypto.py        ← AES-128-ECB encrypt/decrypt
├── examples/
│   └── echo_bot.py
├── tests/
│   ├── test_crypto.py   ← 10 tests
│   └── test_client.py   ← 8 tests
└── pyproject.toml

Testing

pip install -e ".[dev]"
pytest

License

MIT

Metadata

Release files for wechatanybot-sdk 1.0.0

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

Source distribution (sdist)

Source distribution for wechatanybot-sdk 1.0.0
File Size Uploaded
wechatanybot_sdk-1.0.0.tar.gz 14.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for wechatanybot-sdk 1.0.0
File Interpreter ABI Platform
wechatanybot_sdk-1.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 31.6 kB

Release files / wechatanybot_sdk-1.0.0.tar.gz

Download URL wechatanybot_sdk-1.0.0.tar.gz
Size 14.8 kB
Tags Source
SHA-256 checksum
How to use checksums
f0f3c200e802ca2ce2810d3e250f6e6f997064c98ebe2ee4def2b3aba2b29a29
BLAKE2b-256 checksum
How to use checksums
c1f61034728a7b38810b3f59594b80b8c46a7705dc573d1b5dc83961d8722ce1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.2

Release files / wechatanybot_sdk-1.0.0-py3-none-any.whl

Download URL wechatanybot_sdk-1.0.0-py3-none-any.whl
Size 16.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
774103780154161f6ae2e48e77ee5dd90bd0767eab05a202c00a09e664bf752d
BLAKE2b-256 checksum
How to use checksums
948a564fd9416165d3864812e13c69ea77e490961ee21565fd3df907b20d4c25
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.2

Release history Release notifications | RSS feed

This release

1.0.0 This release

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