本文目录导读:

我来帮你介绍在PHP项目中集成飞书(Feishu/Lark)和Slack机器人的实现方案。
飞书机器人实现
基础配置
<?php
namespace App\Services\Bot;
class FeishuBot
{
private $webhookUrl;
private $secret;
public function __construct($webhookUrl, $secret = null)
{
$this->webhookUrl = $webhookUrl;
$this->secret = $secret;
}
/**
* 发送消息
*/
public function sendMessage($content, $msgType = 'text')
{
$data = [
'msg_type' => $msgType,
'content' => $this->buildContent($content, $msgType)
];
// 如果需要签名
if ($this->secret) {
$data['timestamp'] = time();
$data['sign'] = $this->generateSign($data['timestamp']);
}
return $this->request($data);
}
/**
* 生成签名
*/
private function generateSign($timestamp)
{
$stringToSign = $timestamp . "\n" . $this->secret;
return base64_encode(hash_hmac('sha256', '', $stringToSign, true));
}
/**
* 构建内容
*/
private function buildContent($content, $msgType)
{
switch ($msgType) {
case 'text':
return ['text' => $content];
case 'post':
return $this->buildPostContent($content);
case 'interactive':
return $content; // 直接传入卡片JSON
default:
return ['text' => $content];
}
}
/**
* 发送请求
*/
private function request($data)
{
$ch = curl_init($this->webhookUrl);
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_POSTFIELDS => json_encode($data),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 5
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
return [
'code' => $httpCode,
'data' => json_decode($response, true)
];
}
}
使用示例
// 简单文本消息
$bot = new FeishuBot('https://open.feishu.cn/open-apis/bot/v2/hook/xxx');
$bot->sendMessage('这是一条测试消息');
// 富文本消息
$bot->sendMessage([ => '系统通知',
'content' => [
[['tag' => 'text', 'text' => '项目部署成功']],
[['tag' => 'a', 'text' => '查看详情', 'href' => 'http://example.com']]
]
], 'post');
// 消息卡片
$card = [
'config' => ['wide_screen_mode' => true],
'header' => [
'title' => ['tag' => 'plain_text', 'content' => '错误提醒'],
'template' => 'red'
],
'elements' => [
['tag' => 'markdown', 'content' => '**错误信息:** 数据库连接失败']
]
];
$bot->sendMessage($card, 'interactive');
Slack Bot实现
使用Webhook发送消息
<?php
namespace App\Services\Bot;
class SlackBot
{
private $webhookUrl;
private $token;
public function __construct($webhookUrl = null, $token = null)
{
$this->webhookUrl = $webhookUrl;
$this->token = $token;
}
/**
* 通过Webhook发送消息
*/
public function sendViaWebhook($message)
{
$data = is_array($message) ? $message : ['text' => $message];
$ch = curl_init($this->webhookUrl);
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_POSTFIELDS => json_encode($data),
CURLOPT_RETURNTRANSFER => true
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
return $httpCode === 200;
}
/**
* 通过API发送消息(需要Bot Token)
*/
public function sendMessage($channel, $text, $blocks = [])
{
$data = [
'channel' => $channel,
'text' => $text
];
if (!empty($blocks)) {
$data['blocks'] = $blocks;
}
return $this->apiRequest('chat.postMessage', $data);
}
/**
* Slack API请求
*/
private function apiRequest($method, $data)
{
$url = "https://slack.com/api/{$method}";
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
"Authorization: Bearer {$this->token}"
],
CURLOPT_POSTFIELDS => json_encode($data),
CURLOPT_RETURNTRANSFER => true
]);
return json_decode(curl_exec($ch), true);
}
/**
* 发送Block Kit消息
*/
public function sendBlockMessage($channel, $blocks)
{
return $this->sendMessage($channel, ' ', $blocks);
}
}
Slack Block Kit示例
// 创建丰富的消息
$blocks = [
[
'type' => 'header',
'text' => ['type' => 'plain_text', 'text' => '部署通知']
],
[
'type' => 'section',
'fields' => [
['type' => 'mrkdwn', 'text' => "*状态:*\n✅ 成功"],
['type' => 'mrkdwn', 'text' => "*环境:*\n生产"],
['type' => 'mrkdwn', 'text' => "*版本:*\nv2.1.0"],
['type' => 'mrkdwn', 'text' => "*时间:*\n2024-01-01 10:00"]
]
],
[
'type' => 'actions',
'elements' => [
[
'type' => 'button',
'text' => ['type' => 'plain_text', 'text' => '查看日志'],
'url' => 'https://logs.example.com',
'style' => 'primary'
],
[
'type' => 'button',
'text' => ['type' => 'plain_text', 'text' => '回滚'],
'style' => 'danger',
'confirm' => [
'title' => ['type' => 'plain_text', 'text' => '确认回滚'],
'text' => ['type' => 'mrkdwn', 'text' => '确定要回滚吗?'],
'confirm' => ['type' => 'plain_text', 'text' => '确认'],
'deny' => ['type' => 'plain_text', 'text' => '取消']
]
]
]
]
];
$bot = new SlackBot(null, 'xoxb-your-bot-token');
$bot->sendBlockMessage('#deployments', $blocks);
统一通知服务
<?php
namespace App\Services;
class NotificationService
{
private $channels = [];
/**
* 添加通知渠道
*/
public function addChannel($name, $bot)
{
$this->channels[$name] = $bot;
}
/**
* 发送通知到所有渠道
*/
public function notifyAll($message, $channel = null)
{
$results = [];
foreach ($this->channels as $name => $bot) {
if ($channel && $name !== $channel) {
continue;
}
try {
$bot->sendMessage($message);
$results[$name] = true;
} catch (\Exception $e) {
$results[$name] = false;
// 记录日志
Log::error("Notification failed for {$name}: " . $e->getMessage());
}
}
return $results;
}
}
配置与使用
// config/bots.php
return [
'feishu' => [
'webhook' => env('FEISHU_WEBHOOK_URL'),
'secret' => env('FEISHU_SECRET', null)
],
'slack' => [
'webhook' => env('SLACK_WEBHOOK_URL'),
'token' => env('SLACK_BOT_TOKEN')
]
];
// 使用示例
$notification = new NotificationService();
// 添加飞书机器人
$notification->addChannel('feishu', new FeishuBot(
config('bots.feishu.webhook'),
config('bots.feishu.secret')
));
// 添加Slack机器人
$notification->addChannel('slack', new SlackBot(
config('bots.slack.webhook')
));
// 发送通知
$notification->notifyAll('系统部署完成!');
最佳实践建议
- 错误处理:添加重试机制和错误日志
- 消息格式化:统一消息格式,支持Markdown
- 速率限制:注意各平台的API调用限制
- 安全配置:敏感信息使用环境变量
- 异步发送:考虑使用消息队列
需要我详细说明某个特定功能或提供更多使用场景示例吗?