自定义机器人使用指南
自定义机器人添加入口
- 在群聊中点击右上角的「···」图标,点击群机器人;
- 点击添加 webhook 机器人;
- 填写机器人名称和简介,即可添加自定义机器人到群聊中。

如何使用自定义机器人
- 在终端某个群组添加机器人之后,可以获取到 webhook 地址,然后开发者用户按以下说明构造 post data 向这个地址发起 HTTP POST 请求,即可实现给该群组发送消息
- webhook 格式是:https://xz.wps.cn/api/v1/webhook/send?key=xxxxxxx
- 特别特别要注意:一定要保护好机器人的 webhook 地址,避免泄漏!不要分享到 github、博客等可被公开查阅的地方,否则坏人就可以用你的机器人来发垃圾消息了
相关限制
- 消息发送频率限制:每个机器人发送的消息不能超过 20 条/分钟
- 消息内容阈值:每条消息不超过 5000 个字符
文本类型
参数说明
| 参数 | 是否必填 | 说明 |
|---|---|---|
| msgtype | 是 | 消息类型。text-表示文本类型 |
| text | 是 | 文本消息 |
| ∟ content | 是 | 消息内容 |
支持通过在消息体 content 中插入<at>标签的方式@人,如果不填写姓名,则服务端将自动填充姓名至@人位置:
- 使用 id@人:<at user_id="12345">姓名</at>
- 使用 email@人:<at email="somebody@wps.cn">姓名</at>
- @所有人:<at user_id="-1">所有人</at>
代码示例
{
- "msgtype":"text",
- "text":{
- "content":"每日数据监控报告:\n今日数据统计结果请相关同事注意<at user_id=\"17856\">李三</at><at user_id=\"-1\">所有人</at>"
- }
-}
-展示示例

Markdown 类型
参数说明
| 参数 | 是否必填 | 说明 |
|---|---|---|
| msgtype | 是 | 消息类型 |
| markdown | 是 | markdown 消息 |
| ∟ text | 是 | 消息内容 |
代码示例
{
- "msgtype": "markdown",
- "markdown": {
- "text":"## KAE监控报警\n\n报警内容:网关入口\n\n> 备注:严重程度中等"
- }
-}
-展示示例

说明:目前只支持 md 语法的子集,具体支持的元素如下(换行可以使用“双空格+\n”或“\n\n”方式),不同语法之间的组合(颜色+标题等)。
| 名称 | 语法 | 说明 |
|---|---|---|
| @人 | 使用 id@人:<at user_id="12345">姓名</at> 使用 email@人:<at email="somebody@wps.cn">姓名</at> @所有人:<at user_id="-1">所有人</at> | / |
| 标题 | # 一级标题 ## 二级标题 ### 三级标题 #### 四级标题 ##### 五级标题 ###### 六级标题 | / |
| 引用 | > 引用内容 | / |
| 加粗 | **加粗** | 如移动端显示有问题可尝试在后面加空格 |
| 颜色 | <font color='#FF0000'>颜色</font> <font color='red'>颜色</font> | 支持使用十六进制颜色值或对应颜色的英文表示 |
| 斜体 | *斜体* _斜体_ | / |
| 删除线 | ~~删除线~~ | / |
| 链接 | <链接地址> [链接名称](链接地址) | / |
| 有序列表 | 1. 内容 1 2. 内容 2 | / |
| 无序列表 | - 内容 1 - 内容 2 | / |
| 图片 |  | / |
链接类型
参数说明
| 参数 | 是否必填 | 说明 |
|---|---|---|
| msgtype | 是 | 消息类型。link-表示链接类型 |
| title | 是 | 标题内容 |
| text | 是 | markdown 格式的消息。换行可以使用“双空格+\n”或“\n\n”方式。 |
| messageUrl | 否 | 跳转 url |
| btnTitle | 否 | 按钮标题,默认为“查看详情”,长度限制 12 个字符 |
代码示例
{
- "msgtype": "link",
- "link": {
- "title": "日程提醒",
- "text": "需求评审会将于15分钟后开始↵2F-201会议室",
- "messageUrl": "https://kdocs.cn",
- "btnTitle": "查看详情"
- }
-}
-展示示例

卡片类型
参数说明
| 参数 | 是否必填 | 说明 |
|---|---|---|
| msgtype | 是 | 消息类型。card-表示卡片类型 |
| card | 是 | 卡片消息,具体内容见搭建卡片消息,备注:目前 webhook 不支持回传型交互组件, 包括回传型按钮、列表选择器、日期选择器、输入框 |
代码示例
{
- "msgtype":"card",
- "card":{
- "header":{
- "title":{
- "tag":"text",
- "content":{
- "type":"plainText",
- "text":"标题"
- }
- },
- "subtitle":{
- "tag":"text",
- "content":{
- "type":"plainText",
- "text":"副标题"
- }
- }
- },
- "elements":[
- {
- "tag":"text",
- "content":{
- "type":"markdown",
- "text":"普通文本"
- }
- }
- ],
- "i18n":{
- "zh-TW":{
- "header":{
- "title":{
- "tag":"text",
- "content":{
- "type":"plainText",
- "text":"標題"
- }
- },
- "subtitle":{
- "tag":"text",
- "content":{
- "type":"plainText",
- "text":"副標題"
- }
- }
- },
- "elements":[
- {
- "tag":"text",
- "content":{
- "type":"markdown",
- "text":"普通文本"
- }
- }
- ]
- },
- "en-US":{
- "header":{
- "title":{
- "tag":"text",
- "content":{
- "type":"plainText",
- "text":"title"
- }
- },
- "subtitle":{
- "tag":"text",
- "content":{
- "type":"plainText",
- "text":"sub title"
- }
- }
- },
- "elements":[
- {
- "tag":"text",
- "content":{
- "type":"markdown",
- "text":"common text"
- }
- }
- ]
- }
- }
- }
-}
-展示示例

自定义机器人添加 callback
机器人添加 callback

callback 可用性校验
创建者在输入框中输入 url,点击保存。服务端会对该地址进行一次 GET 请求,例如:
[GET] https://xz.wps.cn/api/v1/test
第三方收到请求后返回以下 response 数据即可:
{"result":"ok"}
-即代表该请求可用。
callback 发送消息
当群聊中用户 at 创建者所配置的 webhook 机器人时,服务端会把该条 at 消息通过 POST 请求发送给第三方,例如:
[POST] https://xz.wps.cn/api/v1/test
请求参数
| 参数 | 类型 | 位置 | 说明 |
|---|---|---|---|
| chatid | int64 | body | 会话 id |
| creator | int64 | body | 发送者 id |
| content | string | body | 内容 |
| reply | object | body | 回复内容 |
| robot_key | string | body | 机器人 key |
| url | string | body | callback 地址创建者所填的 url 地址 |
| ctime | int64 | body | 发送时间 |
| 参数 reply | 类型 | 位置 | 说明 |
|---|---|---|---|
| reply_content | string | body | 回复内容 |
| reply_creator | int64 | body | 回复消息发送者 id |
请求参数示例
{
- "chatid": 12345,
- "creator": 2324234,
- "content": "@webhook机器人 111",
- "reply": {
- "reply_content": "回复内容",
- "reply_creator": 1234
- },
- "robot_key": "xxx",
- "url": "https://xxxx",
- "ctime": 3452452
-}
-返回结果示例
{"result":"ok"}
-自定义机器人安全设置
如果开发者未保管好 webhook 地址,可能存在地址泄漏后被恶意用来发送垃圾信息的风险,建议开发者至少选择配置一个安全设置。
自定义关键词
设置后,发送的消息需包含至少一个关键词,最多设置 10 个关键词。
示例:设置了关键词:报警、告警后,通过 webhook 机器人发送的消息需带有至少一个关键词,才可以发送成功。
IP 白名单
设置后,只处理来自 IP 白名单地址范围内的请求,最多设置 10 个 IP 地址/地址段,如:192.168.1.1 或 192.168.1.1/24 或 192.168.1.*。
签名校验
设置后,发送请求时需要签名验证来保障信息来源可信。
- 用户可以在 HTTP Header 中包含签名 (Authorization)。
- 签名头 (Authorization)验证码计算方法如下:Authorization:" key + ":" + sha1( secret_key + Content-Md5 + Content-Type + DATE)。
注意: HTTP Header 中必须包含以下字段
- Content-Md5 HTTP Body 中数据的 md5 值十六进制表达方式, 必需小写。
- Content-Type 目前固定为: application/json。
- DATE 取当前时间, 格式: Wed, 23 Jan 2013 06:43:08 GMT,签名默认有效时间为 15 分钟。
- Authorization 上面所说的签名头。
特权用户设置
设置后,只有群主、管理员和 webhook 机器人的添加者,可以编辑或移除此机器人。

完整 HTTP 实例
Header
POST https://xz.wps.cn/api/v1/webhook/send
-Content-Md5: d41d8cd98f00b204e9800998ecf8427e
-Content-Type: application/json
-DATE: Wed, 19 Oct 2021 02:16:08 GMT
-Authorization:63840ea636369968f9e0de63c0ee02a1:2b9725f94fcf45216edb5392fa540e2083c25b6f
-go 示例代码
var calcContentMD5 string
- // 检查Date是否超过15分钟
- dateTime, err := time.Parse(layout, webhookSendRequest.Date)
- if err != nil {
- return robot.ErrWebhookSendByTimestamp
-
- }
- deltaTime := time.Now().Sub(dateTime)
- if deltaTime < -15*time.Minute || deltaTime > 15*time.Minute {
- return robot.ErrWebhookSendByTimestamp
-
- }
-
- // 检查Content-Md5
- contentMD5Array := md5.Sum(webhookSendRequest.Content)
- calcContentMD5 = hex.EncodeToString(contentMD5Array[:])
- if webhookSendRequest.ContentMD5 != calcContentMD5 {
- return robot.ErrWebhookSendBySign
- }
-
- //获取sign
- splits := strings.Split(webhookSendRequest.Auth, ":")
- if len(splits) != 2 {
- return robot.ErrWebhookSendBySign
-
- }
- // 计算签名
- str := secretKey + webhookSendRequest.ContentMD5 + webhookSendRequest.ContentType + webhookSendRequest.Date
- sigBytes := sha1.Sum([]byte(str))
- sig := hex.EncodeToString(sigBytes[:])
- if sig != splits[1] {
- return robot.ErrWebhookSendBySign
- }
-