本文目录导读:

我来详细介绍 PHP 对接钉钉通知的几种方式:
钉钉自定义机器人 Webhook(最常用)
基础配置
首先在钉钉群中添加自定义机器人,获取 Webhook 地址和加签密钥。
签名算法实现
<?php
class DingTalkRobot
{
private $webhook;
private $secret;
public function __construct($webhook, $secret = '')
{
$this->webhook = $webhook;
$this->secret = $secret;
}
/**
* 生成签名
*/
private function getSign()
{
if (empty($this->secret)) {
return '';
}
$timestamp = time() * 1000;
$stringToSign = $timestamp . "\n" . $this->secret;
$sign = base64_encode(hash_hmac('sha256', $stringToSign, $this->secret, true));
$urlEncodeSign = urlencode($sign);
return "×tamp={$timestamp}&sign={$urlEncodeSign}";
}
/**
* 发送消息
*/
public function sendMessage($content, $type = 'text')
{
$url = $this->webhook . $this->getSign();
switch ($type) {
case 'text':
$data = [
'msgtype' => 'text',
'text' => [
'content' => $content
]
];
break;
case 'markdown':
$data = [
'msgtype' => 'markdown',
'markdown' => [
'title' => '消息通知',
'text' => $content
]
];
break;
default:
return false;
}
return $this->httpRequest($url, $data);
}
/**
* HTTP 请求
*/
private function httpRequest($url, $data)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json;charset=utf-8'
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
$response = curl_exec($ch);
$error = curl_error($ch);
curl_close($ch);
if ($error) {
return ['success' => false, 'error' => $error];
}
return json_decode($response, true);
}
/**
* 发送文本消息
*/
public function sendText($content, $atMobiles = [], $isAtAll = false)
{
$data = [
'msgtype' => 'text',
'text' => [
'content' => $content
],
'at' => [
'atMobiles' => $atMobiles,
'isAtAll' => $isAtAll
]
];
$url = $this->webhook . $this->getSign();
return $this->httpRequest($url, $data);
}
/**
* 发送 Markdown 消息
*/
public function sendMarkdown($title, $markdownText, $atMobiles = [], $isAtAll = false)
{
$data = [
'msgtype' => 'markdown',
'markdown' => [
'title' => $title,
'text' => $markdownText
],
'at' => [
'atMobiles' => $atMobiles,
'isAtAll' => $isAtAll
]
];
$url = $this->webhook . $this->getSign();
return $this->httpRequest($url, $data);
}
}
使用示例
// 基础使用
$webhook = 'https://oapi.dingtalk.com/robot/send?access_token=XXXXX';
$secret = 'SECxxxxx'; // 如果有加签则填写
$ding = new DingTalkRobot($webhook, $secret);
// 发送普通文本
$result = $ding->sendText('你好,这是一条测试消息!');
// 发送@某人的消息
$result = $ding->sendText('任务完成,请查看', ['13800138000'], false);
// 发送 Markdown 消息
$markdown = "### 系统告警\n" .
"> **服务器**: 192.168.1.1\n" .
"> **CPU使用率**: 95%\n" .
"> **内存使用率**: 89%\n" .
"> 请尽快处理!";
$result = $ding->sendMarkdown('告警通知', $markdown);
// 检查发送结果
if (isset($result['errcode']) && $result['errcode'] === 0) {
echo "发送成功";
} else {
echo "发送失败:" . json_encode($result);
}
企业微信/钉钉应用消息推送
如果需要在应用内部推送,可以使用钉钉开放平台的 API:
<?php
class DingTalkApp {
private $appKey;
private $appSecret;
private $agentId;
public function __construct($appKey, $appSecret, $agentId)
{
$this->appKey = $appKey;
$this->appSecret = $appSecret;
$this->agentId = $agentId;
}
/**
* 获取 access_token
*/
public function getAccessToken()
{
$url = 'https://oapi.dingtalk.com/gettoken';
$params = [
'appkey' => $this->appKey,
'appsecret' => $this->appSecret
];
$response = $this->httpGet($url, $params);
if ($response['errcode'] === 0) {
return $response['access_token'];
}
return false;
}
/**
* 发送工作通知消息
*/
public function sendWorkNotification($userId, $content)
{
$accessToken = $this->getAccessToken();
if (!$accessToken) {
return false;
}
$url = 'https://oapi.dingtalk.com/topapi/message/corpconversation/asyncsend_v2?access_token=' . $accessToken;
$data = [
'agent_id' => $this->agentId,
'userid_list' => $userId,
'msg' => [
'msgtype' => 'text',
'text' => [
'content' => $content
]
]
];
return $this->httpPost($url, $data);
}
// HTTP 请求方法实现...
}
使用 Guzzle HTTP 客户端(更现代的方式)
<?php
use GuzzleHttp\Client;
class DingTalkNotifier {
private $webhook;
private $client;
public function __construct($webhook)
{
$this->webhook = $webhook;
$this->client = new Client([
'timeout' => 10,
'verify' => false
]);
}
/**
* 发送通知
*/
public function send($message, $type = 'text', $atAll = false)
{
try {
$payload = [
'msgtype' => $type,
$type => [
'content' => $message
]
];
if ($atAll) {
$payload['at'] = ['isAtAll' => true];
}
$response = $this->client->post($this->webhook, [
'json' => $payload
]);
$result = json_decode($response->getBody(), true);
return $result['errcode'] === 0;
} catch (\Exception $e) {
return false;
}
}
}
// 使用
$notifier = new DingTalkNotifier('https://oapi.dingtalk.com/robot/send?access_token=XXXX');
$notifier->send('部署完成', 'text');
消息模板示例
<?php
class MessageBuilder {
/**
* 构建部署通知
*/
public static function buildDeployMessage($project, $env, $status)
{
$color = $status === '成功' ? 'green' : 'red';
return "### 构建通知\n" .
"> **项目**: $project\n" .
"> **环境**: $env\n" .
"> **状态**: <font color='$color'>$status</font>\n" .
"> **时间**: " . date('Y-m-d H:i:s');
}
/**
* 构建系统告警
*/
public static function buildAlertMessage($server, $metrics)
{
$text = "### 🚨 系统告警\n";
foreach ($metrics as $key => $value) {
$text .= "> **{$key}**: {$value}\n";
}
return $text;
}
}
异常处理与日志记录
<?php
class DingTalkService {
public function sendWithRetry($message, $maxRetries = 3)
{
$retries = 0;
while ($retries < $maxRetries) {
try {
$result = $this->send($message);
if ($result) {
$this->log('success', $message);
return true;
}
} catch (\Exception $e) {
$this->log('error', $e->getMessage());
}
$retries++;
sleep(2); // 等待2秒后重试
}
return false;
}
private function log($level, $message)
{
$log = sprintf("[%s] [%s] %s\n", date('Y-m-d H:i:s'), $level, $message);
file_put_contents('/var/log/dingtalk.log', $log, FILE_APPEND);
}
}
注意事项
- 安全限制:不要将 Webhook 地址暴露在公开代码中
- 频率限制:每个机器人每分钟最多发送 20 条消息
- 消息长度:文本消息不超过 5000 字符
- 敏感信息:不要在消息中发送敏感信息
就是 PHP 对接钉钉通知的主要方式,可以根据实际需求选择合适的方法。