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

Download files

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

Source Distribution

wechatanybot_sdk-1.0.0.tar.gz (14.8 kB view details)

Uploaded Source

Built Distribution

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

wechatanybot_sdk-1.0.0-py3-none-any.whl (16.7 kB view details)

Uploaded Python 3

File details

Details for the file wechatanybot_sdk-1.0.0.tar.gz.

File metadata

  • Download URL: wechatanybot_sdk-1.0.0.tar.gz
  • Upload date:
  • Size: 14.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.2

File hashes

Hashes for wechatanybot_sdk-1.0.0.tar.gz
Algorithm Hash digest
SHA256 f0f3c200e802ca2ce2810d3e250f6e6f997064c98ebe2ee4def2b3aba2b29a29
MD5 c2b82d876d4b84f3a0ef75d919632356
BLAKE2b-256 c1f61034728a7b38810b3f59594b80b8c46a7705dc573d1b5dc83961d8722ce1

See more details on using hashes here.

File details

Details for the file wechatanybot_sdk-1.0.0-py3-none-any.whl.

File metadata

File hashes

Hashes for wechatanybot_sdk-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 774103780154161f6ae2e48e77ee5dd90bd0767eab05a202c00a09e664bf752d
MD5 4b607b21c69809d2f18f0d1e7a85e866
BLAKE2b-256 948a564fd9416165d3864812e13c69ea77e490961ee21565fd3df907b20d4c25

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 files

Supported by

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