mirror of
https://github.com/xinnan-tech/xiaozhi-esp32-server.git
synced 2026-07-27 01:23:55 +08:00
newsnow 插件支持前端配置新闻源
This commit is contained in:
@@ -0,0 +1,107 @@
|
|||||||
|
# get_news_from_newsnow 插件新闻源配置指南
|
||||||
|
|
||||||
|
## 概述
|
||||||
|
|
||||||
|
`get_news_from_newsnow` 插件现在支持通过Web管理界面动态配置新闻源,不再需要修改代码。用户可以在智控台中为每个智能体配置不同的新闻源。
|
||||||
|
|
||||||
|
## 配置方式
|
||||||
|
|
||||||
|
### 1. 通过Web管理界面配置(推荐)
|
||||||
|
|
||||||
|
1. 登录智控台
|
||||||
|
2. 进入"角色配置"页面
|
||||||
|
3. 选择要配置的智能体
|
||||||
|
4. 点击"编辑功能"按钮
|
||||||
|
5. 在右侧参数配置区域找到"newsnow新闻聚合"插件
|
||||||
|
6. 在"新闻源配置"字段中输入JSON格式的新闻源配置
|
||||||
|
|
||||||
|
### 2. 配置文件方式
|
||||||
|
|
||||||
|
在 `config.yaml` 中配置:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
plugins:
|
||||||
|
get_news_from_newsnow:
|
||||||
|
url: "https://newsnow.busiyi.world/api/s?id="
|
||||||
|
news_sources:
|
||||||
|
thepaper: "澎湃新闻"
|
||||||
|
baidu: "百度热搜"
|
||||||
|
cls-depth: "财联社"
|
||||||
|
# 可以添加更多新闻源
|
||||||
|
sina: "新浪新闻"
|
||||||
|
sohu: "搜狐新闻"
|
||||||
|
```
|
||||||
|
|
||||||
|
## 新闻源配置格式
|
||||||
|
|
||||||
|
新闻源配置使用JSON格式,格式为:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"source_id": "显示名称",
|
||||||
|
"source_id2": "显示名称2"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 配置示例
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"thepaper": "澎湃新闻",
|
||||||
|
"baidu": "百度热搜",
|
||||||
|
"cls-depth": "财联社",
|
||||||
|
"sina": "新浪新闻",
|
||||||
|
"sohu": "搜狐新闻"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 默认配置
|
||||||
|
|
||||||
|
如果未配置新闻源,插件将使用以下默认配置:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"thepaper": "澎湃新闻",
|
||||||
|
"baidu": "百度热搜",
|
||||||
|
"cls-depth": "财联社"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 使用说明
|
||||||
|
|
||||||
|
1. **配置新闻源**:在Web界面或配置文件中设置新闻源
|
||||||
|
2. **调用插件**:用户可以说"播报新闻"或"获取新闻"
|
||||||
|
3. **指定新闻源**:用户可以说"播报澎湃新闻"或"获取百度热搜"
|
||||||
|
4. **获取详情**:用户可以说"详细介绍这条新闻"
|
||||||
|
|
||||||
|
## 注意事项
|
||||||
|
|
||||||
|
1. 新闻源的 `source_id` 必须与API接口支持的ID一致
|
||||||
|
2. 配置更改后需要重启服务或重新加载配置
|
||||||
|
3. 如果配置的新闻源无效,插件会自动使用默认新闻源
|
||||||
|
4. JSON格式必须正确,否则会使用默认配置
|
||||||
|
|
||||||
|
## 故障排除
|
||||||
|
|
||||||
|
### 问题:配置的新闻源不生效
|
||||||
|
|
||||||
|
**解决方案**:
|
||||||
|
1. 检查JSON格式是否正确
|
||||||
|
2. 确认新闻源ID是否有效
|
||||||
|
3. 查看日志文件中的错误信息
|
||||||
|
4. 重启服务
|
||||||
|
|
||||||
|
### 问题:无法获取新闻
|
||||||
|
|
||||||
|
**解决方案**:
|
||||||
|
1. 检查网络连接
|
||||||
|
2. 确认API接口地址是否正确
|
||||||
|
3. 查看API接口是否可用
|
||||||
|
4. 检查日志文件中的错误信息
|
||||||
|
|
||||||
|
## 技术实现
|
||||||
|
|
||||||
|
- 插件会从 `conn.config["plugins"]["get_news_from_newsnow"]["news_sources"]` 读取配置
|
||||||
|
- 支持字符串格式的JSON和字典格式的配置
|
||||||
|
- 配置验证和错误处理机制
|
||||||
|
- 向后兼容,未配置时使用默认值
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
-- 更新 get_news_from_newsnow 插件配置,添加新闻源配置字段
|
||||||
|
-- 执行时间:2025-06-25
|
||||||
|
|
||||||
|
-- 更新现有的 get_news_from_newsnow 插件配置
|
||||||
|
UPDATE ai_model_provider
|
||||||
|
SET fields = JSON_ARRAY(
|
||||||
|
JSON_OBJECT(
|
||||||
|
'key', 'url',
|
||||||
|
'type', 'string',
|
||||||
|
'label', '接口地址',
|
||||||
|
'default', 'https://newsnow.busiyi.world/api/s?id='
|
||||||
|
),
|
||||||
|
JSON_OBJECT(
|
||||||
|
'key', 'news_sources',
|
||||||
|
'type', 'json',
|
||||||
|
'label', '新闻源配置',
|
||||||
|
'default', '{"thepaper":"澎湃新闻","baidu":"百度热搜","cls-depth":"财联社"}'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
WHERE provider_code = 'get_news_from_newsnow'
|
||||||
|
AND model_type = 'Plugin';
|
||||||
@@ -218,4 +218,11 @@ databaseChangeLog:
|
|||||||
changes:
|
changes:
|
||||||
- sqlFile:
|
- sqlFile:
|
||||||
encoding: utf8
|
encoding: utf8
|
||||||
path: classpath:db/changelog/202506191643.sql
|
path: classpath:db/changelog/202506191643.sql
|
||||||
|
- changeSet:
|
||||||
|
id: 202506251619
|
||||||
|
author: Tink
|
||||||
|
changes:
|
||||||
|
- sqlFile:
|
||||||
|
encoding: utf8
|
||||||
|
path: classpath:db/changelog/202506251619.sql
|
||||||
@@ -120,7 +120,12 @@ plugins:
|
|||||||
society_rss_url: "https://www.chinanews.com.cn/rss/society.xml"
|
society_rss_url: "https://www.chinanews.com.cn/rss/society.xml"
|
||||||
world_rss_url: "https://www.chinanews.com.cn/rss/world.xml"
|
world_rss_url: "https://www.chinanews.com.cn/rss/world.xml"
|
||||||
finance_rss_url: "https://www.chinanews.com.cn/rss/finance.xml"
|
finance_rss_url: "https://www.chinanews.com.cn/rss/finance.xml"
|
||||||
get_news_from_newsnow: {"url": "https://newsnow.busiyi.world/api/s?id="}
|
get_news_from_newsnow:
|
||||||
|
url: "https://newsnow.busiyi.world/api/s?id="
|
||||||
|
news_sources:
|
||||||
|
thepaper: "澎湃新闻"
|
||||||
|
baidu: "百度热搜"
|
||||||
|
cls-depth: "财联社"
|
||||||
home_assistant:
|
home_assistant:
|
||||||
devices:
|
devices:
|
||||||
- 客厅,玩具灯,switch.cuco_cn_460494544_cp1_on_p_2_1
|
- 客厅,玩具灯,switch.cuco_cn_460494544_cp1_on_p_2_1
|
||||||
@@ -765,4 +770,4 @@ TTS:
|
|||||||
# 支持声音克隆,可自行上传音频,填入voice参数,voice参数为空时,使用默认声音
|
# 支持声音克隆,可自行上传音频,填入voice参数,voice参数为空时,使用默认声音
|
||||||
access_token: "U4YdYXVfpwWnk2t5Gp822zWPCuORyeJL"
|
access_token: "U4YdYXVfpwWnk2t5Gp822zWPCuORyeJL"
|
||||||
voice: "OUeAo1mhq6IBExi"
|
voice: "OUeAo1mhq6IBExi"
|
||||||
output_dir: tmp/
|
output_dir: tmp/
|
||||||
|
|||||||
@@ -8,38 +8,61 @@ from markitdown import MarkItDown
|
|||||||
TAG = __name__
|
TAG = __name__
|
||||||
logger = setup_logging()
|
logger = setup_logging()
|
||||||
|
|
||||||
# 新闻来源字典,包含名称和对应的API ID
|
# 默认新闻来源字典,当配置中没有指定时使用
|
||||||
NEWS_SOURCES = {
|
DEFAULT_NEWS_SOURCES = {
|
||||||
"thepaper": "澎湃新闻",
|
"thepaper": "澎湃新闻",
|
||||||
"baidu": "百度热搜",
|
"baidu": "百度热搜",
|
||||||
"cls-depth": "财联社",
|
"cls-depth": "财联社",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# 动态生成新闻源描述
|
def get_news_sources_from_config(conn):
|
||||||
def generate_news_sources_description():
|
"""从配置中获取新闻源字典"""
|
||||||
sources_desc = []
|
try:
|
||||||
for source_id, source_name in NEWS_SOURCES.items():
|
# 尝试从插件配置中获取新闻源
|
||||||
sources_desc.append(f"{source_name}({source_id})")
|
if (conn.config.get("plugins") and
|
||||||
return "、".join(sources_desc)
|
conn.config["plugins"].get("get_news_from_newsnow") and
|
||||||
|
conn.config["plugins"]["get_news_from_newsnow"].get("news_sources")):
|
||||||
|
|
||||||
|
# 如果配置中是字符串,尝试解析JSON
|
||||||
|
news_sources_config = conn.config["plugins"]["get_news_from_newsnow"]["news_sources"]
|
||||||
|
if isinstance(news_sources_config, str):
|
||||||
|
try:
|
||||||
|
return json.loads(news_sources_config)
|
||||||
|
except json.JSONDecodeError:
|
||||||
|
logger.bind(tag=TAG).warning("新闻源配置JSON格式错误,使用默认配置")
|
||||||
|
return DEFAULT_NEWS_SOURCES
|
||||||
|
elif isinstance(news_sources_config, dict):
|
||||||
|
return news_sources_config
|
||||||
|
else:
|
||||||
|
logger.bind(tag=TAG).warning("新闻源配置格式错误,使用默认配置")
|
||||||
|
return DEFAULT_NEWS_SOURCES
|
||||||
|
else:
|
||||||
|
logger.bind(tag=TAG).debug("未找到新闻源配置,使用默认配置")
|
||||||
|
return DEFAULT_NEWS_SOURCES
|
||||||
|
except Exception as e:
|
||||||
|
logger.bind(tag=TAG).error(f"获取新闻源配置失败: {e},使用默认配置")
|
||||||
|
return DEFAULT_NEWS_SOURCES
|
||||||
|
|
||||||
|
|
||||||
|
# 静态函数描述,使用默认新闻源生成描述
|
||||||
GET_NEWS_FROM_NEWSNOW_FUNCTION_DESC = {
|
GET_NEWS_FROM_NEWSNOW_FUNCTION_DESC = {
|
||||||
"type": "function",
|
"type": "function",
|
||||||
"function": {
|
"function": {
|
||||||
"name": "get_news_from_newsnow",
|
"name": "get_news_from_newsnow",
|
||||||
"description": (
|
"description": (
|
||||||
"获取最新新闻,随机选择一条新闻进行播报。"
|
"获取最新新闻,随机选择一条新闻进行播报。"
|
||||||
f"用户可以选择不同的新闻源,如{generate_news_sources_description()}等。"
|
"用户可以选择不同的新闻源,如澎湃新闻(thepaper)、百度热搜(baidu)、财联社(cls-depth)等。"
|
||||||
"如果没有指定,默认从澎湃新闻获取。"
|
"如果没有指定,默认从澎湃新闻获取。"
|
||||||
"用户可以要求获取详细内容,此时会获取新闻的详细内容。"
|
"用户可以要求获取详细内容,此时会获取新闻的详细内容。"
|
||||||
|
"注意:实际可用的新闻源取决于系统配置。"
|
||||||
),
|
),
|
||||||
"parameters": {
|
"parameters": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"source": {
|
"source": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": f"新闻源,例如{generate_news_sources_description()}等。可选参数,如果不提供则使用默认新闻源",
|
"description": "新闻源,例如thepaper、baidu、cls-depth等。可选参数,如果不提供则使用默认新闻源",
|
||||||
},
|
},
|
||||||
"detail": {
|
"detail": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
@@ -115,6 +138,9 @@ def get_news_from_newsnow(
|
|||||||
):
|
):
|
||||||
"""获取新闻并随机选择一条进行播报,或获取上一条新闻的详细内容"""
|
"""获取新闻并随机选择一条进行播报,或获取上一条新闻的详细内容"""
|
||||||
try:
|
try:
|
||||||
|
# 获取当前配置的新闻源
|
||||||
|
news_sources = get_news_sources_from_config(conn)
|
||||||
|
|
||||||
# 如果detail为True,获取上一条新闻的详细内容
|
# 如果detail为True,获取上一条新闻的详细内容
|
||||||
detail = str(detail).lower() == "true"
|
detail = str(detail).lower() == "true"
|
||||||
if detail:
|
if detail:
|
||||||
@@ -132,7 +158,7 @@ def get_news_from_newsnow(
|
|||||||
url = conn.last_newsnow_link.get("url")
|
url = conn.last_newsnow_link.get("url")
|
||||||
title = conn.last_newsnow_link.get("title", "未知标题")
|
title = conn.last_newsnow_link.get("title", "未知标题")
|
||||||
source_id = conn.last_newsnow_link.get("source_id", "thepaper")
|
source_id = conn.last_newsnow_link.get("source_id", "thepaper")
|
||||||
source_name = NEWS_SOURCES.get(source_id, "未知来源")
|
source_name = news_sources.get(source_id, "未知来源")
|
||||||
|
|
||||||
if not url or url == "#":
|
if not url or url == "#":
|
||||||
return ActionResponse(
|
return ActionResponse(
|
||||||
@@ -167,11 +193,11 @@ def get_news_from_newsnow(
|
|||||||
|
|
||||||
# 否则,获取新闻列表并随机选择一条
|
# 否则,获取新闻列表并随机选择一条
|
||||||
# 验证新闻源是否有效,如果无效则使用默认源
|
# 验证新闻源是否有效,如果无效则使用默认源
|
||||||
if source not in NEWS_SOURCES:
|
if source not in news_sources:
|
||||||
logger.bind(tag=TAG).warning(f"无效的新闻源: {source},使用默认源thepaper")
|
logger.bind(tag=TAG).warning(f"无效的新闻源: {source},使用默认源thepaper")
|
||||||
source = "thepaper"
|
source = "thepaper"
|
||||||
|
|
||||||
source_name = NEWS_SOURCES.get(source, "澎湃新闻")
|
source_name = news_sources.get(source, "澎湃新闻")
|
||||||
logger.bind(tag=TAG).info(f"获取新闻: 新闻源={source}({source_name})")
|
logger.bind(tag=TAG).info(f"获取新闻: 新闻源={source}({source_name})")
|
||||||
|
|
||||||
# 获取新闻列表
|
# 获取新闻列表
|
||||||
|
|||||||
Reference in New Issue
Block a user