mirror of
https://gitee.com/houhuan/TrendRadar.git
synced 2025-12-21 11:17:15 +08:00
v3.0.4
This commit is contained in:
parent
08f0e62c70
commit
5dfca546f5
@ -32,6 +32,7 @@ notification:
|
||||
enable_notification: true # 是否启用通知功能,如果 false,则不发送手机通知
|
||||
message_batch_size: 4000 # 消息分批大小(字节)(这个配置别动)
|
||||
dingtalk_batch_size: 20000 # 钉钉消息分批大小(字节)(这个配置也别动)
|
||||
feishu_batch_size: 29000 # 飞书消息分批大小(字节)
|
||||
batch_send_interval: 1 # 批次发送间隔(秒)
|
||||
feishu_message_separator: "━━━━━━━━━━━━━━━━━━━" # feishu 消息分割线
|
||||
|
||||
|
||||
150
main.py
150
main.py
@ -20,7 +20,7 @@ import requests
|
||||
import yaml
|
||||
|
||||
|
||||
VERSION = "3.0.3"
|
||||
VERSION = "3.0.4"
|
||||
|
||||
|
||||
# === SMTP邮件配置 ===
|
||||
@ -79,6 +79,7 @@ def load_config():
|
||||
"DINGTALK_BATCH_SIZE": config_data["notification"].get(
|
||||
"dingtalk_batch_size", 20000
|
||||
),
|
||||
"FEISHU_BATCH_SIZE": config_data["notification"].get("feishu_batch_size", 29000),
|
||||
"BATCH_SEND_INTERVAL": config_data["notification"]["batch_send_interval"],
|
||||
"FEISHU_MESSAGE_SEPARATOR": config_data["notification"][
|
||||
"feishu_message_separator"
|
||||
@ -2816,6 +2817,8 @@ def split_content_into_batches(
|
||||
if max_bytes is None:
|
||||
if format_type == "dingtalk":
|
||||
max_bytes = CONFIG.get("DINGTALK_BATCH_SIZE", 20000)
|
||||
elif format_type == "feishu":
|
||||
max_bytes = CONFIG.get("FEISHU_BATCH_SIZE", 29000)
|
||||
elif format_type == "ntfy":
|
||||
max_bytes = 3800
|
||||
else:
|
||||
@ -2835,6 +2838,8 @@ def split_content_into_batches(
|
||||
base_header = f"总新闻数: {total_titles}\n\n"
|
||||
elif format_type == "ntfy":
|
||||
base_header = f"**总新闻数:** {total_titles}\n\n"
|
||||
elif format_type == "feishu":
|
||||
base_header = ""
|
||||
elif format_type == "dingtalk":
|
||||
base_header = f"**总新闻数:** {total_titles}\n\n"
|
||||
base_header += f"**时间:** {now.strftime('%Y-%m-%d %H:%M:%S')}\n\n"
|
||||
@ -2854,6 +2859,10 @@ def split_content_into_batches(
|
||||
base_footer = f"\n\n> 更新时间:{now.strftime('%Y-%m-%d %H:%M:%S')}"
|
||||
if update_info:
|
||||
base_footer += f"\n> TrendRadar 发现新版本 **{update_info['remote_version']}**,当前 **{update_info['current_version']}**"
|
||||
elif format_type == "feishu":
|
||||
base_footer = f"\n\n<font color='grey'>更新时间:{now.strftime('%Y-%m-%d %H:%M:%S')}</font>"
|
||||
if update_info:
|
||||
base_footer += f"\n<font color='grey'>TrendRadar 发现新版本 {update_info['remote_version']},当前 {update_info['current_version']}</font>"
|
||||
elif format_type == "dingtalk":
|
||||
base_footer = f"\n\n> 更新时间:{now.strftime('%Y-%m-%d %H:%M:%S')}"
|
||||
if update_info:
|
||||
@ -2867,6 +2876,8 @@ def split_content_into_batches(
|
||||
stats_header = f"📊 热点词汇统计\n\n"
|
||||
elif format_type == "ntfy":
|
||||
stats_header = f"📊 **热点词汇统计**\n\n"
|
||||
elif format_type == "feishu":
|
||||
stats_header = f"📊 **热点词汇统计**\n\n"
|
||||
elif format_type == "dingtalk":
|
||||
stats_header = f"📊 **热点词汇统计**\n\n"
|
||||
|
||||
@ -2944,6 +2955,13 @@ def split_content_into_batches(
|
||||
)
|
||||
else:
|
||||
word_header = f"📌 {sequence_display} **{word}** : {count} 条\n\n"
|
||||
elif format_type == "feishu":
|
||||
if count >= 10:
|
||||
word_header = f"🔥 <font color='grey'>{sequence_display}</font> **{word}** : <font color='red'>{count}</font> 条\n\n"
|
||||
elif count >= 5:
|
||||
word_header = f"📈 <font color='grey'>{sequence_display}</font> **{word}** : <font color='orange'>{count}</font> 条\n\n"
|
||||
else:
|
||||
word_header = f"📌 <font color='grey'>{sequence_display}</font> **{word}** : {count} 条\n\n"
|
||||
elif format_type == "dingtalk":
|
||||
if count >= 10:
|
||||
word_header = (
|
||||
@ -2972,6 +2990,10 @@ def split_content_into_batches(
|
||||
formatted_title = format_title_for_platform(
|
||||
"ntfy", first_title_data, show_source=True
|
||||
)
|
||||
elif format_type == "feishu":
|
||||
formatted_title = format_title_for_platform(
|
||||
"feishu", first_title_data, show_source=True
|
||||
)
|
||||
elif format_type == "dingtalk":
|
||||
formatted_title = format_title_for_platform(
|
||||
"dingtalk", first_title_data, show_source=True
|
||||
@ -3017,6 +3039,10 @@ def split_content_into_batches(
|
||||
formatted_title = format_title_for_platform(
|
||||
"ntfy", title_data, show_source=True
|
||||
)
|
||||
elif format_type == "feishu":
|
||||
formatted_title = format_title_for_platform(
|
||||
"feishu", title_data, show_source=True
|
||||
)
|
||||
elif format_type == "dingtalk":
|
||||
formatted_title = format_title_for_platform(
|
||||
"dingtalk", title_data, show_source=True
|
||||
@ -3050,6 +3076,8 @@ def split_content_into_batches(
|
||||
separator = f"\n\n"
|
||||
elif format_type == "ntfy":
|
||||
separator = f"\n\n"
|
||||
elif format_type == "feishu":
|
||||
separator = f"\n{CONFIG['FEISHU_MESSAGE_SEPARATOR']}\n\n"
|
||||
elif format_type == "dingtalk":
|
||||
separator = f"\n---\n\n"
|
||||
|
||||
@ -3071,6 +3099,8 @@ def split_content_into_batches(
|
||||
)
|
||||
elif format_type == "ntfy":
|
||||
new_header = f"\n\n🆕 **本次新增热点新闻** (共 {report_data['total_new_count']} 条)\n\n"
|
||||
elif format_type == "feishu":
|
||||
new_header = f"\n{CONFIG['FEISHU_MESSAGE_SEPARATOR']}\n\n🆕 **本次新增热点新闻** (共 {report_data['total_new_count']} 条)\n\n"
|
||||
elif format_type == "dingtalk":
|
||||
new_header = f"\n---\n\n🆕 **本次新增热点新闻** (共 {report_data['total_new_count']} 条)\n\n"
|
||||
|
||||
@ -3096,6 +3126,8 @@ def split_content_into_batches(
|
||||
source_header = f"{source_data['source_name']} ({len(source_data['titles'])} 条):\n\n"
|
||||
elif format_type == "ntfy":
|
||||
source_header = f"**{source_data['source_name']}** ({len(source_data['titles'])} 条):\n\n"
|
||||
elif format_type == "feishu":
|
||||
source_header = f"**{source_data['source_name']}** ({len(source_data['titles'])} 条):\n\n"
|
||||
elif format_type == "dingtalk":
|
||||
source_header = f"**{source_data['source_name']}** ({len(source_data['titles'])} 条):\n\n"
|
||||
|
||||
@ -3114,6 +3146,10 @@ def split_content_into_batches(
|
||||
formatted_title = format_title_for_platform(
|
||||
"telegram", title_data_copy, show_source=False
|
||||
)
|
||||
elif format_type == "feishu":
|
||||
formatted_title = format_title_for_platform(
|
||||
"feishu", title_data_copy, show_source=False
|
||||
)
|
||||
elif format_type == "dingtalk":
|
||||
formatted_title = format_title_for_platform(
|
||||
"dingtalk", title_data_copy, show_source=False
|
||||
@ -3155,6 +3191,10 @@ def split_content_into_batches(
|
||||
formatted_title = format_title_for_platform(
|
||||
"telegram", title_data_copy, show_source=False
|
||||
)
|
||||
elif format_type == "feishu":
|
||||
formatted_title = format_title_for_platform(
|
||||
"feishu", title_data_copy, show_source=False
|
||||
)
|
||||
elif format_type == "dingtalk":
|
||||
formatted_title = format_title_for_platform(
|
||||
"dingtalk", title_data_copy, show_source=False
|
||||
@ -3187,6 +3227,8 @@ def split_content_into_batches(
|
||||
failed_header = f"\n\n⚠️ 数据获取失败的平台:\n\n"
|
||||
elif format_type == "ntfy":
|
||||
failed_header = f"\n\n⚠️ **数据获取失败的平台:**\n\n"
|
||||
elif format_type == "feishu":
|
||||
failed_header = f"\n{CONFIG['FEISHU_MESSAGE_SEPARATOR']}\n\n⚠️ **数据获取失败的平台:**\n\n"
|
||||
elif format_type == "dingtalk":
|
||||
failed_header = f"\n---\n\n⚠️ **数据获取失败的平台:**\n\n"
|
||||
|
||||
@ -3204,7 +3246,9 @@ def split_content_into_batches(
|
||||
current_batch_has_content = True
|
||||
|
||||
for i, id_value in enumerate(report_data["failed_ids"], 1):
|
||||
if format_type == "dingtalk":
|
||||
if format_type == "feishu":
|
||||
failed_line = f" • <font color='red'>{id_value}</font>\n"
|
||||
elif format_type == "dingtalk":
|
||||
failed_line = f" • **{id_value}**\n"
|
||||
else:
|
||||
failed_line = f" • {id_value}\n"
|
||||
@ -3358,42 +3402,86 @@ def send_to_feishu(
|
||||
proxy_url: Optional[str] = None,
|
||||
mode: str = "daily",
|
||||
) -> bool:
|
||||
"""发送到飞书"""
|
||||
"""发送到飞书(支持分批发送)"""
|
||||
headers = {"Content-Type": "application/json"}
|
||||
|
||||
text_content = render_feishu_content(report_data, update_info, mode)
|
||||
total_titles = sum(
|
||||
len(stat["titles"]) for stat in report_data["stats"] if stat["count"] > 0
|
||||
)
|
||||
|
||||
now = get_beijing_time()
|
||||
payload = {
|
||||
"msg_type": "text",
|
||||
"content": {
|
||||
"total_titles": total_titles,
|
||||
"timestamp": now.strftime("%Y-%m-%d %H:%M:%S"),
|
||||
"report_type": report_type,
|
||||
"text": text_content,
|
||||
},
|
||||
}
|
||||
|
||||
proxies = None
|
||||
if proxy_url:
|
||||
proxies = {"http": proxy_url, "https": proxy_url}
|
||||
|
||||
try:
|
||||
response = requests.post(
|
||||
webhook_url, headers=headers, json=payload, proxies=proxies, timeout=30
|
||||
# 获取分批内容,使用飞书专用的批次大小
|
||||
batches = split_content_into_batches(
|
||||
report_data,
|
||||
"feishu",
|
||||
update_info,
|
||||
max_bytes=CONFIG.get("FEISHU_BATCH_SIZE", 29000),
|
||||
mode=mode,
|
||||
)
|
||||
|
||||
print(f"飞书消息分为 {len(batches)} 批次发送 [{report_type}]")
|
||||
|
||||
# 逐批发送
|
||||
for i, batch_content in enumerate(batches, 1):
|
||||
batch_size = len(batch_content.encode("utf-8"))
|
||||
print(
|
||||
f"发送飞书第 {i}/{len(batches)} 批次,大小:{batch_size} 字节 [{report_type}]"
|
||||
)
|
||||
if response.status_code == 200:
|
||||
print(f"飞书通知发送成功 [{report_type}]")
|
||||
return True
|
||||
else:
|
||||
print(f"飞书通知发送失败 [{report_type}],状态码:{response.status_code}")
|
||||
|
||||
# 添加批次标识
|
||||
if len(batches) > 1:
|
||||
batch_header = f"**[第 {i}/{len(batches)} 批次]**\n\n"
|
||||
# 将批次标识插入到适当位置(在统计标题之后)
|
||||
if "📊 **热点词汇统计**" in batch_content:
|
||||
batch_content = batch_content.replace(
|
||||
"📊 **热点词汇统计**\n\n", f"📊 **热点词汇统计** {batch_header}"
|
||||
)
|
||||
else:
|
||||
# 如果没有统计标题,直接在开头添加
|
||||
batch_content = batch_header + batch_content
|
||||
|
||||
total_titles = sum(
|
||||
len(stat["titles"]) for stat in report_data["stats"] if stat["count"] > 0
|
||||
)
|
||||
now = get_beijing_time()
|
||||
|
||||
payload = {
|
||||
"msg_type": "text",
|
||||
"content": {
|
||||
"total_titles": total_titles,
|
||||
"timestamp": now.strftime("%Y-%m-%d %H:%M:%S"),
|
||||
"report_type": report_type,
|
||||
"text": batch_content,
|
||||
},
|
||||
}
|
||||
|
||||
try:
|
||||
response = requests.post(
|
||||
webhook_url, headers=headers, json=payload, proxies=proxies, timeout=30
|
||||
)
|
||||
if response.status_code == 200:
|
||||
result = response.json()
|
||||
# 检查飞书的响应状态
|
||||
if result.get("StatusCode") == 0 or result.get("code") == 0:
|
||||
print(f"飞书第 {i}/{len(batches)} 批次发送成功 [{report_type}]")
|
||||
# 批次间间隔
|
||||
if i < len(batches):
|
||||
time.sleep(CONFIG["BATCH_SEND_INTERVAL"])
|
||||
else:
|
||||
error_msg = result.get("msg") or result.get("StatusMessage", "未知错误")
|
||||
print(
|
||||
f"飞书第 {i}/{len(batches)} 批次发送失败 [{report_type}],错误:{error_msg}"
|
||||
)
|
||||
return False
|
||||
else:
|
||||
print(
|
||||
f"飞书第 {i}/{len(batches)} 批次发送失败 [{report_type}],状态码:{response.status_code}"
|
||||
)
|
||||
return False
|
||||
except Exception as e:
|
||||
print(f"飞书第 {i}/{len(batches)} 批次发送出错 [{report_type}]:{e}")
|
||||
return False
|
||||
except Exception as e:
|
||||
print(f"飞书通知发送出错 [{report_type}]:{e}")
|
||||
return False
|
||||
|
||||
print(f"飞书所有 {len(batches)} 批次发送完成 [{report_type}]")
|
||||
return True
|
||||
|
||||
|
||||
def send_to_dingtalk(
|
||||
|
||||
12
readme.md
12
readme.md
@ -11,7 +11,7 @@
|
||||
[](https://github.com/sansan0/TrendRadar/stargazers)
|
||||
[](https://github.com/sansan0/TrendRadar/network/members)
|
||||
[](LICENSE)
|
||||
[](https://github.com/sansan0/TrendRadar)
|
||||
[](https://github.com/sansan0/TrendRadar)
|
||||
[](https://github.com/sansan0/TrendRadar)
|
||||
|
||||
[](https://work.weixin.qq.com/)
|
||||
@ -522,14 +522,18 @@ GitHub 一键 Fork 即可使用,无需编程基础。
|
||||
- 统一所有工具的时间参数格式
|
||||
|
||||
|
||||
### 2025/10/23 - v3.0.3
|
||||
### 2025/10/31 - v3.0.4
|
||||
|
||||
- 扩大 ntfy 错误信息显示范围
|
||||
- 解决飞书因推送内容过长而产生的错误,实现了分批推送
|
||||
|
||||
|
||||
<details>
|
||||
<summary><strong>👉 历史更新</strong></summary>
|
||||
|
||||
### 2025/10/23 - v3.0.3
|
||||
|
||||
- 扩大 ntfy 错误信息显示范围
|
||||
|
||||
|
||||
### 2025/10/21 - v3.0.2
|
||||
|
||||
@ -785,7 +789,7 @@ frequency_words.txt 文件增加了一个【必须词】功能,使用 + 号
|
||||
|
||||
## 🚀 快速开始
|
||||
|
||||
> 部署成功后,新闻数据一般一小时后才会更新,如想加快,可参照【第4步】手动测试配置效果
|
||||
> 配置完成后,新闻数据一小时后才会更新,如想加快,可参照【第4步】手动测试配置效果
|
||||
|
||||
1. **Fork 本项目**到你的 GitHub 账户
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user