Telegram机器人定时推送每日天气或新闻到群组:完整开发指南

本文详细介绍如何用Python开发一个Telegram机器人,实现每天定时向指定群组推送天气预报或新闻摘要,包含BotFather创建、JobQueue调度、天气/新闻API调用等完整步骤和代码示例。

阅读提示涉及账号和安全设置时,请边阅读边核对当前设备界面。

引言

在信息爆炸的时代,我们每天都需要主动获取天气和新闻,而Telegram机器人可以替我们完成这项重复性劳动。通过一个简单的定时推送机器人,您可以将每日天气预报、热点新闻自动发送到指定的群组或频道,让成员无需离开Telegram即可掌握关键信息。本文将从零开始,手把手教您开发这样一个机器人,并附上完整的代码示例和部署要点。

准备工作:创建机器人与获取群组ID

在编写任何代码之前,您需要完成两项准备工作:创建Telegram机器人和获取目标群组的chat_id。

1. 通过BotFather创建机器人

在Telegram中搜索@BotFather,发送/newbot命令,按照提示设置机器人名称和用户名。创建成功后,您会获得一个API Token,形如123456789:ABCdef...xyz,请妥善保存。

2. 获取群组的chat_id

将刚创建的机器人添加到目标群组中,并授予发送消息的权限。然后向群组发送一条消息(例如/start),接着通过以下API获取更新:

curl "https://api.telegram.org/bot<YOUR_TOKEN>/getUpdates"

在返回的JSON中,找到chat对象的id字段,即为群组的chat_id(通常为负数)。如果群组中消息太多,也可以使用getChat方法,但需要先有chat_id。

环境搭建:安装必要的库

我们使用Python 3.8+进行开发,推荐使用python-telegram-bot v20+(异步版本),它内置了JobQueue调度器,非常适合定时任务。同时需要requests库来调用天气和新闻API。运行以下命令安装:

pip install python-telegram-bot requests

编写定时推送脚本:核心逻辑

下面给出一个完整的示例,实现每天早晨8点推送天气和新闻。您可以将天气API替换为心仪的服务(如OpenWeatherMap、和风天气),新闻API可使用NewsAPI等。为了演示,这里使用示例API。

import asyncio
import logging
from datetime import time
import requests
from telegram import Bot
from telegram.ext import Application, CommandHandler, ContextTypes

# 配置
BOT_TOKEN = "YOUR_BOT_TOKEN"
CHAT_ID = -1001234567890  # 群组chat_id

# 天气API配置(以OpenWeatherMap为例)
WEATHER_API_KEY = "YOUR_API_KEY"
CITY = "Beijing"
WEATHER_URL = "http://api.openweathermap.org/data/2.5/weather"

# 新闻API配置(以NewsAPI为例)
NEWS_API_KEY = "YOUR_NEWS_API_KEY"
NEWS_URL = "https://newsapi.org/v2/top-headlines"

logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")

def get_weather():
    params = {"q": CITY, "appid": WEATHER_API_KEY, "units": "metric", "lang": "zh_cn"}
    resp = requests.get(WEATHER_URL, params=params, timeout=10)
    data = resp.json()
    if data.get("cod") != 200:
        return "天气信息获取失败"
    weather = data["weather"][0]["description"]
    temp = data["main"]["temp"]
    humidity = data["main"]["humidity"]
    wind = data["wind"]["speed"]
    return f"🌤 城市:\n天气:\n温度:°C\n湿度:%\n风速:m/s"

def get_news():
    params = {"country": "cn", "apiKey": NEWS_API_KEY, "pageSize": 5}
    resp = requests.get(NEWS_URL, params=params, timeout=10)
    data = resp.json()
    if data.get("status") != "ok":
        return "新闻获取失败"
    articles = data["articles"]
    return "\n\n".join([f"📰 {a['title']}\n{a['url']}" for a in articles])

async def daily_push(context: ContextTypes.DEFAULT_TYPE):
    weather = get_weather()
    news = get_news()
    message = f"🌅 每日播报\n\n--- 天气 ---\n\n\n--- 新闻 ---\n"
    await context.bot.send_message(chat_id=CHAT_ID, text=message, disable_web_page_preview=True)

def main():
    app = Application.builder().token(BOT_TOKEN).build()

    # 设置每日任务,时间为早上8点(UTC+8时区)
    app.job_queue.run_daily(daily_push, time=time(hour=8, minute=0, tzinfo=timezone(timedelta(hours=8))))

    # 启动Bot
    app.run_polling()

if __name__ == "__main__":
    main()

请注意:timezonetimedelta需要从datetime导入,你需要修改代码开头的import部分添加:from datetime import time, timedelta, timezone

代码说明

  • get_weather():调用天气API,返回整理好的文本。
  • get_news():调用新闻API,返回前5条标题和链接。
  • daily_push():异步函数,组合消息并发送到目标群组。
  • app.job_queue.run_daily():使用JobQueue设置每日定时任务,支持时区。

您也可以使用run_dailydays参数来指定每周几推送,例如days=(0,2,4)表示周一、三、五。

部署与运行:保持机器人7×24小时在线

本地运行python bot.py即可,但一旦关闭终端,机器人就会停止工作。为长期运行,推荐使用云服务器,并采用以下两种方式之一管理进程。

方案A:使用systemd服务

创建/etc/systemd/system/telegram-bot.service文件,内容如下:

[Unit]
Description=Telegram Daily Push Bot
After=network.target

[Service]
ExecStart=/usr/bin/python3 /path/to/bot.py
Restart=always
User=yourusername

[Install]
WantedBy=multi-user.target

然后运行sudo systemctl enable --now telegram-bot即可开机自启。

方案B:使用Docker

编写一个简单的Dockerfile

FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY bot.py .
CMD ["python", "bot.py"]

构建并运行容器即可。

常见问题与优化建议

问题1:如何获取群组chat_id?

将机器人加入群组后,发送一条消息,然后访问getUpdates接口解析chat.id。如果遇到冲突,可以尝试将机器人暂时设为管理员,或者使用@RawDataBot这类辅助机器人获取。

问题2:定时任务不触发怎么办?

检查时区设置是否正确,time参数中的tzinfo必须明确指定。同时确认服务器时间与UTC同步。

问题3:如何推送多条时间?

使用run_daily多次调用即可,例如分别在早上8点和晚上8点推送,只需创建两个不同的函数或传入不同内容。

优化建议

  • 在发送消息前加入try/except捕获网络异常,避免因API超时导致崩溃。
  • 将API密钥和chat_id存入环境变量,不要硬编码在代码中。
  • 如果推送内容包含图片,可以使用send_photo方法,并配合每日更新一次的图片URL。
  • 对于多个群组,可以维护一个chat_id列表循环发送。

总结

本文从创建机器人到部署上线,完整地演示了如何实现Telegram机器人定时推送天气和新闻。只需少量代码,您就能为自己的群组打造一个实用的信息助手。您可以根据需要扩展功能,比如添加股票行情、每日一句、RSS订阅等。希望这个指南能帮助您快速入门Telegram机器人开发,享受自动化带来的便利。

FAQ

下载与安装

常见问题

如何获取Telegram群组的chat_id?

将机器人添加到群组后,向群组发送任意消息(如/start),然后访问https://api.telegram.org/bot<你的令牌>/getUpdates,在返回的JSON中查找chat对象的id字段。如果id是负数,就是群组的chat_id。

定时推送的时区如何设置?

在python-telegram-bot的run_daily方法中,time参数需要传入带tzinfo的时间对象。例如time(hour=8, minute=0, tzinfo=timezone(timedelta(hours=8)))表示北京时间早上8点。确保服务器时区与程序设置一致。

可以使用免费天气API吗?

可以。OpenWeatherMap提供免费套餐(每分钟60次调用),和风天气也有免费版。您只需要替换get_weather函数中的API地址、密钥和参数即可。

如何避免机器人重复推送消息?

定时任务本身一天只触发一次。但如果脚本意外重启,JobQueue会基于当前时间重新计算,不会重复。若担心多个实例运行,可以使用锁文件或数据库标记当天已推送。