# 企微智能机器人 WebSocket 接入模式

## 协议概要

- WebSocket URL: `wss://openws.work.weixin.qq.com`
- 认证: `aibot_subscribe` 命令发 `bot_id` + `secret`
- 消息接收: `aibot_msg_callback` 命令
- 事件接收: `aibot_event_callback` 命令
- 消息回复: `aibot_respond_msg` 命令，`msgtype: "stream"`

## 核心代码模式

```python
import websocket

_ws_app = None

def on_open(ws_app):
    global _ws_app
    _ws_app = ws_app
    _send(ws_app, "aibot_subscribe", {"bot_id": BOT_ID, "secret": BOT_SECRET})

def on_message(ws_app, raw):
    msg = json.loads(raw)
    cmd = msg.get("cmd")
    body = msg.get("body")
    
    if cmd == "aibot_msg_callback":
        content = body.get("text", {}).get("content", "")
        msgid = body.get("msgid")
        # Process in background thread to avoid blocking WebSocket
        t = threading.Thread(target=process_and_reply, args=(content, msgid))
        t.daemon = True
        t.start()
    elif cmd == "aibot_event_callback":
        event_type = body.get("event", {}).get("eventtype")
        if event_type == "enter_chat":
            _send(ws_app, "aibot_respond_welcome_msg", {...})

def send_reply(msgid, text):
    _send(_ws_app, "aibot_respond_msg", {
        "msgtype": "stream",
        "stream": {"id": msgid, "finish": True, "content": text}
    })

ws_app = websocket.WebSocketApp(WS_URL, on_open=on_open, on_message=on_message)
ws_app.run_forever(ping_interval=0)  # disable client pings
```

## 消息格式

### 收到的消息 (aibot_msg_callback body)
```json
{
  "msgtype": "text",
  "chatid": "wrxxxxxx",
  "msgid": "xxx",
  "from": {"userid": "xxx"},
  "text": {"content": "@机器人 今日"}
}
```

### 回复消息 (aibot_respond_msg)
```json
{
  "cmd": "aibot_respond_msg",
  "body": {
    "msgtype": "stream",
    "stream": {
      "id": "<原始msgid>",
      "finish": true,
      "content": "回复内容（支持 markdown）"
    }
  }
}
```

## 项目中的具体实现

文件: `~/project/scripts/aibot_ws_client.py`

BOT_ID: `aibyWjiSqbfeqi4LIKYbmuTcqh936YDTkBW`
BOT_SECRET: `I4brkUa2HWaeRIJM5A34j1izv9t8iEcpLWGpm6x4YXb`

消息处理流程：
1. `on_msg_callback` → 提取 text.content
2. 检测是否包含 URL → 是则走 `_analyze_article_url()` (DeepSeek 分析)
3. 否则走 `bot_handler.process_message()` (指令处理)
4. 在后台线程执行，避免阻塞 WebSocket 心跳
5. `send_reply(msgid, result)` 返回 markdown

## 启动命令

```
cd ~/project/scripts
~/project/we-mp-rss-main源文件/we-mp-rss-main/venv/bin/python3 aibot_ws_client.py
```

## 重启命令

```
pkill -f aibot_ws_client.py
# wait 2s, then re-run start command
```
