MENU

钉钉自定义机器人PHP类库

2021 年 03 月 13 日 • 阅读: 122 • PHP,编码

之前写钉钉群通知机器人的时候,封装了的一个机器人类库。
支持 老版机器人发送(只用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 .= '&timestamp=' . $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/app/custom-robot-access
$Ding->send();