Skip to content

feat: WeChat messenger channel integration #102

Description

@aecs4u

Summary

Add WeChat integration to enable RustyClaw agents to communicate via China's dominant messaging platform.

Background

WeChat (微信) is China's "super app" with 1.3B+ monthly active users. Key features:

  • Messaging and voice/video calls
  • WeChat Pay
  • Mini Programs
  • Official Accounts (subscription and service accounts)
  • Enterprise WeChat (WeCom) for businesses

Motivation

WeChat is essential for:

  • Chinese market reach (mandatory for China operations)
  • Enterprise communication in Asia
  • Payment integration
  • Mini Program ecosystems
  • Government/business integration in China

Proposed Design

Note: WeChat has multiple integration paths:

Option 1: WeChat Official Account (Subscription/Service Account)

[[messengers]]
name = "wechat"
type = "wechat_official"
enabled = true
app_id = "wx1234567890"
app_secret = "$WECHAT_APP_SECRET"
token = "$WECHAT_TOKEN"
encoding_aes_key = "$WECHAT_AES_KEY"

Option 2: Enterprise WeChat (WeCom)

[[messengers]]
name = "wecom"
type = "wecom"
enabled = true
corp_id = "ww1234567890"
agent_id = "1000002"
corp_secret = "$WECOM_SECRET"

Core Functionality

  1. Official Account:

    • Receive user messages via webhook
    • Send template messages
    • Customer service messages
    • Menu management
  2. Enterprise WeChat:

    • Send messages to employees
    • Department/tag-based messaging
    • Application messages
    • Group chat bots

Implementation

pub struct WeChatMessenger {
    app_id: String,
    app_secret: String,
    access_token: Option<(String, Instant)>,  // token + expiry
    client: reqwest::Client,
}

impl WeChatMessenger {
    pub async fn get_access_token(&mut self) -> Result<String> {
        // Check cached token
        if let Some((token, expiry)) = &self.access_token {
            if Instant::now() < *expiry {
                return Ok(token.clone());
            }
        }

        // Fetch new token
        let response = self.client
            .get("https://api.weixin.qq.com/cgi-bin/token")
            .query(&[
                ("grant_type", "client_credential"),
                ("appid", &self.app_id),
                ("secret", &self.app_secret),
            ])
            .send()
            .await?
            .json::<serde_json::Value>()
            .await?;

        let token = response["access_token"]
            .as_str()
            .ok_or("Missing access_token")?
            .to_string();

        let expires_in = response["expires_in"]
            .as_u64()
            .unwrap_or(7200);

        self.access_token = Some((token.clone(), Instant::now() + Duration::from_secs(expires_in)));
        Ok(token)
    }

    pub async fn send_template_message(&self, openid: &str, template_id: &str, data: serde_json::Value) -> Result<()> {
        let token = self.get_access_token().await?;

        self.client
            .post(format!("https://api.weixin.qq.com/cgi-bin/message/template/send?access_token={}", token))
            .json(&serde_json::json!({
                "touser": openid,
                "template_id": template_id,
                "data": data
            }))
            .send()
            .await?;

        Ok(())
    }
}

API Endpoints

WeChat Official Account

Endpoint Method Purpose
/cgi-bin/token GET Get access token
/cgi-bin/message/custom/send POST Send customer service message
/cgi-bin/message/template/send POST Send template message
/cgi-bin/menu/create POST Create menu

Enterprise WeChat

Endpoint Method Purpose
/cgi-bin/gettoken GET Get access token
/cgi-bin/message/send POST Send application message
/cgi-bin/appchat/send POST Send group chat message

Dependencies

[dependencies]
# Uses existing reqwest HTTP client
sha1 = "0.10"  # For webhook signature verification

Challenges

Challenge Solution
China firewall (GFW) Deploy in China or use CN-friendly hosting
Official Account verification Requires Chinese business license
Rate limits Aggressive (template: 10K/day, custom: 48h window)
Language barrier Documentation primarily in Chinese
Compliance ICP filing, real-name verification required

Acceptance Criteria

  • WeChat Official Account configuration
  • Access token management with 2-hour expiry handling
  • Webhook signature verification (SHA1)
  • Receive user messages and events
  • Send template messages
  • Send customer service messages
  • Enterprise WeChat (WeCom) support
  • Rate limit compliance
  • Documentation in docs/MESSENGER_WECHAT.md (English + 中文)

Security Considerations

  • App secret stored in encrypted vault
  • Webhook signature verification mandatory
  • Token refresh mechanism
  • IP whitelist configuration on WeChat side
  • HTTPS required for all webhooks

Related Issues

References

Notes

⚠️ Deployment Considerations:

  • Servers must be accessible from China (not blocked by GFW)
  • Consider using Alibaba Cloud, Tencent Cloud, or Huawei Cloud
  • Official Account verification requires Chinese business entity
  • Enterprise WeChat is easier for foreign companies

Recommendation: Start with Enterprise WeChat (WeCom) if targeting business users, as it has fewer restrictions for international companies.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions