鉴于很多Telegram推送插件不完善，于是做了这个插件。⚡ 功能✅ Telegram 机器人推送评论通知（支持多 Chat ID 群发、邮箱绑定、Telegram 回复评论、评论快捷审核）✅ Typecho 后台文章一键推送至Telegram🧩 截图 管理界面后台推送Bot 推送 移动端优化 💻 Github 地址🏗️ 整体架构插件主要由三个核心文件组成:Plugin.php - 插件主类,负责配置、评论监听和消息推送TelegramComment_Action.php - Action处理类,负责Webhook回调和管理接口push.php - 推送文章📋 核心实现流程1️⃣ 插件激活流程 (Plugin::activate)public static function activate(): string { Typecho\Plugin::factory('Widget_Feedback')->finishComment = __CLASS__ . '::onFinishComment'; Typecho\Plugin::factory('Widget_Comments_Edit')->finishComment = __CLASS__ . '::onFinishComment'; Utils\Helper::addAction('telegram-comment', 'TypechoPlugin\\TelegramNotice\\TelegramComment_Action'); try { $opt = Utils\Helper::options()->plugin('TelegramNotice'); $token = trim((string)($opt->botToken ?? '')); if ($token !== '') { self::ensureWebhookConfigured($token); } } catch (\Throwable $e) { // ignore } return _t('TelegramNotice 启用成功'); }关键动作:注册评论钩子 (finishComment),监听新评论和评论编辑注册自定义Action路由 /action/telegram-comment2️⃣ 评论推送流程 (Plugin::onFinishComment)public static function onFinishComment($comment) { $opt = Utils\Helper::options()->plugin('TelegramNotice'); $token = trim((string)($opt->botToken ?? '')); // ... 准备配置参数 // 1. 确保Webhook已配置 self::ensureWebhookConfigured($token); // 2. 渲染消息模板 $message = self::renderTemplate($tpl, $comment, $postTitle); // 3. 构建Inline Keyboard (审核按钮) $keyboard = [ 'inline_keyboard' => [ [ ['text' => '✅ 通过', 'callback_data' => "approve_{$comment->coid}"], ['text' => '🗑️ 标记垃圾', 'callback_data' => "spam_{$comment->coid}"], ['text' => '💬 回复', 'callback_data' => "reply_{$comment->coid}"], ] ] ]; // 4. 确定发送目标 // - 如果评论者邮箱有绑定chat_id -> 发给绑定的用户 // - 否则发给默认chat_id列表 $targetChatIds = self::resolveTargetChatIds($opt, $mail); // 5. 群发消息 foreach ($targetChatIds as $cid) { self::tgApi($token, 'sendMessage', [ 'chat_id' => $cid, 'text' => $message, 'parse_mode' => 'HTML', 'reply_markup' => json_encode($keyboard) ]); } }推送逻辑:Webhook自动配置: 确保Telegram Webhook指向本站模板渲染: 替换 {title} {author} {text} 等变量Inline Keyboard: 添加"通过/垃圾/回复"交互按钮邮箱绑定: 支持根据评论者邮箱发送到特定Chat ID多目标群发: 可同时发送到多个Chat ID3️⃣ Webhook回调处理 (TelegramComment_Action)public function execute() { $do = trim($this->req('do', '')); if ($do === 'webhookCheck' || $do === 'webhookSet') { $this->handleWebhookAjax($do); // 后台管理接口 return; } if ($do === 'webhook') { $this->handleTelegramWebhook(); // Telegram回调 return; } $this->response->setStatus(404); $this->response->throwJson(['ok' => false, 'error' => 'not_found']); }处理三种请求:A. Webhook检测 (?do=webhookCheck)调用Telegram API getWebhookInfo比较当前URL与期望URL返回配置状态B. Webhook配置 (?do=webhookSet)调用 setWebhook 设置回调地址带上 allowed_updates 参数(仅接收 callback_query 和 message)C. Telegram回调 (?do=webhook&secret=xxx)接收Telegram推送的用户交互事件:private function handleTelegramWebhook(): void { // 1. 验证secret // 2. 解析Telegram回调数据 (callback_query 或 message) // 3. 处理按钮点击: // - approve_{coid}: 审核通过评论 // - spam_{coid}: 标记为垃圾评论 // - waiting_{coid}: 等待回复模式 // 4. 处理Reply-to消息 (直接回复评论) // 5. 更新数据库状态 // 6. 回复操作结果 }4️⃣ 审核按钮处理逻辑当用户在Telegram点击按钮时:if ($action === 'approve') { // 1. 更新评论状态为 'approved' $db->query($db->update('table.comments') ->rows(['status' => 'approved']) ->where('coid = ?', $coid)); // 2. 回复操作结果 Plugin::tgApi($token, 'answerCallbackQuery', [ 'callback_query_id' => $callbackQueryId, 'text' => '✅ 已通过' ]); // 3. 编辑原消息(移除按钮,标记已处理) Plugin::tgApi($token, 'editMessageText', [ 'chat_id' => $chatId, 'message_id' => $messageId, 'text' => $originalText . "\n\n✅ 已通过", 'parse_mode' => 'HTML' ]); }5️⃣ 直接回复评论功能支持在Telegram内使用"Reply-to"直接发布评论回复:// 1. 点击"💬 回复"按钮 -> 状态切换为等待模式 if ($action === 'reply') { // 更新按钮为"等待回复..."状态 $keyboard = [ 'inline_keyboard' => [[ ['text' => '⏸️ 取消回复', 'callback_data' => "cancel_reply_{$coid}"] ]] ]; } // 2. 用户Reply-to消息 -> 检测是否有等待状态 if ($isReply && $replyToMsgId) { // 提取coid // 创建新评论记录 $db->query($db->insert('table.comments')->rows([ 'cid' => $parentComment['cid'], 'coid' => 0, 'parent' => $coid, 'text' => $replyText, 'author' => $authorName, 'mail' => $authorMail, 'status' => 'approved' ])); }🔧 关键技术特性📡 Webhook自动管理插件启用时自动配置每次推送时检测并修复后台提供"一键配置"按钮🎯 智能推送分发// 邮箱绑定优先 if (isset($emailBindMap[$commentMail])) { $boundChatId = $emailBindMap[$commentMail]; if ($broadcastDefault) { // 既发给绑定用户,也群发 return array_unique(array_merge([$boundChatId], $defaultChatIds)); } else { // 仅发给绑定用户 return [$boundChatId]; } }🔐 安全机制Webhook Secret验证Database字段类型检查Try-catch异常捕获HTML转义防XSS📊 消息模板系统$vars = [ '{title}' => $postTitle, '{author}' => $comment->author, '{text}' => $trimmedText, '{permalink}' => $permalink, '{ip}' => $comment->ip, '{created}' => date('Y-m-d H:i:s', $comment->created), '{coid}' => $comment->coid, '{mail}' => $comment->mail, ]; return strtr($template, $vars);📊 数据流图┌─────────────┐ │ 新评论发布 │ └──────┬──────┘ │ ▼ ┌──────────────────┐ │ onFinishComment │ (评论钩子触发) └─────┬────────────┘ │ ├─→ 渲染消息模板 ├─→ 构建Inline Keyboard ├─→ 解析邮箱绑定 │ ▼ ┌─────────────────────┐ │ 调用Telegram API │ (sendMessage) │ 发送到多个Chat ID │ └─────────┬───────────┘ │ ▼ ┌──────────────────────┐ │ 用户在Telegram看到 │ │ [✅通过] [🗑️垃圾] [💬回复] │ └─────────┬────────────┘ │ (点击按钮) ▼ ┌──────────────────────┐ │ Telegram Webhook回调 │ │ ↓ │ │ /action/telegram-comment?do=webhook └─────────┬────────────┘ │ ▼ ┌─────────────────────┐ │ TelegramComment_Action │ │ handleTelegramWebhook │ └─────┬───────────────┘ │ ├─→ approve: 更新status='approved' ├─→ spam: 更新status='spam' └─→ reply: 等待Reply-to消息