Skip to main content

WeChat iLink Bot SDK for Python (wechatanybot) — async, typed, production-grade

Project description

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

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

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.

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