mirror of
https://github.com/Nezumi-2711/astrbot_plugin_qq_group_daily_analysis.git
synced 2026-09-22 13:38:43 +00:00
fix(RetryManager): 重试管理器直接从渲染器请求原始图像字节,QQ 客户端不再需要从本地服务器下载图片,从而绕过了导致超时的网络传输层
直接字节获取(Direct Byte Retrieval): 重试管理器现在直接从渲染器请求原始图像字节(Bytes),而不是通过 URL。这使得 QQ 客户端不再需要从本地服务器下载图片,从而绕过了导致超时的网络传输层。Base64 编码: 图像字节现在被编码为 Base64 字符串。协议兼容性: 消息负载(Payload)现在使用 base64:// 前缀构建,这是 OneBot/AstrBot 协议中发送 Base64 图片的标准方式。
This commit is contained in:
+26
-8
@@ -1,6 +1,7 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
import random
|
import random
|
||||||
import time
|
import time
|
||||||
|
import base64
|
||||||
from collections.abc import Callable
|
from collections.abc import Callable
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
|
|
||||||
@@ -148,19 +149,33 @@ class RetryManager:
|
|||||||
"quality": 85,
|
"quality": 85,
|
||||||
}
|
}
|
||||||
logger.debug(f"[RetryManager] 正在重新渲染群 {task.group_id} 的图片...")
|
logger.debug(f"[RetryManager] 正在重新渲染群 {task.group_id} 的图片...")
|
||||||
image_url = await self.html_render_func(
|
|
||||||
|
# 修改:return_url=False 获取二进制数据而不是URL
|
||||||
|
# 这对于解决 NTQQ "Timeout" 错误至关重要,因为它避免了 QQ 客户端下载本地/内网 URL 的网络问题
|
||||||
|
image_data = await self.html_render_func(
|
||||||
task.html_content,
|
task.html_content,
|
||||||
{},
|
{},
|
||||||
True, # 返回 URL
|
False, # return_url=False, 获取 bytes
|
||||||
image_options,
|
image_options,
|
||||||
)
|
)
|
||||||
|
|
||||||
if not image_url:
|
if not image_data:
|
||||||
logger.warning(
|
logger.warning(
|
||||||
f"[RetryManager] 重新渲染失败(返回空 URL){task.group_id}"
|
f"[RetryManager] 重新渲染失败(返回空数据){task.group_id}"
|
||||||
)
|
)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
# 将 bytes 转换为 base64 字符串
|
||||||
|
try:
|
||||||
|
base64_str = base64.b64encode(image_data).decode("utf-8")
|
||||||
|
image_file_str = f"base64://{base64_str}"
|
||||||
|
logger.debug(
|
||||||
|
f"[RetryManager] 图片转Base64成功,长度: {len(base64_str)}"
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"[RetryManager] Base64编码失败: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
# 2. 获取 Bot 实例
|
# 2. 获取 Bot 实例
|
||||||
bot = self.bot_manager.get_bot_instance(task.platform_id)
|
bot = self.bot_manager.get_bot_instance(task.platform_id)
|
||||||
if not bot:
|
if not bot:
|
||||||
@@ -170,7 +185,9 @@ class RetryManager:
|
|||||||
return False # 无法重试,因为 Bot 已离线
|
return False # 无法重试,因为 Bot 已离线
|
||||||
|
|
||||||
# 3. 发送图片
|
# 3. 发送图片
|
||||||
logger.info(f"[RetryManager] 正在向群 {task.group_id} 发送重试图片...")
|
logger.info(
|
||||||
|
f"[RetryManager] 正在向群 {task.group_id} 发送重试图片 (Base64模式)..."
|
||||||
|
)
|
||||||
|
|
||||||
# 使用 OneBot v11 标准 API
|
# 使用 OneBot v11 标准 API
|
||||||
if hasattr(bot, "api") and hasattr(bot.api, "call_action"):
|
if hasattr(bot, "api") and hasattr(bot.api, "call_action"):
|
||||||
@@ -182,7 +199,7 @@ class RetryManager:
|
|||||||
"type": "text",
|
"type": "text",
|
||||||
"data": {"text": "📊 每日群聊分析报告(重试发送):\n"},
|
"data": {"text": "📊 每日群聊分析报告(重试发送):\n"},
|
||||||
},
|
},
|
||||||
{"type": "image", "data": {"file": image_url}},
|
{"type": "image", "data": {"file": image_file_str}},
|
||||||
]
|
]
|
||||||
|
|
||||||
result = await bot.api.call_action(
|
result = await bot.api.call_action(
|
||||||
@@ -195,8 +212,9 @@ class RetryManager:
|
|||||||
if retcode == 0:
|
if retcode == 0:
|
||||||
return True
|
return True
|
||||||
elif retcode == 1200:
|
elif retcode == 1200:
|
||||||
|
# 即使是 Base64 也可能超时,但概率小很多
|
||||||
logger.warning(
|
logger.warning(
|
||||||
"[RetryManager] 发送失败 (retcode=1200): 可能是Bot被禁言或不在群内,稍后重试"
|
"[RetryManager] 发送失败 (retcode=1200): 消息可能过大或Bot连接不稳定"
|
||||||
)
|
)
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
@@ -215,7 +233,7 @@ class RetryManager:
|
|||||||
elif hasattr(bot, "send_msg"): # 尝试 AstrBot 抽象接口
|
elif hasattr(bot, "send_msg"): # 尝试 AstrBot 抽象接口
|
||||||
try:
|
try:
|
||||||
# 尝试直接发送
|
# 尝试直接发送
|
||||||
await bot.send_msg(image_url, group_id=task.group_id)
|
await bot.send_msg(image_file_str, group_id=task.group_id)
|
||||||
return True
|
return True
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"[RetryManager] 抽象接口发送失败: {e}")
|
logger.error(f"[RetryManager] 抽象接口发送失败: {e}")
|
||||||
|
|||||||
Reference in New Issue
Block a user