npm package: @inventorjs/wecom-bot-server
Description: 企业微信机器人回调服务框架 - Node.js 版本
Latest version: 0.0.15

# 企业微信机器人服务框架 - Node.js 版本

基于 Express 的企业微信群机器人回调功能接口服务框架，功能完整复刻 Python 版本 [wecom-bot-svr](https://github.com/easy-wx/wecom-bot-svr)。

## ✨ 特性

- 🤖 **完整功能**：支持企业微信群机器人所有回调功能
- 🔐 **消息加解密**：内置 AES-256-CBC 加解密，保证消息安全
- 📤 **主动发送**：支持主动发送文本、Markdown、文件、图片、图文消息
- 🎯 **事件处理**：支持进群、退群等事件回调
- 🛠️ **灵活扩展**：底层封装与业务逻辑严格分离，易于定制
- 🚀 **开箱即用**：纯 JavaScript 实现，无需编译，直接运行
- 📦 **轻量依赖**：仅依赖少量优质第三方包

## 项目结构

```
wecom-bot-server/
├── lib/                      # 核心框架层（底层封装）
│   ├── index.js             # 包导出
│   ├── server.js            # WecomBotServer 核心类
│   ├── crypto.js            # 消息加解密模块
│   ├── req-msg.js           # 请求消息类
│   └── rsp-msg.js           # 响应消息类
├── demo/                   # 完整示例
├── package.json              # 项目配置
└── README.md                 # 项目文档
```

## 📦 安装

### 使用 pnpm（推荐）

```bash
pnpm install @inventorjs/wecom-bot-server
```

### 1. 配置企业微信机器人

1. 在企业微信群中添加机器人
2. 进入机器人配置页面
3. 配置回调地址：`http://your-domain:9001/wecom-bot`
4. 获取以下配置信息：
   - **Token**：3个字符的固定值
   - **AES Key**：43个字符的固定值
   - **Webhook Key**：从 Webhook URL 中获取（用于主动发送消息）

### 4. 在群里@机器人测试

- 发送 `@机器人 help` - 查看帮助
- 发送 `@机器人 ping` - 测试响应
- 发送 `@机器人 info` - 查看机器人信息

## 📖 使用指南

### 使用示例
> 正常只需要 new WecomBotServer() 即可，如果需要接收事件回调，则 自行实现 `messageHandler` 和 `messageHandler`

### 自定义消息处理

```javascript
import { RspTextMsg, RspMarkdownMsg, TextReqMsg } from '@inventorjs/wecom-bot-server';

export async function messageHandler(reqMsg, server) {
  // 文本消息处理
  if (reqMsg instanceof TextReqMsg) {
    const content = reqMsg.content.trim();
    
    // 自定义命令
    if (content === 'hello') {
      const rsp = new RspTextMsg();
      rsp.content = 'Hello! 👋';
      return rsp;
    }
    
    // Markdown 响应
    if (content === 'markdown') {
      const rsp = new RspMarkdownMsg();
      rsp.content = '## 标题\n**粗体** *斜体*';
      return rsp;
    }
    
    // 发送文件
    if (content === 'file') {
      await server.sendFile(reqMsg.chatId, '/path/to/file.txt');
      return new RspTextMsg(); // 返回空响应
    }
  }
  
  // 默认响应
  const rsp = new RspTextMsg();
  rsp.content = '收到消息';
  return rsp;
}
```

### 自定义事件处理

```javascript
import { EventReqMsg, RspMarkdownMsg } from '@inventorjs/wecom-bot-server';

export async function eventHandler(reqMsg) {
  const rsp = new RspMarkdownMsg();
  
  switch (reqMsg.eventType) {
    case 'add_to_chat':
      rsp.content = '欢迎使用机器人！';
      break;
    
    case 'delete_from_chat':
      rsp.content = '再见！';
      break;
    
    default:
      rsp.content = `事件: ${reqMsg.eventType}`;
  }
  
  return rsp;
}
```

### WecomBotServer

#### 构造函数

```javascript
const server = new WecomBotServer({
  name: '机器人名称',
  host: '0.0.0.0',
  port: 9001,
  path: '/wecom-bot', // 这里和 机器人配置的回调地址保持一致
  activeMsgPath: '/active-send',

  // 推荐从环境变量获取
  token: 'xxx',
  aesKey: 'xxx',
  botKey: 'xxx'

  handlers: {
    messageHandler,
    eventHandler,
    errorHandler: (err) => console.error(err)
  },
});
```

#### 主动发送消息

```javascript
// 发送文本
await server.sendText('文本内容', ['@用户ID'], ['@手机号']);

// 发送 Markdown
await server.sendMarkdown('## 标题\n内容');

// 发送文件
await server.sendFile('/path/to/file.txt');

// 发送图片Base64
await server.sendEncodedImage(base64Data, md5);

// 发送图片文件
await server.sendImage('/path/to/file.txt');

// 发送图文
await server.sendNews('标题', '描述', 'url', 'picUrl');
```

### 消息类型

#### 请求消息

- `ReqMsg` - 消息基类
- `TextReqMsg` - 文本消息
- `ImageReqMsg` - 图片消息
- `EventReqMsg` - 事件消息
- `AttachmentReqMsg` - 附件消息
- `MixedMessageReqMsg` - 混合消息

#### 响应消息

- `RspMsg` - 响应基类
- `RspTextMsg` - 文本响应
- `RspMarkdownMsg` - Markdown 响应

## 🔌 HTTP API

### 主动发送消息接口

**POST** `/active_send`

**安全限制**：仅接受本地 IP（127.0.0.1）请求

#### 发送文本消息

```bash
curl -X POST http://127.0.0.1:9001/active-send \
  -d "msg_type=text" \
  -d "chat_id=群ID" \
  -d "content=Hello World"
```

#### 发送 Markdown 消息

```bash
curl -X POST http://127.0.0.1:9001/active-send \
  -d "msg_type=markdown" \
  -d "chat_id=群ID" \
  -d "content=## 标题"
```

#### 发送文件

```bash
curl -X POST http://127.0.0.1:9001/active-send \
  -d "msg_type=file" \
  -d "chat_id=群ID" \
  -d "file_path=/path/to/file.txt"
```

## 📝 消息处理流程

```
企业微信群 → POST /wecom_bot (加密XML)
    ↓
解密消息 → 解析为 ReqMsg 对象
    ↓
根据类型调用处理器 (messageHandler / eventHandler)
    ↓
返回 RspMsg 对象 → 转换为XML → 加密
    ↓
企业微信群 ← 显示机器人回复
```

## ❓ 常见问题

### 1. 如何获取 Token 和 AES Key？

在企业微信群机器人配置页面，点击"随机生成"按钮即可获取。

### 2. 如何获取 Webhook Key？

在企业微信群机器人配置页面，Webhook URL 格式为：
```
https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
```
其中 `key=` 后面的部分就是 Webhook Key。

### 3. 群消息必须 @机器人吗？

是的，在群聊中需要 @机器人 才会触发回调。单聊则不需要。

### 4. 如何发送文件？

需要配置 `botKey`，然后调用 `server.sendFile()` 方法。

### 5. 支持哪些消息类型？

- 文本消息（text）
- 图片消息（image）
- 事件消息（event）
- 附件消息（attachment）
- 混合消息（mixed）

## 🤝 贡献

欢迎提交 Issue 和 Pull Request！

## 📄 许可证

MIT License

## 🙏 致谢

本项目基于 Python 版本 [wecom-bot-svr](https://github.com/easy-wx/wecom-bot-svr) 的功能设计，使用 Node.js 完整实现。

## 📮 联系方式

如有问题，请提交 Issue。