教程:每日简报机器人
This guide will walk you through creating a fully automated daily briefing bot that researches topics, summarizes findings, and delivers them to Telegram or Discord every morning.
Overview
The bot will:
- Run automatically every morning
- Research current events and trending topics
- Generate concise summaries using AI
- Deliver the briefing via Telegram or Discord
Step 1: Choose Your Platform
Option A: Telegram
- Create a bot using BotFather
- Get your API token (e.g.,
123456789:ABCdefGHIjklMNOpqrSTUVwxyZ) - Add the bot to your private group or channel
Option B: Discord
- Create a server application at Discord Developer Portal
- Enable "Bot" and generate a token
- Invite the bot to your server with appropriate permissions
Step 2: Set Up the Environment
# Create project directory
mkdir daily-briefing-bot && cd daily-briefing-bot
# Initialize Python environment
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install dependencies
pip install requests python-dotenv schedule openai telegram-bot-api discord.py
Step 3: Configure Environment Variables
Create a .env file:
# Platform Configuration
PLATFORM=telegram # or 'discord'
# API Keys
TELEGRAM_TOKEN=123456789:ABCdefGHIjklMNOpqrSTUVwxyZ
DISCORD_TOKEN=your_discord_bot_token_here
# AI Provider
AI_PROVIDER=openai # or 'openrouter', 'anthropic'
OPENAI_API_KEY=sk-your-openai-key-here
OPENROUTER_API_KEY=your-openrouter-key-here
# Delivery Settings
CHANNEL_ID=1234567890 # Telegram chat ID or Discord channel ID
TIMEZONE=America/New_York # Use IANA timezone format
BRIEFING_TIME=08:00 # 24-hour format
# Research Topics (comma-separated)
TOPICS="AI news, climate change, global markets, tech innovations"
Step 4: Create the Core Bot Script
bot.py
import os
import json
import schedule
import time
from datetime import datetime, timedelta
from dotenv import load_dotenv
import requests
import openai
from typing import List, Dict, Any
load_dotenv()
class DailyBriefingBot:
def __init__(self):
self.platform = os.getenv("PLATFORM")
self.api_key = os.getenv("OPENAI_API_KEY") if os.getenv("AI_PROVIDER") == "openai" else os.getenv("OPENROUTER_API_KEY")
self.ai_provider = os.getenv("AI_PROVIDER")
self.topics = [t.strip() for t in os.getenv("TOPICS").split(",")]
self.channel_id = os.getenv("CHANNEL_ID")
self.timezone = os.getenv("TIMEZONE")
self.briefing_time = os.getenv("BRIEFING_TIME")
# Initialize OpenAI client
if self.ai_provider == "openai":
openai.api_key = self.api_key
elif self.ai_provider == "openrouter":
openai.api_key = self.api_key
openai.base_url = "https://openrouter.ai/api/v1/"
def get_current_news(self, topic: str) -> List[Dict[str, str]]:
"""Fetch recent news articles for a given topic"""
try:
# Using NewsAPI (free tier available)
api_key = os.getenv("NEWSAPI_KEY") or "your-newsapi-key"
url = f"https://newsapi.org/v2/everything?q={topic}&language=en&sortBy=publishedAt&pageSize=5&apiKey={api_key}"
response = requests.get(url)
if response.status_code == 200:
data = response.json()
return [
{
"title": article["title"],
"description": article["description"] or article["content"],
"url": article["url"],
"published_at": article["publishedAt"]
}
for article in data.get("articles", [])
]
else:
print(f"Error fetching news for {topic}: {response.status_code}")
return []
except Exception as e:
print(f"Exception while fetching news: {e}")
return []
def summarize_with_ai(self, content: str, topic: str) -> str:
"""Generate a concise summary using AI"""
prompt = f"""
Summarize the following news content about '{topic}' in 3-5 bullet points.
Keep it concise, factual, and suitable for a daily briefing.
Content:
{content}
Summary:
"""
try:
if self.ai_provider == "openai":
response = openai.ChatCompletion.create(
model="gpt-4-turbo",
messages=[
{"role": "system", "content": "You are a professional news summarizer."},
{"role": "user", "content": prompt}
],
max_tokens=300,
temperature=0.3
)
return response.choices[0].message.content.strip()
elif self.ai_provider == "openrouter":
response = openai.ChatCompletion.create(
model="meta-llama/llama-3-8b-instruct",
messages=[
{"role": "system", "content": "You are a professional news summarizer."},
{"role": "user", "content": prompt}
],
max_tokens=300,
temperature=0.3
)
return response.choices[0].message.content.strip()
except Exception as e:
print(f"AI summarization error: {e}")
return "Unable to generate summary."
def format_briefing_message(self) -> str:
"""Compile all research into a formatted message"""
message_parts = []
for topic in self.topics:
print(f"Researching: {topic}")
articles = self.get_current_news(topic)
if not articles:
continue
# Extract content for summarization
content = "\n\n".join([
f"Title: {a['title']}\nSource: {a['url']}\nSummary: {a['description'][:200]}..."
for a in articles
])
summary = self.summarize_with_ai(content, topic)
message_parts.append(f"### {topic.upper()}\n{summary}\n")
return "\n".join(message_parts)
def send_to_telegram(self, message: str):
"""Send message to Telegram"""
url = f"https://api.telegram.org/bot{os.getenv('TELEGRAM_TOKEN')}/sendMessage"
payload = {
"chat_id": self.channel_id,
"text": message,
"parse_mode": "MarkdownV2"
}
try:
response = requests.post(url, json=payload)
if response.status_code == 200:
print("✅ Message sent to Telegram")
else:
print(f"❌ Telegram error: {response.status_code} - {response.text}")
except Exception as e:
print(f"Telegram send error: {e}")
def send_to_discord(self, message: str):
"""Send message to Discord"""
url = f"https://discord.com/api/v10/channels/{self.channel_id}/messages"
headers = {
"Authorization": f"Bot {os.getenv('DISCORD_TOKEN')}",
"Content-Type": "application/json"
}
payload = {
"content": message
}
try:
response = requests.post(url, json=payload, headers=headers)
if response.status_code == 200:
print("✅ Message sent to Discord")
else:
print(f"❌ Discord error: {response.status_code} - {response.text}")
except Exception as e:
print(f"Discord send error: {e}")
def deliver_briefing(self):
"""Main function to run the daily briefing"""
print(f"⏰ Starting daily briefing at {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
# Format the briefing
briefing = self.format_briefing_message()
if not briefing.strip():
print("⚠️ No content to deliver")
return
# Send via selected platform
if self.platform == "telegram":
self.send_to_telegram(briefing)
elif self.platform == "discord":
self.send_to_discord(briefing)
print("✅ Daily briefing completed!")
def run_scheduler(self):
"""Set up scheduled execution"""
# Schedule to run daily at specified time
schedule.every().day.at(self.briefing_time).do(self.deliver_briefing)
print(f"📅 Daily briefing scheduled for {self.briefing_time} ({self.timezone})")
# Keep the script running
while True:
schedule.run_pending()
time.sleep(60)
if __name__ == "__main__":
bot = DailyBriefingBot()
bot.run_scheduler()
Step 5: Add Optional Enhancements
Add RSS Feed Support
# In get_current_news(), add RSS support
import feedparser
def get_rss_feed(self, url: str) -> List[Dict]:
feed = feedparser.parse(url)
return [
{
"title": entry.title,
"description": entry.summary,
"url": entry.link,
"published_at": entry.published
}
for entry in feed.entries[:5]
]
Add Custom Topic Sources
# Add to .env
CUSTOM_SOURCES="techcrunch.com/rss,coindesk.com/feed"
# In bot.py, parse and use custom sources
sources = [s.strip() for s in os.getenv("CUSTOM_SOURCES").split(",")]
for source in sources:
articles.extend(self.get_rss_feed(source))
Add Image Attachments
# For Telegram
def send_with_image(self, message: str, image_url: str):
url = f"https://api.telegram.org/bot{os.getenv('TELEGRAM_TOKEN')}/sendPhoto"
payload = {
"chat_id": self.channel_id,
"caption": message,
"photo": image_url
}
requests.post(url, json=payload)
Step 6: Deploy & Monitor
Local Testing
python bot.py
Production Deployment Options
Option A: VPS (e.g., AWS EC2, DigitalOcean)
# On Ubuntu/Debian
sudo apt update
sudo apt install python3-pip git cron
git clone https://github.com/your-repo/daily-briefing-bot.git
cd daily-briefing-bot
source venv/bin/activate
pip install -r requirements.txt
# Add to crontab: 0 8 * * * /path/to/venv/bin/python /path/to/bot.py
Option B: Cloud Services
- AWS Lambda + EventBridge: Trigger daily
- Google Cloud Functions: Scheduled triggers
- Modal.com: Run Python scripts with cron-like scheduling
Step 7: Monitor & Maintain
Logging
Add logging to track performance:
import logging
logging.basicConfig(filename='bot.log', level=logging.INFO)
Health Checks
Add periodic health checks:
def check_health(self):
# Test API connectivity
# Check database connection
# Log status
pass
Final Notes
Your automated daily briefing bot is now ready! It will:
- Run automatically every morning
- Research trending topics across multiple sources
- Generate concise, AI-powered summaries
- Deliver professional briefings to your preferred platform
For advanced features, consider integrating:
- Sentiment analysis
- Personalized topic preferences
- Interactive feedback loops
- Multi-language support
🌟 Pro Tip: Use agentskills.io to discover pre-built AI agents and templates for even faster deployment.
Start your automation journey today and never miss a beat in the fast-moving world of information!"
教程:构建每日简报机器人
在本教程中,你将创建一个个人化简报机器人,它每天早晨自动启动,研究你关心的主题,总结发现内容,并将简洁的简报直接发送到你的 Telegram 或 Discord。
完成后,你将拥有一个完全自动化的流程,结合了 网络搜索、定时调度、任务委派 和 消息推送 —— 无需编写任何代码。
我们要构建什么?
以下是整个工作流:
- 早上 8:00 —— 定时调度器触发你的任务
- Hermes 启动 一个全新的代理会话,并加载你的提示(prompt)
- 网络搜索 获取你关注主题的最新资讯
- 内容摘要 将信息提炼为清晰易读的简报格式
- 消息推送 将简报发送至你的 Telegram 或 Discord
整个过程全自动运行。你只需在喝咖啡时阅读简报即可。
准备工作
开始前,请确保你已具备以下条件:
- 已安装 Hermes Agent —— 参见 安装指南
- 已运行网关(Gateway) —— 网关守护进程负责执行定时任务:
hermes gateway install # 以用户服务方式安装
sudo hermes gateway install --system # Linux 服务器:开机自启系统服务
# 或
hermes gateway # 前台运行 - Firecrawl API 密钥 —— 在环境变量中设置
FIRECRAWL_API_KEY以启用网络搜索 - 已配置消息通道(可选但推荐)—— Telegram 或 Discord 设置好主频道
你仍然可以完成本教程,使用 deliver: "local"。简报将保存至 ~/.hermes/cron/output/,你可以随时查看。
第一步:手动测试工作流
在自动化之前,先确认简报功能正常。启动一个聊天会话:
hermes
然后输入以下提示:
Search for the latest news about AI agents and open source LLMs.
Summarize the top 3 stories in a concise briefing format with links.
Hermes 将自动进行网络搜索,阅读结果,并生成类似如下内容的输出:
☀️ Your AI Briefing — March 8, 2026
1. Qwen 3 Released with 235B Parameters
Alibaba's latest open-weight model matches GPT-4.5 on several
benchmarks while remaining fully open source.
→ https://qwenlm.github.io/blog/qwen3/
2. LangChain Launches Agent Protocol Standard
A new open standard for agent-to-agent communication gains
adoption from 15 major frameworks in its first week.
→ https://blog.langchain.dev/agent-protocol/
3. EU AI Act Enforcement Begins for General-Purpose Models
The first compliance deadlines hit, with open source models
receiving exemptions under the 10M parameter threshold.
→ https://artificialintelligenceact.eu/updates/
---
3 stories • Sources searched: 8 • Generated by Hermes Agent
如果成功,说明你可以进入下一步自动化流程。
不断尝试不同的提示,直到获得你喜欢的输出效果。可以加入如“使用表情符号标题”或“每段摘要不超过两句话”等指令。最终选定的提示将用于定时任务。
第二步:创建定时任务
现在让我们将此流程设置为每天早晨自动运行。有两种方式可选。
选项 A:自然语言(在聊天中)
只需告诉 Hermes 你的需求即可:
Every morning at 8am, search the web for the latest news about AI agents
and open source LLMs. Summarize the top 3 stories in a concise briefing
with links. Use a friendly, professional tone. Deliver to telegram.
Hermes 会使用统一的 cronjob 工具为你自动生成定时任务。
选项 B:CLI 斜杠命令
若需要更多控制权,可使用 /cron 命令:
/cron add "0 8 * * *" "Search the web for the latest news about AI agents and open source LLMs. Find at least 5 recent articles from the past 24 hours. Summarize the top 3 most important stories in a concise daily briefing format. For each story include: a clear headline, a 2-sentence summary, and the source URL. Use a friendly, professional tone. Format with emoji bullet points and end with a total story count."
黄金法则:自包含的提示
定时任务在 完全独立的新会话 中运行 —— 不保留之前的对话记忆,也不会继承你“之前设置”的上下文。因此,你的提示必须 包含所有必要信息,让代理能独立完成任务。
糟糕的提示:
Do my usual morning briefing.
优秀的提示:
Search the web for the latest news about AI agents and open source LLMs.
Find at least 5 recent articles from the past 24 hours. Summarize the
top 3 most important stories in a concise daily briefing format. For each
story include: a clear headline, a 2-sentence summary, and the source URL.
Use a friendly, professional tone. Format with emoji bullet points.
好的提示明确指出了 要搜索的内容、文章数量、输出格式 和 语气风格。它把代理所需的一切都整合在一个提示中。
第三步:自定义简报内容
一旦基础简报功能正常,就可以开始创意发挥了。
多主题简报
一次覆盖多个领域:
/cron add "0 8 * * *" "Create a morning briefing covering three topics. For each topic, search the web for recent news from the past 24 hours and summarize the top 2 stories with links.
Topics:
1. AI and machine learning — focus on open source models and agent frameworks
2. Cryptocurrency — focus on Bitcoin, Ethereum, and regulatory news
3. Space exploration — focus on SpaceX, NASA, and commercial space
Format as a clean briefing with section headers and emoji. End with today's date and a motivational quote."
使用委派实现并行研究
为了更快生成简报,可指示 Hermes 将每个主题分派给子代理:
/cron add "0 8 * * *" "Create a morning briefing by delegating research to sub-agents. Delegate three parallel tasks:
1. Delegate: Search for the top 2 AI/ML news stories from the past 24 hours with links
2. Delegate: Search for the top 2 cryptocurrency news stories from the past 24 hours with links
3. Delegate: Search for the top 2 space exploration news stories from the past 24 hours with links
Collect all results and combine them into a single clean briefing with section headers, emoji formatting, and source links. Add today's date as a header."
每个子代理独立且并行地进行搜索,主代理再将结果整合成一份精炼的简报。详情请参阅 委派文档。
仅工作日调度
不需要周末的简报?使用仅限周一至周五的 cron 表达式:
/cron add "0 8 * * 1-5" "Search for the latest AI and tech news..."
每日两次简报
获取早间概览和晚间回顾:
/cron add "0 8 * * *" "Morning briefing: search for AI news from the past 12 hours..."
/cron add "0 18 * * *" "Evening recap: search for AI news from the past 12 hours..."
通过记忆添加个人背景
如果你启用了 记忆功能,可以存储跨会话持久的偏好设置。但请注意 —— 定时任务在全新会话中运行,不携带对话记忆。要添加个人上下文,需直接将信息嵌入提示中:
/cron add "0 8 * * *" "You are creating a briefing for a senior ML engineer who cares about: PyTorch ecosystem, transformer architectures, open-weight models, and AI regulation in the EU. Skip stories about product launches or funding rounds unless they involve open source.
Search for the latest news on these topics. Summarize the top 3 stories with links. Be concise and technical — this reader doesn't need basic explanations."
在提示中加入目标读者的身份信息(如角色、兴趣、跳过内容),能显著提升简报的相关性。
第四步:管理你的任务
列出所有已安排的任务
在聊天中输入:
/cron list
或从终端执行:
hermes cron list
你会看到类似如下输出:
ID | Name | Schedule | Next Run | Deliver
------------|-------------------|-------------|--------------------|--------
a1b2c3d4 | Morning Briefing | 0 8 * * * | 2026-03-09 08:00 | telegram
e5f6g7h8 | Evening Recap | 0 18 * * * | 2026-03-08 18:00 | telegram
删除某个任务
在聊天中:
/cron remove a1b2c3d4
或用自然语言提问:
Remove my morning briefing cron job.
Hermes 会使用 cronjob(action="list") 查找该任务,并用 cronjob(action="remove") 删除它。
检查网关状态
确保调度器正在运行:
hermes cron status
如果网关未运行,任务将无法执行。建议将其作为后台服务安装以保证可靠性:
hermes gateway install
# or on Linux servers
sudo hermes gateway install --system
更进一步探索
你已经成功搭建了一个可用的每日简报机器人。接下来可以尝试以下方向:
- 定时任务(Cron) —— 完整的调度格式、重复限制与交付选项参考
- 委派 —— 深入了解并行子代理工作流
- 消息平台 —— 配置 Telegram、Discord 等推送目标
- 记忆 —— 实现跨会话的持久上下文
- 技巧与最佳实践 —— 更多提示工程建议
简报机器人的模式适用于任何场景:竞品监控、GitHub 仓库摘要、天气预报、投资组合追踪、服务器健康检查,甚至每日笑话。只要你能用提示描述清楚,就能定时执行。