钉钉Robot开发文档

发布于 2020-06-12  39 次阅读


钉钉群机器人定义

群机器人是钉钉群的高级扩展功能。群机器人可以将第三方服务的信息聚合到群聊中,实现自动化的信息同步。目前,大部分机器人在被添加后,还需要进行Webhook配置,才可正常使用(配置说明详见操作流程中的帮助链接)。

例如:

通过聚合GitHub,GitLab等源码管理服务,实现源码更新同步。

通过聚合Trello,JIRA等项目协调服务,实现项目信息同步。

另外,群机器人支持Webhook协议的自定义接入,支持更多可能性,例如:你可将运维报警通过自定义机器人聚合到钉钉群实现提醒功能。

机器人发送消息频率限制

消息发送太频繁会严重影响群成员的使用体验,大量发消息的场景(譬如系统监控报警)可以将这些信息进行整合,通过markdown消息以摘要的形式发送到群里。

  • 每个机器人每分钟最多发送20条。如果超过20条,会限流10分钟。

PC客户端配置入口

登录钉钉PC客户端(请升级至最新版),操作入口:

  • 左上角点击头像-进入“机器人管理”,可以对所有机器人进行统一管理。
  • 进入钉钉群-在右侧功能栏点击群设置-智能群助手,可以看到添加机器人的入口。点击“添加机器人”进入管理面板,可以进行添加、编辑和删除群机器人的操作。
image.png

手机客户端配置入口

登录钉钉手机端(请升级至最新版)-打开需要配置机器人的钉钉群-点击右上角群设置-点击智能群助手,进入智能群助手页面后,可以进行添加、编辑和删除群机器人的操作。

image.png
image.png

三方系统事件通知到钉钉聊天群

概述

高效的团队往往会充分利用不同的工具来提升自己的工作效率,譬如通过钉钉进行沟通协同,使用Trello进行任务管理,使用GitLab或者GitHub来进行代码管理,使用JIRA来进行项目与事务跟踪等等。不同的工具分工合作,把团队的事务数字化管理流转起来,并在一定程度上实现了流程的自动化,将大家从一些繁琐的事务中解放出来,有效地提升了大家的协同能力和工作质量。

不过,随着工具的增多,大家的关注点也会逐步分散,不能及时响应工具里面事项的状态变更。慢慢地,各种团队协同工具逐渐变为个人的管理工具,导致团队整体的协同效率下降。

幸运的是,当前很多工具都保持着一种开放的态度,将系统中各种事件以标准的方式 (Webhook) 提供出来。我们只要结合钉钉的群机器人的能力,无需编写任何代码,只需要简单的几步配置,就可以将这些事件集成到钉钉上,体验一站式的办公协同环境。这些系统将事件发送到钉钉群聊,既能帮助大家及时感知到事件状态的变化,也方便大家在群里面围绕这个事件进行及时的沟通,一举两得。

以钉钉研发团队为例,我们每个研发小组都会在自己的群里面配置上GitLab机器人,将自己项目的代码提交记录(主要是push和merge事件)实时同步到群里。

image.png

模块的负责人看到后,知道模块的代码已经被修改了,可以点击消息卡片中的链接,马上进入到GitLab页面中看到对应的代码变动,进行代码review。

当然,项目负责人从大家提交代码的频度和时间点上,也能感知到项目的大概进展情况。如果看到开发同学凌晨还在不停地提交代码,除了发个红包鼓励下之外,需要马上找到开发负责人寻求开发资源上的支持了。

当前,钉钉支持接入的三方系统有GitHub,GitLab,JIRA,Travis和Trello(正在努力持续增加中),大家可以结合自己团队的使用习惯将合适的事件集成到钉钉上。

GitLab机器人

生成GitLab机器人webhook

进入到机器人管理页面,选择GitLab机器人,生成GitLab机器人,可获取到相应群的webhook,其格式如下:

https://oapi.dingtalk.com/robot/send?access_token=xxxxxxxx

在GitLab中设置项目的webhook

  • 进入你的 GitLab 项目,依次点击左侧「Settings」-->「Webhooks 」来添加 Webhook
  • 填入Webhook地址

GitHub机器人

生成GitHub机器人webhook

进入到机器人管理页面,选择GitHub机器人,生成GitHub机器人,可获取到相应群的webhook,其格式如下:

https://oapi.dingtalk.com/robot/send?access_token=xxxxxxxx

在GitHub中设置项目的webhook

  • 进入 GitHub 代码库,依次点击「Settings」、「Webhooks & Services」、「Add Webhook」
  • 填入对应的Webhook地址,完成配置

JIRA机器人

生成JIRA机器人webhook

进入到机器人管理页面,选择“JIRA机器人”,生成JIRA机器人,可获取到相应群的webhook,其格式如下:

https://oapi.dingtalk.com/robot/send?access_token=xxxxxxxx

在JIRA中设置项目的webhook

在JIRA系统中,通过 [设置] -> [System] -> [Webhooks] 进入webhook设置页面,为相应的项目设置钉钉群机器人的webhook,具体操作如下图所示:

  • 点击[System] 菜单
  • 选择[Webhooks]设置项
  • 新增项目WebHook,并填写上钉钉群聊天机器人webhook

Travis机器人

生成Travis机器人webhook

进入到机器人管理页面,选择“Travis机器人”,生成Travis机器人,可获取到相应群的webhook,其格式如下:

https://oapi.dingtalk.com/robot/send?access_token=xxxxxxxx

配置Travis的项目配置文件

将如下内容添加到 .travis.yml 文件中即可完成配置

notifications:   webhooks: https://oapi.dingtalk.com/robot/send?access_token=xxxxxxxx

阿里云Code机器人

生成阿里云Code机器人webhook

进入到机器人管理页面,选择“阿里云Code机器人”,生成阿里云Code机器人,可获取到相应群的webhook,其格式如下:

https://oapi.dingtalk.com/robot/send?access_token=xxxxxxxx

在阿里云Code中设置项目的webhook

进入项目,依次点击左侧「设置」,进入设置页面,然后点击「Web钩子 」填入生成的Webhook,并勾选感兴趣的事件,即可完成设置。

Trello机器人

授权钉钉访问Trello账户

进入到机器人管理页面,选择“Trello机器人”,按照流程登入Trello完成授权即可。

若还没有账号和密码,进入到 https://trello.com/ 第三方网站进行注册

其中选择的看板list与在 https://trello.com/ 上添加的看板数据同步。

自研系统事件通知到钉钉聊天群

企业内部有较多系统支撑着公司的核心业务流程,譬如CRM系统、交易系统、监控报警系统等等。通过钉钉的自定义机器人,可以将这些系统事件同步到钉钉的聊天群。

以钉钉团队的使用场景为例,通过自定义机器人,我们将系统检测出来的业务异常报警通知到钉钉的值班群,让值班同学及时感知到异常事件的发生,快速响应。相比于传统的短信报警,钉钉消息报警不仅内容上更为详细,样式上也更为美观,而且钉钉消息上可以直接带上详情的链接,值班同学在PC上通过点击即可快速查看详情。

image.png

要完成这个功能,只需要监控系统将之前发送短信的逻辑,修改为通过HTTP发送到指定URL地址(也就是群机器人的webhook)即可。

通过钉钉的自定义机器人,也可以实现很多功能,譬如:

(1)预案平台的预案执行完毕后,通过钉钉机器人将预案的相关信息和状态同步到群里;

(2)故障处理平台将故障的处理过程实时同步到钉钉群;

(3)数据分析团队的分析任务完成后,会通过钉钉机器人将结果发送到群里,并通过消息的@功能提醒需求方。

获取自定义机器人webhook

步骤一,打开机器人管理页面。以PC端为例,打开PC端钉钉,点击头像,选择“机器人管理”。

image.png

步骤二,在机器人管理页面选择“自定义”机器人,输入机器人名字并选择要发送消息的群,同时可以为机器人设置机器人头像。

屏幕快照 2019-10-25 下午1.50.45.png

步骤三,完成必要的安全设置(至少选择一种),勾选 我已阅读并同意《自定义机器人服务及免责条款》,点击“完成”。安全设置目前有3种方式,设置说明见下文介绍。

image.png

步骤四,完成安全设置后,复制出机器人的Webhook地址,可用于向这个群发送消息,格式如下:

https://oapi.dingtalk.com/robot/send?access_token=XXXXXX

注意:请保管好此Webhook 地址,不要公布在外部网站上,泄露后有安全风险。

安全设置

安全设置目前有3种方式:

(1)方式一,自定义关键词

最多可以设置10个关键词,消息中至少包含其中1个关键词才可以发送成功。

例如:添加了一个自定义关键词:监控报警

则这个机器人所发送的消息,必须包含 监控报警 这个词,才能发送成功。

(2)方式二,加签

第一步,把timestamp+"\n"+密钥当做签名字符串,使用HmacSHA256算法计算签名,然后进行Base64 encode,最后再把签名参数再进行urlEncode,得到最终的签名(需要使用UTF-8字符集)。

参数说明
timestamp当前时间戳,单位是毫秒,与请求调用时间误差不能超过1小时
secret密钥,机器人安全设置页面,加签一栏下面显示的SEC开头的字符串

签名计算代码

#python 3.8 
import time
import hmac
import hashlib
import base64
import urllib.parse

timestamp = str(round(time.time() * 1000))
secret = 'this is secret'
secret_enc = secret.encode('utf-8')
string_to_sign = '{}\n{}'.format(timestamp, secret)
string_to_sign_enc = string_to_sign.encode('utf-8')
hmac_code = hmac.new(secret_enc, string_to_sign_enc, digestmod=hashlib.sha256).digest()
sign = urllib.parse.quote_plus(base64.b64encode(hmac_code))
print(timestamp)
print(sign)

第二步,把 timestamp和第一步得到的签名值拼接到URL中。

参数说明
timestamp第一步使用到的时间戳
sign第一步得到的签名值

(3)方式三,IP地址(段)

设定后,只有来自IP地址范围内的请求才会被正常处理。支持两种设置方式:IP、IP段,暂不支持IPv6地址白名单,格式如下:

image.png

注意:安全设置的上述三种方式,需要至少设置其中一种,以进行安全保护。校验不通过的消息将会发送失败,错误如下:

// 消息内容中不包含任何关键词
{
  "errcode":310000,
  "errmsg":"keywords not in content"
}

// timestamp 无效
{
  "errcode":310000,
  "errmsg":"invalid timestamp"
}

// 签名不匹配
{
  "errcode":310000,
  "errmsg":"sign not match"
}

// IP地址不在白名单
{
  "errcode":310000,
  "errmsg":"ip X.X.X.X not in whitelist"
}

使用自定义机器人

(1)获取到Webhook地址后,用户可以向这个地址发起HTTP POST 请求,即可实现给该钉钉群发送消息。注意,发起POST请求时,必须将字符集编码设置成UTF-8。

(2)当前自定义机器人支持文本 (text)、链接 (link)、markdown(markdown)、ActionCard、FeedCard消息类型,大家可以根据自己的使用场景选择合适的消息类型,达到最好的展示样式。

(3)自定义机器人发送消息时,可以通过手机号码指定“被@人列表”。在“被@人列表”里面的人员收到该消息时,会有@消息提醒(免打扰会话仍然通知提醒,首屏出现“有人@你”)。

(4)当前机器人尚不支持应答机制 (该机制指的是群里成员在聊天@机器人的时候,钉钉回调指定的服务地址,即Outgoing机器人)。

SDK :

可以下载SDK,简化调用方式。

消息发送频率限制:

每个机器人每分钟最多发送20条。消息发送太频繁会严重影响群成员的使用体验,大量发消息的场景 (譬如系统监控报警) 可以将这些信息进行整合,通过markdown消息以摘要的形式发送到群里。

测试自定义机器人

通过下面方法,可以快速验证自定义机器人是否可以正常工作:

使用命令行工具curl。

为避免出错,将以下命令逐行复制到命令行,需要将xxxxxxxx替换为真实access_token;若测试出错,请检查复制的命令是否和测试命令一致,多特殊字符会报错。

curl 'https://oapi.dingtalk.com/robot/send?access_token=xxxxxxxx' \
   -H 'Content-Type: application/json' \
   -d '{"msgtype": "text","text": {"content": "我就是我, 是不一样的烟火"}}'

消息类型及数据格式

text类型

{
    "msgtype": "text", 
    "text": {
        "content": "我就是我, 是不一样的烟火@156xxxx8827"
    }, 
    "at": {
        "atMobiles": [
            "156xxxx8827", 
            "189xxxx8325"
        ], 
        "isAtAll": false
    }
}
参数参数类型必须说明
msgtypeString消息类型,此时固定为:text
contentString消息内容
atMobilesArray被@人的手机号(在content里添加@人的手机号)
isAtAllBoolean是否@所有人

link类型

{
    "msgtype": "link", 
    "link": {
        "text": "这个即将发布的新版本,创始人xx称它为红树林。而在此之前,每当面临重大升级,产品经理们都会取一个应景的代号,这一次,为什么是红树林", 
        "title": "时代的火车向前开", 
        "picUrl": "", 
        "messageUrl": "https://www.dingtalk.com/s?__biz=MzA4NjMwMTA2Ng==&mid=2650316842&idx=1&sn=60da3ea2b29f1dcc43a7c8e4a7c97a16&scene=2&srcid=09189AnRJEdIiWVaKltFzNTw&from=timeline&isappinstalled=0&key=&ascene=2&uin=&devicetype=android-23&version=26031933&nettype=WIFI"
    }
}
参数参数类型必须说明
msgtypeString消息类型,此时固定为:link
titleString消息标题
textString消息内容。如果太长只会部分展示
messageUrlString点击消息跳转的URL
picUrlString图片URL
image.png

markdown类型

{
     "msgtype": "markdown",
     "markdown": {
         "title":"杭州天气",
         "text": "#### 杭州天气 @150XXXXXXXX \n> 9度,西北风1级,空气良89,相对温度73%\n> ![screenshot](https://img.alicdn.com/tfs/TB1NwmBEL9TBuNjy1zbXXXpepXa-2400-1218.png)\n> ###### 10点20分发布 [天气](https://www.dingalk.com) \n"
     },
      "at": {
          "atMobiles": [
              "150XXXXXXXX"
          ],
          "isAtAll": false
      }
 }
参数类型必选说明
msgtypeString此消息类型为固定markdown
titleString首屏会话透出的展示内容
textStringmarkdown格式的消息
atMobilesArray被@人的手机号(在text内容里要有@手机号)
isAtAllBoolean是否@所有人

说明:目前只支持md语法的子集,具体支持的元素如下:

标题
# 一级标题
## 二级标题
### 三级标题
#### 四级标题
##### 五级标题
###### 六级标题

引用
> A man who stands for nothing will fall for anything.

文字加粗、斜体
**bold**
*italic*

链接
[this is a link](http://name.com)

图片
![](http://name.com/pic.jpg)

无序列表
- item1
- item2

有序列表
1. item1
2. item2

整体跳转ActionCard类型

{
    "actionCard": {
        "title": "乔布斯 20 年前想打造一间苹果咖啡厅,而它正是 Apple Store 的前身", 
        "text": "![screenshot](https://gw.alicdn.com/tfs/TB1ut3xxbsrBKNjSZFpXXcXhFXa-846-786.png) 
 ### 乔布斯 20 年前想打造的苹果咖啡厅 
 Apple Store 的设计正从原来满满的科技感走向生活化,而其生活化的走向其实可以追溯到 20 年前苹果一个建立咖啡馆的计划", 
        "btnOrientation": "0", 
        "singleTitle" : "阅读全文",
        "singleURL" : "https://www.dingtalk.com/"
    }, 
    "msgtype": "actionCard"
}
参数类型必须说明
msgtypeString此消息类型为固定actionCard
titleString首屏会话透出的展示内容
textStringmarkdown格式的消息
singleTitleString单个按钮的标题。(设置此项和singleURL后btns无效)
singleURLString点击singleTitle按钮触发的URL
btnOrientationString0-按钮竖直排列,1-按钮横向排列

通过整体跳转ActionCard类型消息发出的消息样式如下:

独立跳转ActionCard类型

{
    "actionCard": {
        "title": "乔布斯 20 年前想打造一间苹果咖啡厅,而它正是 Apple Store 的前身", 
        "text": "![screenshot](https://gw.alicdn.com/tfs/TB1ut3xxbsrBKNjSZFpXXcXhFXa-846-786.png) 
 ### 乔布斯 20 年前想打造的苹果咖啡厅 
 Apple Store 的设计正从原来满满的科技感走向生活化,而其生活化的走向其实可以追溯到 20 年前苹果一个建立咖啡馆的计划", 
        "btnOrientation": "0", 
        "btns": [
            {
                "title": "内容不错", 
                "actionURL": "https://www.dingtalk.com/"
            }, 
            {
                "title": "不感兴趣", 
                "actionURL": "https://www.dingtalk.com/"
            }
        ]
    }, 
    "msgtype": "actionCard"
}
参数类型必须说明
msgtypeString此消息类型为固定actionCard
titleString首屏会话透出的展示内容
textStringmarkdown格式的消息
btnsArray按钮
└titleString按钮标题
└actionURLString点击按钮触发的URL
btnOrientationString0-按钮竖直排列,1-按钮横向排列

通过独立跳转ActionCard类型消息发出的消息样式如下:

image.png

FeedCard类型

{
    "feedCard": {
        "links": [
            {
                "title": "时代的火车向前开", 
                "messageURL": "https://www.dingtalk.com/s?__biz=MzA4NjMwMTA2Ng==&mid=2650316842&idx=1&sn=60da3ea2b29f1dcc43a7c8e4a7c97a16&scene=2&srcid=09189AnRJEdIiWVaKltFzNTw&from=timeline&isappinstalled=0&key=&ascene=2&uin=&devicetype=android-23&version=26031933&nettype=WIFI", 
                "picURL": "https://gw.alicdn.com/tfs/TB1ayl9mpYqK1RjSZLeXXbXppXa-170-62.png"
            },
            {
                "title": "时代的火车向前开2", 
                "messageURL": "https://www.dingtalk.com/s?__biz=MzA4NjMwMTA2Ng==&mid=2650316842&idx=1&sn=60da3ea2b29f1dcc43a7c8e4a7c97a16&scene=2&srcid=09189AnRJEdIiWVaKltFzNTw&from=timeline&isappinstalled=0&key=&ascene=2&uin=&devicetype=android-23&version=26031933&nettype=WIFI", 
                "picURL": "https://gw.alicdn.com/tfs/TB1ayl9mpYqK1RjSZLeXXbXppXa-170-62.png"
            }
        ]
    }, 
    "msgtype": "feedCard"
}
参数类型必须说明
msgtypeString此消息类型为固定feedCard
titleString单条信息文本
messageURLString点击单条信息到跳转链接
picURLString单条信息后面图片的URL

通过FeedCard类型消息发出的消息样式如下:


若金色的阳光停止了它耀眼的光芒,你的一个微笑,将照亮我的整个世界