不用每天手动刷 GitHub,写一个脚本自动监控你关注的仓库,有新提交、新 Release 或新 Issue 时立即推送到微信/邮件/Telegram。
你有没有这种情况:关注了好几个 GitHub 项目,想跟踪它们的动态,但每天手动刷太麻烦,刷多了又怕漏掉重要的更新。
或者你维护了几个私有仓库,想第一时间知道有没有人提 Issue、有没有新 Release、有没有新 Commit。
手动盯 GitHub 太累了,让脚本帮你盯。
这个项目用 Python + GitHub API,实现一个轻量级的仓库更新监控工具。有新动态时,自动推送到你的微信、邮件或 Telegram。
项目背景
GitHub 官方有 Watch 功能,但通知太杂:每个 commit、每个 PR、每个 Issue 都会发邮件,三天不看邮箱就爆炸了。
我们需要的是:只推送真正重要的更新——新 Release、高星 PR、关键 Issue,而且推送到我们常用的渠道(微信/Telegram/飞书)。
用 GitHub REST API 查询最新状态,跟本地记录对比,有变化就推送。全程自动化,一行命令搞定。
技术选型
| 组件 | 选型 | 理由 |
|---|---|---|
| 语言 | Python 3.10+ | 生态丰富,GitHub API 库成熟 |
| API | GitHub REST API v3 | 稳定、文档完善、无需 OAuth 即可读公开仓库 |
| 存储 | JSON 文件 | 零依赖,记录每个仓库的最后状态 |
| 推送 | 微信/邮件/Telegram | 按偏好配置,支持多选 |
| 调度 | cron / systemd timer | 每 30 分钟检查一次 |
不需要数据库,不需要服务器,一个 Python 脚本 + 一个定时任务就够了。
实现步骤
第一步:安装依赖
pip install pygithub requests
只装两个包。pygithub 操作 GitHub API,requests 做推送。
第二步:准备配置文件
在项目目录下创建 config.json:
{
"repositories": [
{
"name": "facebook/react",
"channels": ["wechat", "telegram"],
"notify": {"release": true, "issue": true, "star": true}
},
{
"name": "vercel/next.js",
"channels": ["telegram"],
"notify": {"release": true, "issue": false, "star": false}
}
],
"push": {
"wechat_webhook": "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=YOUR_KEY",
"telegram_bot_token": "YOUR_BOT_TOKEN",
"telegram_chat_id": "YOUR_CHAT_ID",
"email_smtp": "smtp.qq.com",
"email_user": "your@qq.com",
"email_password": "YOUR_APP_PASSWORD",
"email_to": "your@qq.com"
},
"interval_minutes": 30
}
按需填写。公开仓库不需要 Token,私有仓库需要 GitHub Personal Access Token,加到配置里即可。
第三步:写监控脚本
创建 monitor.py:
#!/usr/bin/env python3
"""GitHub 仓库更新监控工具"""
import json
import time
import requests
from pathlib import Path
from datetime import datetime
# ============ 配置加载 ============
CONFIG_PATH = Path(__file__).parent / "config.json"
STATE_PATH = Path(__file__).parent / "state.json"
def load_config():
with open(CONFIG_PATH) as f:
return json.load(f)
def load_state():
if STATE_PATH.exists():
with open(STATE_PATH) as f:
return json.load(f)
return {}
def save_state(state):
with open(STATE_PATH, "w") as f:
json.dump(state, f, indent=2)
# ============ GitHub API 查询 ============
GITHUB_TOKEN = "" # 私有仓库时填写 Personal Access Token
HEADERS = {"Authorization": f"token {GITHUB_TOKEN}"} if GITHUB_TOKEN else {}
def get_latest_release(repo_name):
url = f"https://api.github.com/repos/{repo_name}/releases/latest"
resp = requests.get(url, headers=HEADERS, timeout=10)
if resp.status_code == 200:
return resp.json()["tag_name"]
return None
def get_open_issues_count(repo_name):
url = f"https://api.github.com/search/issues?q=repo:{repo_name}+is:open+is:issue"
resp = requests.get(url, headers=HEADERS, timeout=10)
if resp.status_code == 200:
return resp.json()["total_count"]
return None
def get_stargazers_count(repo_name):
url = f"https://api.github.com/repos/{repo_name}"
resp = requests.get(url, headers=HEADERS, timeout=10)
if resp.status_code == 200:
return resp.json()["stargazers_count"]
return None
# ============ 推送函数 ============
def push_wechat(webhook_url, text):
payload = {
"msgtype": "text",
"text": {"content": text}
}
requests.post(webhook_url, json=payload, timeout=10)
def push_telegram(bot_token, chat_id, text):
url = f"https://api.telegram.org/bot{bot_token}/sendMessage"
requests.post(url, json={"chat_id": chat_id, "text": text}, timeout=10)
def push_email(smtp_server, user, password, to, subject, body):
import smtplib
from email.mime.text import MIMEText
msg = MIMEText(body, "plain", "utf-8")
msg["Subject"] = subject
msg["From"] = user
msg["To"] = to
with smtplib.SMTP(smtp_server, 587) as s:
s.starttls()
s.login(user, password)
s.sendmail(user, [to], msg.as_string())
def send_notifications(repo_name, changes, push_config):
lines = [f"🔔 GitHub 仓库更新: {repo_name}"]
for change in changes:
lines.append(f" • {change}")
text = "\n".join(lines)
if "wechat" in push_config.get("channels", []):
webhook = push_config.get("wechat_webhook")
if webhook:
push_wechat(webhook, text)
if "telegram" in push_config.get("channels", []):
token = push_config.get("telegram_bot_token")
chat_id = push_config.get("telegram_chat_id")
if token and chat_id:
push_telegram(token, chat_id, text)
if "email" in push_config.get("channels", []):
smtp = push_config.get("email_smtp")
user = push_config.get("email_user")
pwd = push_config.get("email_password")
to = push_config.get("email_to")
if smtp and user:
push_email(smtp, user, pwd, to, f"[GitHub] {repo_name} 有更新", text)
# ============ 主逻辑 ============
def check_repos():
config = load_config()
state = load_state()
push_cfg = config["push"]
for repo in config["repositories"]:
repo_name = repo["name"]
notify = repo.get("notify", {})
changes = []
# 初始化 state
if repo_name not in state:
state[repo_name] = {}
# 检查 Release
if notify.get("release", True):
current_release = get_latest_release(repo_name)
last_release = state[repo_name].get("release")
if current_release and current_release != last_release:
changes.append(f"🎉 新 Release: {current_release}")
state[repo_name]["release"] = current_release
# 检查 Issue
if notify.get("issue", True):
current_issues = get_open_issues_count(repo_name)
last_issues = state[repo_name].get("issues", 0)
if current_issues is not None and current_issues > last_issues:
changes.append(f"📝 新增 {current_issues - last_issues} 个 Issue")
state[repo_name]["issues"] = current_issues
# 检查 Star
if notify.get("star", False):
current_stars = get_stargazers_count(repo_name)
last_stars = state[repo_name].get("stars", 0)
if current_stars is not None and current_stars > last_stars:
changes.append(f"⭐ 新增 {current_stars - last_stars} 个 Star")
state[repo_name]["stars"] = current_stars
# 推送
if changes:
print(f"[{datetime.now()}] {repo_name}: {changes}")
send_notifications(repo_name, changes, {**repo, **push_cfg})
else:
print(f"[{datetime.now()}] {repo_name}: 无更新")
save_state(state)
if __name__ == "__main__":
check_repos()
第四步:设置定时任务
用 cron 每 30 分钟运行一次:
# 编辑 crontab
crontab -e
# 添加这一行(每30分钟执行)
*/30 * * * * /usr/bin/python3 /home/youruser/github-monitor/monitor.py >> /home/youruser/github-monitor/monitor.log 2>&1
或者用 systemd timer(更优雅):
# /etc/systemd/system/github-monitor.service
[Unit]
Description=GitHub Repo Monitor
[Service]
Type=oneshot
ExecStart=/usr/bin/python3 /home/youruser/github-monitor/monitor.py
WorkingDirectory=/home/youruser/github-monitor
# /etc/systemd/system/github-monitor.timer
[Unit]
Description=Run GitHub Monitor every 30 minutes
[Timer]
OnBootSec=5min
OnUnitActiveSec=30min
Unit=github-monitor.service
[Install]
WantedBy=timers.target
sudo systemctl enable --now github-monitor.timer
第五步:推送渠道配置
企业微信机器人:在企业微信群设置 → 群机器人 → 添加机器人 → 复制 Webhook 地址填入配置。
Telegram Bot:找 @BotFather 创建 bot,拿到 Token;创建群组把 bot 加进去,拿到 Chat ID(用 @userinfobot 查)。
邮件推送:QQ 邮箱开启 SMTP 服务,获取授权码作为 email_password。
运行效果
脚本启动后,每分钟检查一次配置的仓库:
[2026-08-21 10:00:01] facebook/react: 无更新
[2026-08-21 10:30:02] facebook/react: 无更新
[2026-08-21 11:00:01] vercel/next.js: 无更新
[2026-08-21 11:30:02] facebook/react: ['🎉 新 Release: v19.0.0', '⭐ 新增 1200 个 Star']
有新 Release 时,你的企业微信群会收到:
🔔 GitHub 仓库更新: facebook/react • 🎉 新 Release: v19.0.0 • ⭐ 新增 1200 个 Star
简洁明了,没有噪音。
优化方向
已经能用了,想继续加也可以:
- 支持 GitHub Event Webhook:主动接收推送,不用轮询,更实时
- 支持 PR 监控:有合并请求时推送,方便代码审查
- 支持 Fork 监控:有人 Fork 你的仓库时通知
- 加一个简单的 Web 仪表盘:用 Flask 搭个页面,查看所有监控仓库的状态
- 支持多语言通知:根据仓库语言自动选择通知文案
- 加入 AI 摘要:用大模型对 Release Note 生成中文摘要,更适合国内用户
- 支持 Discord/Slack/飞书:扩展更多推送渠道
一行 Python 脚本,半小时搞定,以后再也不用手动刷 GitHub 了。你关注哪些仓库?要不要加个监控?
这篇文章对你有帮助吗?