在当今快节奏的工作环境中,高效的沟通和及时的信息传递对于团队的协作至关重要。而钉钉自定义机器人作为一种灵活、高效的消息通知工具,正逐渐受到企业和团队的青睐。通过钉钉自定义机器人,您可以轻松地实现系统监控告警、任务状态提醒、客服消息推送等功能。而要想使用钉钉自定义机器人发送消息,API和加签就是必不可少的工具。本文将带您深入了解如何通过API使用钉钉自定义机器人发送消息,并详细介绍如何进行加签操作,只需要简单的配置和调用,就能够轻松将钉钉自定义机器人引入到您的工作流程中,实现高效的消息通知和协作!以下分别提供了Node.js和php的示例代码。
1.添加群机器人
在群设置里添加自定义机器人,并进行安全设置。
安全设置分为自定义关键词,加签和设置白名单IP三种,可自行选择。
2.编写代码实现消息推送
(1)三种安全设置
- 自定义关键词:自定义关键词是一种将机器人的消息内容与特定关键词进行匹配的安全设置。只有当消息内容包含了指定的关键词,机器人才会将消息转发给接收方。这样做可以避免机器人收到无关信息或者垃圾信息。
- 加签:加签是一种对机器人发送消息进行数字签名的安全设置,它可以确保接收到的消息内容是由合法的机器人发送的。在机器人发送消息前,需要私钥对消息进行签名,接收到消息后使用公钥验证签名的合法性,以此来防止伪造或篡改消息。
- 设置白名单IP:设置白名单IP是一种限制接收方的IP地址的安全设置。只有来自指定IP地址的请求才能访问机器人,其他的请求将被拒绝。这种设置可以保证机器人只能被指定机器或者指定网络环境访问,提高机器人的安全性。
第一种和第三种很好理解,这里主要讲解如何使用加签的方式成功推送消息。
(2)加签
有关钉钉机器人的加签规则在官方文档中有介绍:自定义机器人安全设置文档
① 计算签名
首先把 timestamp+”\n”+密钥 作为签名字符串,使用HmacSHA256算法进行加密,然后转换为Base64,最后再把签名参数进行urlEncode,得到最终的签名(需要使用UTF-8字符集)。
const crypto = require('crypto'); getSign(str) { let hmac = crypto.createHmac('sha256', this.key); let encodeStr = hmac.update(str).digest().toString('base64'); return encodeURIComponent(encodeStr); } let sign = getSign(timestamp + "\n" + '填写自己的密钥');
② 拼接请求地址
把 timestamp 和上一步得到的签名值拼接到Webhook中:https://oapi.dingtalk.com/robot/send?access_token=XXXXXX×tamp=XXX&sign=XXX
let Webhook='填写自己的Webhook'; let url = `${Webhook}×tamp=${new Date().getTime()}&sign=${sign}`;
③ 发送请求
const axios = require('axios'); const response = await axios.post(url, { msgtype: 'markdown', markdown: { title, text: message }, }); if (!response.data.errcode) console.log('消息发送成功!'); else console.log('消息发送失败');
POST请求中的参数 msgtype 为消息的类型,支持五种类型分别为文本 (text)、链接 (link)、markdown(markdown)、ActionCard、FeedCard消息类型,可以根据自己的使用场景选择合适的消息类型。参数选项可以以下参考官方文档。
自定义机器人接入文档
④ 封装为消息类
Node.js示例代码如下:
const axios = require('axios'); const crypto = require('crypto'); class DingTalkMessenger { constructor() { this.Webhook ='填写自己的Webhook'; this.key = '填写自己的key'; } // 获取签名 getSign(str) { let hmac = crypto.createHmac('sha256', this.key); let encodeStr = hmac.update(str).digest().toString('base64'); return encodeURIComponent(encodeStr); } async sendDingTalkMessage(message,title) { try { let timestamp = new Date().getTime(); let sign = this.getSign(timestamp + "\n" + this.key); let url = `${this.Webhook}×tamp=${timestamp}&sign=${sign}`; const response = await axios.post(url, { msgtype: 'markdown', markdown: { title, text: message }, }); if (!response.data.errcode) console.log('消息发送成功!'); else console.log('消息发送失败'); } catch (error) { console.error('消息发送失败:', error); } } } // 测试发送 markdown语法 const message = "#### 武汉天气 \n > 9度,西北风1级,空气良89,相对温度73%\n > ![screenshot](https://img.alicdn.com/tfs/TB1NwmBEL9TBuNjy1zbXXXpepXa-2400-1218.png)\n > ###### 10点20分发布 [天气](https://www.dingtalk.com) \n"; const title="来自慕旋博客的一条消息"; const dingTalk = new DingTalkMessenger(); dingTalk.sendDingTalkMessage(message,title);
php示例代码如下:
<?php class DingTalkMessenger { private $Webhook; private $key; public function __construct() { $this->Webhook = '填写自己的Webhook'; $this->key = '填写自己的key'; } // 获取签名 private function getSign($str) { $hmac = hash_hmac('sha256', $str, $this->key, true); $encodeStr = base64_encode($hmac); return urlencode($encodeStr); } public function sendDingTalkMessage($message,$title) { try { $timestamp = time() * 1000; // 毫秒级时间戳 $sign = $this->getSign($timestamp . "\n" . $this->key); $url = "{$this->Webhook}×tamp={$timestamp}&sign={$sign}"; $data = [ 'msgtype' => 'markdown', 'markdown' => [ 'title' => "来自慕旋博客的一条消息", 'text' => $message, ], ]; $options = [ 'http' => [ 'header' => "Content-Type: application/json", 'method' => 'POST', 'content' => json_encode($data), ], ]; $context = stream_context_create($options); $result = file_get_contents($url, false, $context); if ($result === false) { echo "消息发送失败"; } else { echo "消息发送成功!"; } } catch (Exception $e) { echo "消息发送失败:" . $e->getMessage(); } } } $message = "#### 武汉天气 \n > 9度,西北风1级,空气良89,相对温度73%\n > ![screenshot](https://img.alicdn.com/tfs/TB1NwmBEL9TBuNjy1zbXXXpepXa-2400-1218.png)\n > ###### 10点20分发布 [天气](https://www.dingtalk.com) \n"; $title = "来自慕旋博客的一条消息"; $dingTalk = new DingTalkMessenger(); $dingTalk->sendDingTalkMessage($message,$title); ?>