Telegram通过GitHub Actions定时推送消息教程

本教程详细讲解如何利用GitHub Actions实现定时向Telegram推送消息,涵盖Bot创建、Workflow配置、定时策略与实战示例,助你轻松构建自动化通知服务。

阅读提示建议先浏览小标题,再根据需要深入阅读具体段落。

在日常工作与生活中,我们经常需要定时发送通知或提醒:每天早晨推送天气、每周一发送周报、整点报时、服务器监控告警等。Telegram作为一款安全、高效的即时通讯工具,结合GitHub Actions的持续集成能力,可以轻松实现免费、稳定且无需服务器的定时消息推送。本教程将手把手带你完成从Telegram Bot创建到GitHub Actions工作流配置的全过程,让你快速掌握这项自动化技巧。

准备工作:创建Telegram Bot并获取Chat ID

在开始之前,你需要一个Telegram账号,并创建一个Bot。Bot是Telegram中用于接收命令和发送消息的机器人账户,通过Bot API控制。

  1. 创建Bot:在Telegram中搜索并打开@BotFather,发送/newbot,按提示设置Bot名称和用户名(必须以bot结尾)。创建成功后,BotFather会返回一个HTTP API Token,形如123456789:ABCdef...,务必保存好这个Token。
  2. 获取你的Chat ID:向你的Bot发送任意一条消息(例如你好),然后访问https://api.telegram.org/bot<你的Token>/getUpdates,在返回的JSON中找到chat下的id字段,即为你的Chat ID。如果你要把消息发送到群组,需要将Bot拉入群组并发送消息,然后获取群组的Chat ID(通常以负号开头)。

创建GitHub Actions工作流

GitHub Actions是GitHub提供的持续集成与持续部署(CI/CD)服务,支持通过YAML文件定义工作流。我们可以利用其schedule事件来定时触发任务。

第一步:建立仓库与目录结构

在GitHub上新建一个仓库(或使用已有仓库),然后在仓库中创建.github/workflows目录,用于存放工作流文件。

第二步:编写工作流文件

.github/workflows下新建一个YAML文件,例如send-message.yml。基础结构如下:

name: Send Telegram Message

on:
  schedule:
    - cron: '0 9 * * *'  # 每天UTC时间9:00触发(北京时间17:00)
  workflow_dispatch:    # 允许手动触发

jobs:
  send:
    runs-on: ubuntu-latest
    steps:
      - name: Send message via API
        run: |
          curl -s -X POST "https://api.telegram.org/bot${{ secrets.TELEGRAM_BOT_TOKEN }}/sendMessage" \
            -d chat_id="${{ secrets.TELEGRAM_CHAT_ID }}" \
            -d text="你好,这是定时消息!"

在上面的示例中,我们使用secrets来保存Token和Chat ID,避免硬编码。你需要在仓库的SettingsSecrets and variablesActions中添加这两个Secret。

编写推送脚本:使用curl或Python

上面的示例直接用curl调用Telegram API,简单直接。但如果你需要更灵活的逻辑(如处理变量、发送Markdown格式、发送图片等),推荐使用Python脚本。

示例:Python脚本发送消息

  1. 在仓库根目录创建send_message.py
  2. 脚本内容:
import os
import sys
import requests

TOKEN = os.environ["TELEGRAM_BOT_TOKEN"]
CHAT_ID = os.environ["TELEGRAM_CHAT_ID"]

def send_message(text):
    url = f"https://api.telegram.org/bot/sendMessage"
    data = {"chat_id": CHAT_ID, "text": text}
    response = requests.post(url, data=data)
    return response.json()

if __name__ == "__main__":
    # 这里可以替换成你的动态内容,例如从文件读取或计算
    msg = "各位好,这是来自GitHub Actions的定时消息!"
    print(send_message(msg))
  1. 修改工作流文件,添加Python步骤:
jobs:
  send:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: '3.12'
      - run: pip install requests
      - run: python send_message.py
        env:
          TELEGRAM_BOT_TOKEN: ${{ secrets.TELEGRAM_BOT_TOKEN }}
          TELEGRAM_CHAT_ID: ${{ secrets.TELEGRAM_CHAT_ID }}

定时任务的Cron表达式详解

Github Actions的schedule事件使用POSIX cron语法,由5个字段组成:分钟(0-59)、小时(0-23)、日(1-31)、月(1-12)、星期(0-6,0为周日)。

  • 每天9点:0 9 * * *
  • 每小时的第15分:15 * * * *
  • 周一至周五早上8点:0 8 * * 1-5
  • 每月1号午夜:0 0 1 * *

时区注意:GitHub Actions默认使用UTC时区。如果你的目标时间是北京时间(UTC+8),需要自行换算。例如北京时间每天晚上8点,对应的UTC是中午12点:0 12 * * *

完整示例:每日定时推送天气预报

现在我们来一个更贴近实际的例子:每天早晨8点(北京时间)向Telegram推送指定城市的天气信息。

准备工作

我们需要一个天气API,例如使用OpenWeatherMap的免费接口(需要注册获取API Key),或者使用无需Key的wttr.in。这里以wttr.in为例,它无需Key,非常方便。

创建Python脚本

import os
import requests

TOKEN = os.environ["TELEGRAM_BOT_TOKEN"]
CHAT_ID = os.environ["TELEGRAM_CHAT_ID"]
CITY = os.environ.get("CITY", "Beijing")

def get_weather(city):
    url = f"https://wttr.in/?format=%C+%t"
    return requests.get(url).text.strip()

def send_message(text):
    url = f"https://api.telegram.org/bot/sendMessage"
    data = {"chat_id": CHAT_ID, "text": text}
    return requests.post(url, data=data).json()

if __name__ == "__main__":
    weather = get_weather(CITY)
    msg = f"早上好!今日天气:"
    print(send_message(msg))

工作流文件

name: Weather Report

on:
  schedule:
    - cron: '0 0 * * *'  # UTC 0:00 = 北京时间 8:00
  workflow_dispatch:

jobs:
  weather:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: '3.12'
      - run: pip install requests
      - run: python weather.py
        env:
          TELEGRAM_BOT_TOKEN: ${{ secrets.TELEGRAM_BOT_TOKEN }}
          TELEGRAM_CHAT_ID: ${{ secrets.TELEGRAM_CHAT_ID }}
          CITY: Beijing   # 可修改为你的城市

将以上文件提交到仓库后,GitHub Actions会在每天UTC 0:00自动运行,向你推送天气信息。

常见问题与注意事项

1. 时区与触发延迟

GitHub Actions的定时任务可能因服务器负载而有几分钟的延迟,并非精确到秒。对于大多数通知场景,这种延迟可以接受。如果对时间精度有要求,建议将任务设计为在目标时间前几分钟触发。

2. 确保Secret不被泄露

绝对不要将Bot Token写在代码或日志中。始终使用secrets,并在脚本中通过环境变量读取。同时,不要在任何输出中打印环境变量。

3. 消息长度与格式

Telegram API的sendMessage最大支持4096个字符。如果需要发送长消息,可以拆分多条或使用文件方式。另外,支持Markdown或HTML格式,通过parse_mode参数指定。

4. GitHub Actions的免费额度

公共仓库的Actions免费,私有仓库每月有2000分钟的免费额度,对个人项目通常足够。若超出,可考虑使用其他免费的CI服务(如GitLab CI)或自建。

总结

通过本教程,你已学会了如何利用GitHub Actions定时向Telegram推送消息。这一方案无需服务器、完全免费、配置灵活,适用于各类定时提醒、日报推送、监控告警等场景。你可以根据实际需求扩展脚本逻辑,例如发送图片、文件,或者集成多个数据源。现在就去动手试一下吧,让自动化为你节省宝贵时间。

FAQ

安装与配置指南

常见问题

GitHub Actions定时推送是免费的吗?

对于公共仓库,GitHub Actions是完全免费的。对于私有仓库,免费额度为每月2000分钟,执行简单API请求通常几秒内完成,个人使用绰绰有余。

如何修改定时推送的时间?

修改工作流文件中cron表达式的值即可。注意GitHub Actions默认UTC时区,需要换算成你的本地时间。

能否推送Markdown格式或图片?

可以。调用Telegram Bot API的sendMessage时添加parse_mode参数(如parse_mode=MarkdownV2或HTML)即可发送富文本;发送图片则可使用sendPhoto方法,并传递图片URL或文件。

如果推送失败,如何排查?

在GitHub仓库的Actions页面查看运行日志,常见的失败原因包括Token或Chat ID配置错误、网络问题、脚本语法错误等。确保Secrets已正确设置。

我可以使用GitHub Actions向群组推送消息吗?

可以。但你需要将Bot添加到目标群组,并获取该群组的Chat ID(通常是负数)。在sendMessage的chat_id参数中填入群组ID即可。