一、接入机器人

1.进入智能群助手

钉钉 javasdk 机器人 php 钉钉机器人_SSL

 2.添加机器人

钉钉 javasdk 机器人 php 钉钉机器人_SSL_02

3.选择自定义:通过webhook接入自定义服务

钉钉 javasdk 机器人 php 钉钉机器人_SSL_03

 4.设置关键字或加签:

设置关键字后:发送内容中包含设置的关键字之一才会发送成功

加签:请求时链接地址上加sign,如 $url = "{$url}&timestamp={$time}&sign={$sign}";

钉钉 javasdk 机器人 php 钉钉机器人_自定义_04

群主/群成员可以在电脑端通过如下的路径添加自定义机器人:

步骤一:【电脑端钉钉 】-【群聊】-【群设置】-【智能群助手】-【添加更多】-【添加机器人】-【自定义】-【添加】,编辑机器人名称和选择添加的群组。

完成必要的安全设置(至少选择一种),勾选 我已阅读并同意《自定义机器人服务及免责条款》,点击“完成”即可。

二、代码实现

如果设置的敏感词,那么发送的消息中必须含有敏感词,才可以成功发送
如果设置了验签,那么必须要计算签名才可以发送
下面是验签方式的代码

方法一:

$url = 'webhook地址';
// 第一步,把timestamp+"\n"+密钥当做签名字符串,使用HmacSHA256算法计算签名,然后进行Base64 encode,最后再把签名参数再进行urlEncode,得到最终的签名(需要使用UTF-8字符集)。
$time = time() *1000;//毫秒级时间戳,我这里为了方便,直接把时间*1000了
$secret = '这是密钥';
$sign = hash_hmac('sha256', $time . "\n" . $secret,$secret,true);
$sign = base64_encode($sign);
$sign = urlencode($sign);
$msg = [
    'msgtype' => 'text',//这是文件发送类型,可以根据需求调整
    'text'    => [
        'content' => '这是需要发送的内容',
    ],
];
$url = "{$url}×tamp={$time}&sign={$sign}";
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($msg));
curl_setopt($curl, CURLOPT_HEADER, 0);
curl_setopt($curl, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$res = curl_exec($curl);
curl_close($curl);
var_dump($res);

方法二:

function sendMessage2DingTalk($msg, $secret, $accessToken)
{
    // 当前时间(毫秒)
    $timestamp = time() * 1000;
    // HmacSHA256加密,设置为 true 输出原始二进制数据
    $hmacsha256 = hash_hmac('sha256', $timestamp . "
" . $secret, $secret, true);
    // 请求参数
    $param = [
        'access_token' => $accessToken,
        'timestamp' => $timestamp,
        // 签名值
        'sign' => urlencode(base64_encode($hmacsha256))
    ];
    // Webhook地址
    $webhook = "https://oapi.dingtalk.com/robot/send?" . http_build_query($param);
    // 发送消息
    $options = [
        'http' => [
            // 请求方法
            'method' => "POST",
            // 请求格式为json
            'header' => "Content-type:application/json;charset=utf-8
",
            // 请求内容
            'content' => $msg
        ],
        // 不验证ssl证书
        "ssl" => [
            "verify_peer" => false,
            "verify_peer_name" => false
        ]
    ];
    return file_get_contents($webhook, false, stream_context_create($options));
}

sendMessage2DingTalk('{"msgtype":"text","text":{"content":"我就是我, 是不一样的烟火啊"}}', "SECxxx", "xxx");

 我的代码

//加签机器人
// 当前时间(毫秒)
$timestamp = time() * 1000;
$secret = 'SEC5384c3***ea1719c1be2e3fff3';//秘钥
$signStr = getSign($timestamp, $secret);
$webhookUrl = "https://oapi.dingtalk.com/robot/send?access_token=d9e39e***134d71" . $signStr;
define('DING_TALK', $webhookUrl);

$robot = new Plugin_Robot;

//获取签名参数
function getSign($timestamp = 0, $secret = '')
{
	$signStr = hash_hmac('sha256', $timestamp . "\n" . $secret, $secret, true);
	$signStr = urlencode(base64_encode($signStr));
	$params = '&' . http_build_query(['timestamp' => $timestamp, 'sign' => $signStr]);
	return $params;
}
$date = date('Y-m-d H:i:s');

$res=$robot->text('test');


//*****robot.php****//
//发送text文本信息
public function text($content = '', $mobiles = [], $userIds = [], $isAtAll = false)
	{
		$sendContent = [
			"msgtype" => "text",
			"text" => [
				"content" => $content
			],
			"at" => [
				"atMobiles" => $mobiles,
				"atUserIds" => $userIds,   //不是钉钉管理员无法获取userIds
				"isAtAll" => $isAtAll
			]
		];
		$res = $this->_curl_post_json($this->webhookurl, $sendContent);
		return $res;
	}


//发送json数据
	public function _curl_post_json($url, $data = array())
	{
		$curl = curl_init($url);
		curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
		curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
		curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 5);
		curl_setopt($curl, CURLOPT_POST, 1);
		curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data, 320));
		curl_setopt($curl, CURLOPT_HEADER, 0);
		curl_setopt($curl, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
		curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
		$res = curl_exec($curl);
		curl_close($curl);
		return $res;
	}

设置关键字

//webhook 地址
define('DING_TALK', 'https://oapi.dingtalk.com/robot/send?access_token=XXX');//钉钉机器人

//curl发送json数据
function curl_post_json($url, $data = array(), $header = array(), $timeout = 80, $port = 80){
	$curl = curl_init($url);
	curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
	curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
	curl_setopt($curl, CURLOPT_POST, 1);
	curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data,320));
	curl_setopt($curl, CURLOPT_HEADER, 0);
	curl_setopt($curl, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
	curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
	$res = curl_exec($curl);
	curl_close($curl);
	return $res;
}

//发送逻辑

$resStr = $search_result;
			if (strlen($search_result) > 4000){ //markdown格式的消息,最大不超过5000字符。
				$resStr = substr($search_result, 0, 1000) . '...' . substr($search_result, -1000);
			}
			$voiceContent = "### **监控:**" . $type .
				"  \n  #### **查询条件:**  \n  " . $noticeData['search_cond'] .
				"  \n  #### **查询结果:**  \n  " . $resStr .
				"  \n  #### **错误原因:**  " . $noticeData['content'] . ':查询超时';
			$talkContent = [
				"msgtype" => "markdown",//这是文件发送类型,可以根据需求调整
				"markdown" => [
					"title" => "访问异常通知",
					"text" => $voiceContent
				]];

			$res = curl_post_json(DING_TALK, $talkContent);
			$errcode = json_decode($res, true)['errcode'];

三、最后看效果图

钉钉 javasdk 机器人 php 钉钉机器人_SSL_05

四、注意事项

1.钉钉机器人MarkDown类型的消息不支持@人

最近在做告警系统的过程中,需要用到钉钉机器人进行告警,创建自定义机器人后,发送相关消息。我们需要@群内的相关人员,使用过程中发现只有text类型的消息支持@相关人,其余类型不支持。百思不得其解,下面是钉钉的开发文档

钉钉机器人开发文档

钉钉 javasdk 机器人 php 钉钉机器人_钉钉 javasdk 机器人_06

如需要@人,只需要在at这个json对象中加入对应手机号就ok,text['content']中不用写@手机号,而其他类型的消息,比如MarkDown类型则不能@相关人,但可以设置 at['isAtAll'] 为true

起初我以为是我哪里配置的问题,找了很久始终没有找到原因。最后提了工单,他们告诉我在text中也要把手机号当作文本拼接在后面

钉钉 javasdk 机器人 php 钉钉机器人_钉钉 javasdk 机器人_07

文档中没有任何说明,而且这是什么反人类的设计……坑啊!

钉钉 javasdk 机器人 php 钉钉机器人_自定义_08

$markdown="#### 杭州天气 \n > 9度,西北风1级,空气良89,相对温度73% @18**01 \n > ![screenshot](https://t7.baidu.com/it/u=3691080281,11347921&fm=193&f=GIF)\n > ###### 10点20分发布 相关负责关注是否需要处理异常数据 [天气](https://image.so.com/) \n ";
$res2 = $robot->markdown('我是预警标题', $markdown, ["18**01",'1851**33']);
var_dump($res2, $date);

记录一下,避免大家遇到类似的问题

参考:

http:///www.codenong.com/cs106471299/

https://www.php.cn/blog/detail/35766.html