解决方案设计
技术研究 人工智能 Telegram
步骤 1:通过 BotFather 创建 Bot 并获取 Token 步骤 2:配置 Slash Commands 步骤 3:设置 Webhook(部署后执行)
架构概述
基于前两章的分析,本方案采用 Serverless Webhook 中继 架构,实现 Telegram 与 GitHub Actions 的双向集成。
flowchart TD
A[用户输入 /deploy] -->|Bot API| B[Telegram 服务器]
B -->|Webhook POST| C[Cloudflare Worker<br/>或 Vercel Function]
C -->|解析命令| D{命令验证}
D -->|有效| E[调用 GitHub API]
D -->|无效| F[返回错误提示]
E -->|workflow_dispatch| G[GitHub Actions]
G -->|执行结果| H[Actions Job]
H -->|回调通知| C
C -->|Bot API| I[发送结果到 Telegram]
I --> J[用户收到反馈]
方案对比
方案 A:Cloudflare Workers(推荐)
优点:
- 全球边缘网络,延迟低(< 50ms)
- 免费额度充足(10万次/天)
- 原生支持环境变量和密钥管理
- 无需维护服务器
缺点:
- 有 50ms CPU 时间限制(但 HTTP 请求不计入)
- 需要学习 Workers 特定 API
适用场景:生产环境、高可用性要求
方案 B:Vercel Serverless Functions
优点:
- 与 Next.js 等框架集成好
- 开发体验优秀
- 免费 Hobby 计划足够
缺点:
- 冷启动时间较长(几百毫秒)
- 函数执行时间限制(10s Hobby / 60s Pro)
适用场景:已有 Vercel 项目、快速原型
方案 C:Pipedream(低代码)
优点:
- 无需编写代码
- 预置集成组件
- 可视化工作流
缺点:
- 免费额度有限(10k/月)
- 灵活性受限
- vendor lock-in
适用场景:概念验证、无开发资源
方案对比表
| 维度 | Cloudflare Workers | Vercel Functions | Pipedream |
|---|---|---|---|
| 成本 | 免费(10万/天) | 免费( generous ) | 免费(10k/月) |
| 延迟 | < 50ms | 100-500ms | 200-1000ms |
| 维护 | 零 | 零 | 零 |
| 灵活性 | 高 | 高 | 中 |
| 学习曲线 | 中 | 低 | 低 |
| 适用规模 | 任意 | 中小 | 小 |
详细设计(以 Cloudflare Workers 为例)
1. Telegram Bot 配置
步骤 1:通过 BotFather 创建 Bot 并获取 Token
/newbot -> 按提示命名 -> 获得 Token
步骤 2:配置 Slash Commands
/setcommands
选择你的 Bot
输入命令列表:
deploy - 部署应用到生产环境
build - 触发构建工作流
status - 查看工作流状态
步骤 3:设置 Webhook(部署后执行)
curl "https://api.telegram.org/bot<TOKEN>/setWebhook" \
-d "url=https://your-worker.your-subdomain.workers.dev/webhook" \
-d "secret_token=YOUR_WEBHOOK_SECRET"
2. Worker 代码结构
// index.js
export default {
async fetch(request, env, ctx) {
const url = new URL(request.url);
if (url.pathname === '/webhook' && request.method === 'POST') {
return handleWebhook(request, env);
}
return new Response('Not Found', { status: 404 });
}
};
async function handleWebhook(request, env) {
// 验证 Webhook Secret
const secretToken = request.headers.get('X-Telegram-Bot-Api-Secret-Token');
if (secretToken !== env.WEBHOOK_SECRET) {
return new Response('Unauthorized', { status: 401 });
}
const update = await request.json();
// 只处理消息类型的更新
if (!update.message || !update.message.text) {
return new Response('OK');
}
const text = update.message.text;
const chatId = update.message.chat.id;
// 解析命令
if (!text.startsWith('/')) {
return new Response('OK');
}
const [command, ...args] = text.slice(1).split(' ');
// 路由命令
switch (command) {
case 'deploy':
return handleDeploy(chatId, args, env);
case 'build':
return handleBuild(chatId, args, env);
case 'status':
return handleStatus(chatId, env);
default:
await sendMessage(env.BOT_TOKEN, chatId, 'Unknown command');
return new Response('OK');
}
}
async function handleDeploy(chatId, args, env) {
const environment = args[0] || 'staging';
try {
// 触发 GitHub Actions
const response = await fetch(
`https://api.github.com/repos/${env.GITHUB_OWNER}/${env.GITHUB_REPO}/actions/workflows/deploy.yml/dispatches`,
{
method: 'POST',
headers: {
'Authorization': `Bearer ${env.GITHUB_TOKEN}`,
'Accept': 'application/vnd.github+json',
'X-GitHub-Api-Version': '2022-11-28'
},
body: JSON.stringify({
ref: 'main',
inputs: { environment }
})
}
);
if (response.ok) {
await sendMessage(
env.BOT_TOKEN,
chatId,
`✅ Deployment triggered for *${environment}* environment`
);
} else {
const error = await response.text();
await sendMessage(
env.BOT_TOKEN,
chatId,
`❌ Failed to trigger deployment: ${error}`
);
}
} catch (error) {
await sendMessage(
env.BOT_TOKEN,
chatId,
`❌ Error: ${error.message}`
);
}
return new Response('OK');
}
async function sendMessage(token, chatId, text) {
await fetch(`https://api.telegram.org/bot${token}/sendMessage`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
chat_id: chatId,
text: text,
parse_mode: 'Markdown'
})
});
}
3. GitHub Actions 工作流示例
# .github/workflows/deploy.yml
name: Deploy
on:
workflow_dispatch:
inputs:
environment:
description: 'Deployment environment'
required: true
type: choice
options:
- staging
- production
default: 'staging'
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Deploy
run: |
echo "Deploying to ${{ github.event.inputs.environment }}"
# 你的部署脚本
- name: Notify Telegram
if: always()
uses: appleboy/telegram-action@master
with:
to: ${{ secrets.TELEGRAM_CHAT_ID }}
token: ${{ secrets.TELEGRAM_BOT_TOKEN }}
message: |
Deployment ${{ job.status == 'success' && '✅ succeeded' || '❌ failed' }}
Environment: ${{ github.event.inputs.environment }}
Commit: ${{ github.sha }}
4. 安全加固
Webhook 验证
必须使用 secret_token 防止伪造请求:
const secretToken = request.headers.get('X-Telegram-Bot-Api-Secret-Token');
if (secretToken !== env.WEBHOOK_SECRET) {
return new Response('Unauthorized', { status: 401 });
}
命令白名单
只允许特定用户或群组执行命令:
const ALLOWED_CHAT_IDS = env.ALLOWED_CHAT_IDS.split(',');
if (!ALLOWED_CHAT_IDS.includes(chatId.toString())) {
await sendMessage(env.BOT_TOKEN, chatId, '⛔ Unauthorized');
return new Response('OK');
}
GitHub Token 权限
使用 Fine-grained PAT,仅授予:
Actions: Read and writeContents: Read(用于验证工作流文件)
扩展性设计
命令路由系统
支持多仓库、多工作流:
/deploy repo-name staging
/build repo-name branch-name
/status repo-name workflow-id
配置映射表:
const REPO_MAP = {
'frontend': { owner: 'myorg', repo: 'frontend-app' },
'backend': { owner: 'myorg', repo: 'backend-api' }
};
异步状态跟踪
由于 GitHub Actions 执行是异步的,可以通过以下方式跟踪状态:
- Actions 中使用
appleboy/telegram-action发送完成通知 - Worker 中使用 Cloudflare KV 存储运行 ID,轮询检查状态
日志与监控
// 记录到 Cloudflare Analytics
ctx.waitUntil(
fetch('https://analytics.cloudflare.com/log', {
method: 'POST',
body: JSON.stringify({
command,
chatId,
timestamp: Date.now(),
success: response.ok
})
})
);
参考资料
- Cloudflare Workers Documentation - Workers 官方文档
- Telegram Bot API - Security Considerations - Webhook 安全指南
- Vercel Serverless Functions - Vercel 函数文档
- Pipedream Integration Platform - 低代码集成平台