请登录后探索更多精彩内容!
以前找 moe.one 要了一个 TG 新帖推送插件,我上 TG 上的少没细心关注,这几天才发现这个推送机器人抽风很厉害,不能做到实时推送,中间会间隔一堆才推一次,看不懂代码逻辑,于是自己在网上找了 RSS 订阅 BOT 部署,试了两个用的人多的项目,都是 docker 部署,我想改改消息格式都不知道怎么下手,实在对 docker 不懂... 默认的消息格式让我强迫症实在难受,于是让 AI 配合写了如下 Python 脚本,此文记录一下搭建步骤,避免以后有需要时又要去找 AI 掰扯。
打开服务器终端,安装 Python 和所需库
安装 pip更新包列表:
apt update
安装 python3-pip:
apt install python3-pip
安装完成后,确认 pip 是否正确安装:
pip3 --version
正常会返回 pip 的版本信息。
安装所需库
pip3 install feedparser requests python-telegram-bot
下一步,我们需要去 Telegram 创建 Bot,在 TG 里搜索 @BotFather,进入对话框,输入 /newbot 以创建新机器人,然后回复一个机器人名字,再回复一个机器人的用户名,需要带 bot,可以参考截图设置:
@BotFather 会回复你一个机器人的 HTTP API,保存它,后面会用到。
进入刚刚创建的机器人对话框,将他拉进一个你需要推送的群,或者直接给你自己推送也行,拉群记得给它管理员和消息权限。
TG 搜索 @get_id_bot,进入对话框点击右上角,将他拉到刚刚的群里,在群聊对话框输入:/my_id@get_id_bot 发送,会得到一个 - 开头的群聊 ID,记录它,包括 - 符号。
信息获取完成,接下来就是创建脚本了,回到服务器终端
mkdir dalaorss cd dalaorss
nano rss_bot.py
import feedparser import logging import asyncio import json import os import html # 导入 html 模块 from telegram import Bot from telegram.error import TelegramError # Telegram Bot Token 和目标聊天 ID TELEGRAM_TOKEN = '你的机器人API' CHAT_ID = '你的群聊ID' # 存储已发送的帖子 ID 的文件 POSTS_FILE = 'sent_posts.json' # 读取已发送的帖子 ID def load_sent_posts(): if os.path.exists(POSTS_FILE): with open(POSTS_FILE, 'r') as f: return json.load(f) return [] # 保存已发送的帖子 ID def save_sent_posts(post_ids): with open(POSTS_FILE, 'w') as f: json.dump(post_ids, f) # 从 RSS 源获取更新 def fetch_updates(): feed_url = "你的订阅地址" try: return feedparser.parse(feed_url) except Exception as e: logging.error(f"获取 RSS 更新时出错: {e}") return None # 转义 Markdown 特殊字符 def escape_markdown(text): special_chars = r"_*[]()~`>#+-.!" for char in special_chars: text = text.replace(char, f"\\{char}") return text # 发送消息到 Telegram async def send_message(bot, title, link): # 使用 html 转义处理标题和链接 escaped_title = html.escape(title) # 转义标题 escaped_link = html.escape(link) # 转义链接 # 转义 Markdown 特殊字符 escaped_title = escape_markdown(escaped_title) # 转义 Markdown 特殊字符 escaped_link = escape_markdown(escaped_link) # 转义 Markdown 特殊字符 # 使用 Markdown 格式,将标题直接放在文本中,链接直接显示 message = f"标题:{escaped_title}\n链接:{escaped_link}" # 直接使用标题而不加反引号 try: await bot.send_message(chat_id=CHAT_ID, text=message, parse_mode='MarkdownV2') logging.info(f"消息发送成功: {escaped_title}") except TelegramError as e: logging.error(f"发送消息时出错: {e}") # 主函数 async def check_for_updates(sent_post_ids): updates = fetch_updates() if updates is None: return # 如果获取更新出错,则返回 new_post_ids = [] # 用于存储新帖子 ID for entry in updates.entries: # 从 guid 中提取帖子 ID post_id = entry.guid.split('-')[-1].split('.')[0] # 提取 ID # 检查是否为新帖子 if post_id not in sent_post_ids: new_post_ids.append((post_id, entry.title, entry.link)) # 存储 ID, 标题和链接 # 如果有新帖子,按 ID 升序排序并发送最新帖子 if new_post_ids: new_post_ids.sort(key=lambda x: int(x[0])) # 升序排序 latest_post_id, title, link = new_post_ids[0] # 获取最新的帖子 async with Bot(token=TELEGRAM_TOKEN) as bot: await send_message(bot, title, link) # 更新已发送的帖子 ID sent_post_ids.append(latest_post_id) save_sent_posts(sent_post_ids) # 保存到文件 # 主循环 async def main(): logging.basicConfig(level=logging.INFO) # 加载已发送的帖子 ID sent_post_ids = load_sent_posts() while True: try: await check_for_updates(sent_post_ids) except Exception as e: logging.error(f"检查更新时出错: {e}") await asyncio.sleep(60) # 每 60 秒检查一次 if __name__ == "__main__": asyncio.run(main())
nohup python3 rss_bot.py &
现在就可以去更新 rss 看看推送状态了,这里的脚本内容以我自己论坛为例,如果你也是 xiuno 论坛那么照抄就行,如果是博客或者其它程序,可能还需要做一些修改。
推送效果:
个人比较喜欢这种格式,如果你喜欢别的模式比如消息内预览,可以使用 docker 版本的,网上搜一下就有。
脚本运行后,怎么查看或关闭:
检查当前运行的进程
ps aux | grep python
会得到正在运行的进程,查看到 rss_bot 那条,最前面有一个 ID,命令行输入
kill ID
即可停止。
查看输出日志
cat nohup.out
暂无评论
暂无评论