# WorkTool 后端通信协议文档 本文档详细描述了 WorkTool 机器人(客户端)与后台服务器(服务端)之间的通信协议。 ## 1. 连接方式 WorkTool 使用 WebSocket 协议与服务端进行长连接通信。 * **WebSocket URL**: `ws://<服务器IP>:<端口>/webserver/wework/<链接号>` * `<链接号>` (robotId): 机器人的唯一标识,由用户在 APP 端设置。 * **通信格式**: JSON * **心跳机制**: 客户端每 5 秒发送一次心跳包 `{"type": 11}`,服务端可忽略或回复。 ## 2. 数据包结构 所有的通信数据(发送和接收)都包裹在 `WeworkMessageListBean` 结构中。 ### 2.1 外层包装 (WeworkMessageListBean) 服务端发送给客户端的 JSON 必须符合以下结构: ```json { "socketType": 2, // 消息类型:2 表示下发指令列表 "list": [ // 指令列表,可包含多个指令 { "type": 203, // 具体指令类型 (例如 203=发送消息) "messageId": "uuid", // 消息ID (可选,用于回调对应) ... // 指令参数 (详见下文) } ], "encryptType": 0 // 加密类型:0=不加密, 1=AES加密 (默认0) } ``` ### 2.2 消息确认 当客户端收到服务端消息后,会回复一个确认包(通常服务端不需要处理): ```json { "socketType": 1, // SOCKET_TYPE_MESSAGE_CONFIRM "messageId": "..." // 收到的消息ID } ``` ## 3. 常用指令详解 以下列出常用的指令及其 JSON 参数示例。参数放在 `list` 数组的对象中。 ### 3.1 发送文本消息 (SEND_MESSAGE) * **Type**: `203` * **说明**: 在指定房间(群或好友)发送文本。 ```json { "type": 203, "titleList": ["张三", "技术交流群"], // 接收者名称列表 (群名或好友名) "receivedContent": "你好,这是测试消息", // 消息内容 "at": "李四" // (可选) 需要 @ 的人昵称,仅在群聊有效 } ``` ### 3.2 转发消息 (RELAY_MESSAGE) * **Type**: `205` * **说明**: 将某人的消息转发给其他人。 ```json { "type": 205, "titleList": ["来源群名"], // 消息来源房间名 "receivedName": "张三", // 消息发送者昵称 "originalContent": "原消息内容", // 用于匹配消息内容 "textType": 1, // 消息类型 (1=文本, 2=图片, 详见附录) "nameList": ["目标群1", "李四"], // 转发目标列表 "extraText": "这是转发的消息" // (可选) 转发时的附加留言 } ``` ### 3.3 推送文件/图片 (PUSH_FILE) * **Type**: `218` * **说明**: 发送网络文件或图片。 ```json { "type": 218, "titleList": ["张三"], "objectName": "文件名.jpg", // 保存的文件名 "fileUrl": "http://example.com/a.jpg", // 文件下载地址 "fileType": "image", // 文件类型 (image, video, file) "extraText": "请查收图片" // (可选) 附加留言 } ``` ### 3.4 推送链接 (PUSH_LINK) * **Type**: `224` * **说明**: 发送卡片链接。 ```json { "type": 224, "titleList": ["张三"], "objectName": "百度一下", // 链接标题 "receivedContent": "你就知道", // 链接描述/副标题 "originalContent": "https://www.baidu.com", // 跳转链接 "fileUrl": "http://example.com/icon.png" // 链接图标地址 } ``` ### 3.5 获取最近聊天列表 (GET_RECENT_LIST) * **Type**: `505` * **说明**: 获取消息列表首页的最近聊天记录。 ```json { "type": 505 } ``` ### 3.6 获取群信息 (GET_GROUP_INFO) * **Type**: `501` * **说明**: 获取指定群的成员列表等信息。 ```json { "type": 501, "selectList": ["技术交流群"] // 要查询的群名列表 } ``` ## 4. 执行结果回调 当机器人执行完指令后,会向服务端发送执行结果。 * **SocketType**: `3` (SOCKET_TYPE_RAW_CONFIRM) * **数据结构**: ```json { "socketType": 3, "messageId": "原始指令的messageId", "list": [ { "errorCode": 0, // 0 表示成功,非 0 表示失败 "errorReason": "", // 失败原因 "successList": ["张三"], // 执行成功的对象列表 "failList": [], // 执行失败的对象列表 "rawMsg": "{...}", // 原始指令 JSON "runTime": 1670000000000, // 开始执行时间戳 "timeCost": 1.5 // 耗时 (秒) } ] } ``` ### 常见错误码 (ErrorCode) * `0`: 成功 * `201102`: 发送消息失败 * `201104`: 目标寻找失败 (未找到群或联系人) * `501000`: 其他未知错误 ## 附录:消息类型定义 (textType) * 1: 文本 (TEXT_TYPE_PLAIN) * 2: 图片 (TEXT_TYPE_IMAGE) * 3: 语音 (TEXT_TYPE_VOICE) * 5: 视频 (TEXT_TYPE_VIDEO) * 8: 链接 (TEXT_TYPE_LINK) * 9: 文件 (TEXT_TYPE_FILE) * 15: 引用回复 (TEXT_TYPE_REPLY) ## 附录:自动通过好友请求 当 APP 开启"自动通过好友请求"开关后,有新好友添加成功时会主动上传好友信息到服务端。 ### 上传时机 * 自动通过好友请求成功后 * 手动通过好友请求成功后 ### 消息类型 * **Type**: `502` (GET_FRIEND_INFO) ### 数据结构 ```json { "type": 502, "friend": { "name": "张三", // 好友昵称 "newFriend": true, // 标记为新好友 "wechatId": "zhangsan123", // 微信号 "phone": "13800138000", // 手机号 "corpName": "XX科技有限公司", // 企业名称 "department": "技术部", // 部门 "position": "工程师", // 职位 "email": "zhangsan@example.com", // 邮箱 "markName": "张工", // 备注名 "gender": 1, // 性别: 1男 2女 0未知 "leavingMsg": "请求添加好友时的留言" // 留言/验证消息 } } ``` ### 服务端接收示例 服务端只需监听 WebSocket 消息,当 `type=502` 且 `friend.newFriend=true` 时,表示有新好友添加成功。 --- ## 附录:接收消息列表 (101) 客户端监听到新消息时,会主动上传消息列表到服务端。 ### 消息类型 * **Type**: `101` (TYPE_RECEIVE_MESSAGE_LIST) ### 数据结构(群聊) ```json { "type": 101, "roomType": 1, "titleList": ["技术交流群"], "messageList": [ { "sender": 0, "textType": 1, "nameList": ["张三"], "itemMessageList": [ {"feature": 2, "text": "你好,这是消息内容"} ] }, { "sender": 1, "textType": 1, "itemMessageList": [ {"feature": 2, "text": "收到"} ] } ] } ``` ### 数据结构(单聊) ```json { "type": 101, "roomType": 2, "titleList": ["张三"], "contact": { "name": "张三", "wechatId": "zhangsan123", "phone": "13800138000", "corpName": "XX科技有限公司", "department": "技术部", "position": "工程师", "email": "zhangsan@example.com", "markName": "张工" }, "messageList": [ { "sender": 0, "textType": 1, "itemMessageList": [ {"feature": 2, "text": "你好"} ] } ] } ``` ### 字段说明 | 字段 | 类型 | 说明 | |------|------|------| | type | int | 消息类型:101=接收的消息列表 | | roomType | int | 房间类型:1=外部群, 2=外部联系人, 3=内部群, 4=内部联系人 | | titleList | Array | 聊天对象名称(群名或好友名) | | contact | Object | 联系人信息(仅单聊时有效) | | messageList | Array | 消息列表 | ### messageList 每条消息 | 字段 | 类型 | 说明 | |------|------|------| | sender | int | 发送者:0=其他人, 1=自己, 2=系统消息 | | textType | int | 消息类型:1=文本, 2=图片, 3=语音, 5=视频, 8=链接, 9=文件 | | nameList | Array | 发送者名称列表(群聊时有效) | | itemMessageList | Array | 消息内容列表 | ### contact 联系人信息 | 字段 | 类型 | 说明 | |------|------|------| | name | String | 好友昵称 | | wechatId | String | 微信号 | | phone | String | 手机号 | | corpName | String | 企业名称 | | department | String | 部门 | | position | String | 职位 | | email | String | 邮箱 | | markName | String | 备注名 | | gender | int | 性别:1=男, 2=女, 0=未知 |