之前写钉钉群通知机器人的时候,封装了的一个机器人类库。
支持 老版机器人发送(只用token)、新版机器人发送(需要token + 验签)
token 就是生成机器人时地址后面的 access_token 的值.
封装类库
<?php
// 钉钉自定义机器人 webhook 封装
class Dingtalk
{
private $token = null; // token 类型
private $isAt = false; // 是否@所有人
// 实例化的时候 传递发送群的token
public function __construct($token = '')
{
// 如果传递的是数组 就走验签
if (is_array($token)) {
$this->tokenSign($token);
} else {
$this->token = $token;
}
}
// 走加签过程
private function tokenSign($Array)
{
// 赋值基础
$this->token = $Array['token'];
$Temptime = explode(' ', microtime());
$msectime = (float)sprintf('%.0f', (floatval($Temptime[0]) + floatval($Temptime[1])) * 1000);
$stringToSign = $msectime . "\n" . $Array['secret'];
$stringToSign = $stringToSign;
$sig = hash_hmac('sha256', $stringToSign, $Array['secret'], true);
$sign = urlencode(base64_encode($sig));
$this->token .= '×tamp=' . $msectime;
$this->token .= '&sign=' . $sign;
}
// 获取 token
public function token()
{
return $this->token;
}
// 是否@所有人
public function isAt(bool $type)
{
$this->isAt = $type;
}
/** 发送文本类
* @param $content 文本内容
* @return mixed|string
*/
public function text($content)
{
$data['msgtype'] = 'text';
$data['text'] = ['content' => $content];
preg_match_all("/(?<=@)\d{11}/", $content, $regular);
if ($regular[0]) $data['at']['atMobiles'] = $regular[0];
if ($this->isAt) $data['at']['isAtAll'] = $this->isAt;
return $this->send($data);
}
/** 发送链接类
* @param $title link的标题
* @param $text link的内容
* @param $url 跳转的超链接
* @param string $img 图片的地址 选填
*/
public function link($title, $text, $url, $img = '')
{
$data['msgtype'] = 'link'; // 链接类型
$data['link']['title'] = $title;
$data['link']['text'] = $text;
$data['link']['messageUrl'] = $url;
if ($img) $data['link']['picUrl'] = $img;
preg_match_all("/(?<=@)\d{11}/", $text, $regular);
if ($regular[0]) $data['at']['atMobiles'] = $regular[0];
if ($this->isAt) $data['at']['isAtAll'] = $this->isAt;
return $this->send($data);
}
/** 发送markdown消息
* @param $post_json
* @return mixed|string
*/
public function markdown($title, $content)
{
$data['msgtype'] = 'markdown'; //markdown 类型
$data['markdown']['title'] = $title;
$data['markdown']['text'] = $content;
// 正则取at用户手机号,如果有手机号 则@
preg_match_all("/(?<=@)\d{11}/", $content, $regular);
if ($regular[0]) $data['at']['atMobiles'] = $regular[0];
$data['at']['isAtAll'] = $this->isAt;
return $this->send($data);
}
/**
* 发送钉钉消息
* 若上面预设的类型不能满足 则在实例化之后自行拼装数组 使用send发送
* @param $post_json
* @return mixed|string
*/
public function send($post_json)
{
$post_json = json_encode($post_json);
try {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://oapi.dingtalk.com/robot/send?access_token=' . $this->token);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json;charset=utf-8'));
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_json);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// 线下环境不用开启curl证书验证, 未调通情况可尝试添加该代码
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
$data = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); // 获取请求的
curl_close($ch);
$resdata['data'] = $data;
$resdata['code'] = $httpCode;
return $resdata;
} catch (Exception $e) {
return 'error:' . $e->getMessage();
}
}
}
食用方法
初始化
// 使用老版token,一个长度64的字符串
$token = 'qnfxx**********';
$Ding = new Dingtalk($token);
// 使用新版 token + 加签 的形式
$token = [
'token' => ''qnfxx**********'',
'secret' => ''
];
$Ding = new Dingtalk($token);
获取token
这样主要是用来获取加签后的 token 一般是用不到的
$token = $Ding->token();
@所有人
发送消息时,是否@所有人,默认不会 @所有人
$Ding->isAt(true);
发送消息
发送消息目前支持四种方式,其中前三种是对第四种的封装.如果提供的封装不能满足发送类型的需要,可以使用第四种方式发送.
其中前三个方法均支持直接在内容中 @群成员,需要@其钉钉绑定的手机号即可, 例如 "早上好, @1500xxxxxxx"
// 第一种 发送 text 内容
$Ding->text();
// 第二种 发送 link 链接
$Dind->link();
// 第三种 发送 markdown,注意仅支持简单的md语法,以及部分简单的行内样式
$Ding->markdown();
// 第四种 send(),接收一个数组,数组需要按照需要的JSON格式拼装, 可以参考钉钉机器人文档:
// https://developers.dingtalk.com/document/robots/custom-robot-access
$Ding->send();