本文目录导读:

将 PHP 项目接入钉钉机器人,主要分为两种场景:
- 群机器人(Webhook):向钉钉群发送消息通知(如报警、日志、订单提醒),最常见。
- 应用机器人(Stream/HTTP):接收并回复用户的消息(类似客服或 ChatBot),交互更复杂。
下面分别提供这两种场景的详细接入步骤和 PHP 代码示例。
群机器人(发送消息)
这是最常用的方式,主要用于将系统事件推送到钉钉群,不需要复杂的认证,操作简单。
创建群机器人
- 步骤:在钉钉目标群里,点击群设置 -> 智能群助手 -> 添加机器人 -> 选择“自定义”(通过 Webhook 接入)。
- 关键信息:
Webhook URL:https://oapi.dingtalk.com/robot/send?access_token=xxxxx。安全设置:- 方式1(推荐):加签(Secret),需要将时间戳和 Secret 拼接后做 HmacSHA256 签名,添加到请求中。
- 方式2:自定义关键词,消息中必须包含该关键词。
- 方式3:IP 地址段,只允许指定 IP 调用。
PHP 代码实现(使用 cURL)
以下代码封装了加签和发送消息的逻辑,兼容常用消息类型。
<?php
class DingTalkRobot
{
private $webhookUrl;
private $secret;
/**
* @param string $webhookUrl 钉钉机器人的 Webhook 地址
* @param string $secret 安全设置的加签密钥 (如果不加签,传空字符串)
*/
public function __construct($webhookUrl, $secret = '')
{
$this->webhookUrl = $webhookUrl;
$this->secret = $secret;
}
/**
* 生成签名(用于加签模式)
* @return string 拼接了 timestamp 和 sign 的完整 URL
*/
private function generateSignedUrl()
{
if (empty($this->secret)) {
return $this->webhookUrl;
}
$timestamp = round(microtime(true) * 1000);
$stringToSign = $timestamp . "\n" . $this->secret;
$sign = base64_encode(hash_hmac('sha256', $stringToSign, $this->secret, true));
// 追加到 URL
return $this->webhookUrl . "×tamp=" . $timestamp . "&sign=" . urlencode($sign);
}
/**
* 发送消息
* @param array $data 消息体数组
* @return array 响应结果 ['errcode' => 0, 'errmsg' => 'ok']
*/
public function send($data)
{
$url = $this->generateSignedUrl();
$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',
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 本地调试建议 false,生产环境建议 true
$response = curl_exec($ch);
$error = curl_error($ch);
curl_close($ch);
if ($error) {
return ['errcode' => -1, 'errmsg' => 'cURL error: ' . $error];
}
return json_decode($response, true);
}
// ---------- 便捷消息封装 ----------
/**
* 发送文本消息
* @param string $content 消息内容
* @param array $atMobiles 被@人的手机号列表
* @param bool $isAtAll 是否@所有人
*/
public function sendText($content, $atMobiles = [], $isAtAll = false)
{
$data = [
'msgtype' => 'text',
'text' => [
'content' => $content,
],
'at' => [
'atMobiles' => $atMobiles,
'isAtAll' => $isAtAll,
],
];
return $this->send($data);
}
/**
* 发送 Markdown 消息
* @param string $title 标题(用于首屏)
* @param string $markdownContent 支持 Markdown 的正文
*/
public function sendMarkdown($title, $markdownContent)
{
$data = [
'msgtype' => 'markdown',
'markdown' => [
'title' => $title,
'text' => $markdownContent,
],
];
return $this->send($data);
}
/**
* 发送 ActionCard 消息
*/
public function sendActionCard($title, $text, $singleTitle, $singleURL)
{
$data = [
'msgtype' => 'actionCard',
'actionCard' => [
'title' => $title,
'text' => $text,
'btnOrientation' => '0', // 0: 按钮竖直排列, 1: 水平排列
'singleTitle' => $singleTitle,
'singleURL' => $singleURL,
],
];
return $this->send($data);
}
}
// -------------------- 使用示例 --------------------
// 1. 初始化(将 YOUR_WEBHOOK_URL 和 YOUR_SECRET 替换为你的真实信息)
$webhookUrl = 'https://oapi.dingtalk.com/robot/send?access_token=YOUR_ACCESS_TOKEN';
$secret = 'YOUR_SECRET'; // 如果没加签,传空字符串 ''
$robot = new DingTalkRobot($webhookUrl, $secret);
// 2. 发送文本消息(无需@)
$result = $robot->sendText('【订单通知】新订单 #12345 已创建');
// 3. 发送 Markdown 消息(支持加粗、链接、列表)
$markdown = "## 📢 服务器告警\n";
$markdown .= "- **服务器**: 生产01\n";
$markdown .= "- **状态**: CPU 使用率 95%\n";
$markdown .= "- [查看详情](http://example.com)";
$result = $robot->sendMarkdown('告警通知', $markdown);
// 4. 检查结果
if ($result['errcode'] === 0) {
echo "消息发送成功!";
} else {
echo "发送失败:" . $result['errmsg'];
}
注意事项:
- 如果设置了,消息内容必须包含该关键词,否则会被钉钉过滤。
- 消息频率有限制(每个机器人每分钟最多 20 条),过多消息会被限流。
应用机器人(接收与回复消息)
如果需要实现对话交互(用户向机器人发消息,机器人处理后回复),需要创建“应用机器人”,旧方案使用 HTTP 回调(需公网固定IP),新推荐方案是 Stream 模式(WebSocket),无需公网 IP。
Stream 模式接入(推荐,无需公网 IP)
- 准备:
- 在钉钉开发者后台创建“企业内部应用”或“第三方企业应用”。
- 开启“机器人与消息推送”功能。
- 获取应用的
clientId(即 AppKey)和clientSecret。
- 原理:你的本地 PHP 应用通过 WebSocket 连接到钉钉服务端,服务端将用户消息转发到你的应用,应用处理后再发回。
PHP 接入 Stream 模式(使用官方 SDK)
钉钉提供了官方的 PHP SDK (dingtalk/robot-stream) 来处理连接和消息。
安装步骤:
composer require dingtalk/robot-stream
核心代码(demo.php):
<?php
require_once __DIR__ . '/vendor/autoload.php';
use GuzzleHttp\Client;
use DingTalk\Robot\RobotStreamClient;
use DingTalk\Robot\Message\TextMessage;
use DingTalk\Robot\Message\MarkdownMessage;
use Psr\Log\AbstractLogger;
// 1. 配置日志(可选,方便调试)
class SimpleLogger extends AbstractLogger
{
public function log($level, $message, array $context = [])
{
echo "[{$level}] {$message}" . PHP_EOL;
}
}
// 2. 初始化客户端(传入你的 AppKey 和 AppSecret)
$clientId = 'your_app_key'; // 从应用详情页获取
$clientSecret = 'your_app_secret'; // 从应用详情页获取
$logger = new SimpleLogger();
// 3. 创建 RobotStreamClient 实例
$robotClient = new RobotStreamClient($clientId, $clientSecret, $logger);
// 4. 设置消息回调(当用户@机器人时触发)
$robotClient->setMessageHandler(function ($messageData) use (&$robotClient) {
// $messageData 结构包含: senderId, senderNick, conversationType, text/content 等
$senderId = $messageData->getSenderId(); // 发送者 userId
$content = $messageData->getText()->getContent(); // 用户发来的文本消息
// 根据用户消息进行处理,构建回复
if (strpos($content, '你好') !== false) {
$replyText = "你好!我是 PHP 机器人。\n\n你可以输入:\n- 天气\n- 时间";
} elseif ($content === '时间') {
$replyText = "当前时间:" . date('Y-m-d H:i:s');
} else {
$replyText = "收到:「{$content}」,我还不理解,再试试别的吧。";
}
// 发送回复消息(调用官方 SDK 的 reply 方法)
$robotClient->replyMessageText($replyText, $messageData);
// 或者回复 Markdown:
// $robotClient->replyMessage(new MarkdownMessage("标题\n**加粗**\n- 列表"), $messageData);
});
// 5. 启动服务(保持连接)
echo "机器人服务启动中...\n";
$robotClient->run();
运行方式:
# 在命令行运行(需保持终端开启) php demo.php
- 优势:无公共 IP 要求,长连接,稳定,官方维护。
- 缺点:PHP 脚本需常驻后台(守护进程),建议配合 Supervisor 使用。
总结选择
| 场景 | 方案 | 适用场景 | 实现难度 |
|---|---|---|---|
| 只发消息 | 群机器人(Webhook) | 监控报警、订单通知、日志推送 | ★☆☆☆☆ |
| 收发消息 | 应用机器人(Stream) | 客服机器人、AI 对话、内部工具 | ★★★★☆ |
建议:
- 如果你只是需要在 PHP 项目执行到某个点时(例如支付成功)通知运维/销售,用场景一的 Webhook,直接调用
sendText即可。 - 如果你要做一个能和用户在钉钉里对话的机器人,用场景二的 Stream 模式。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播