mirror of
https://github.com/Nezumi-2711/astrbot_plugin_qq_group_daily_analysis.git
synced 2026-09-22 20:01:04 +00:00
feat(reaction): 将文字反馈调整为表情反馈
This commit is contained in:
@@ -459,6 +459,7 @@ class GroupDailyAnalysis(Star):
|
||||
分析群聊日常活动(跨平台支持)
|
||||
用法: /群分析 [天数]
|
||||
"""
|
||||
event.should_call_llm(True) # 阻止默认 LLM 解析
|
||||
group_id = self._get_group_id_from_event(event)
|
||||
platform_id = self._get_platform_id_from_event(event)
|
||||
|
||||
@@ -499,7 +500,11 @@ class GroupDailyAnalysis(Star):
|
||||
)
|
||||
TraceContext.set(trace_id)
|
||||
|
||||
yield event.plain_result("🔍 正在启动跨平台分析引擎,正在拉取最近消息...")
|
||||
# 使用表情回应代替文本回复
|
||||
adapter = self.bot_manager.get_adapter(platform_id)
|
||||
orig_msg_id = getattr(event.message_obj, "message_id", None)
|
||||
if adapter and orig_msg_id:
|
||||
await adapter.set_reaction(event.get_group_id(), orig_msg_id, "🔍") # 🔍
|
||||
|
||||
try:
|
||||
# 调用 DDD 应用级服务
|
||||
@@ -515,9 +520,8 @@ class GroupDailyAnalysis(Star):
|
||||
yield event.plain_result("❌ 分析失败,原因未知")
|
||||
return
|
||||
|
||||
yield event.plain_result(
|
||||
f"📊 已获取{result['messages_count']}条消息,正在生成渲染报告..."
|
||||
)
|
||||
if adapter and orig_msg_id:
|
||||
await adapter.set_reaction(event.get_group_id(), orig_msg_id, "📊") # 📊
|
||||
|
||||
async for res in self._send_analysis_report(event, result):
|
||||
yield res
|
||||
|
||||
@@ -749,3 +749,39 @@ class DiscordAdapter(PlatformAdapter):
|
||||
) -> dict[str, str | None]:
|
||||
"""批量获取头像的最佳实践。"""
|
||||
return {uid: await self.get_user_avatar_url(uid, size) for uid in user_ids}
|
||||
|
||||
async def set_reaction(
|
||||
self, group_id: str, message_id: str, emoji: str | int, is_add: bool = True
|
||||
) -> bool:
|
||||
"""
|
||||
Discord 实现消息回应。
|
||||
"""
|
||||
if not discord:
|
||||
return False
|
||||
|
||||
try:
|
||||
# 映射常见的表情 ID 为文字表情,使分析状态在跨平台保持一致
|
||||
mapping = {289: "🔍", 424: "📊", 124: "✅"}
|
||||
emoji_to_use = emoji
|
||||
if isinstance(emoji, int) or (isinstance(emoji, str) and emoji.isdigit()):
|
||||
emoji_to_use = mapping.get(int(emoji), emoji)
|
||||
|
||||
channel_id = int(group_id)
|
||||
channel = self._discord_client.get_channel(channel_id)
|
||||
if not channel:
|
||||
channel = await self._discord_client.fetch_channel(channel_id)
|
||||
|
||||
if not hasattr(channel, "get_partial_message"):
|
||||
# 如果较低版本的 SDK 没这个方法,则直接 fetch
|
||||
msg = await channel.fetch_message(int(message_id))
|
||||
else:
|
||||
msg = channel.get_partial_message(int(message_id))
|
||||
|
||||
if is_add:
|
||||
await msg.add_reaction(emoji_to_use)
|
||||
else:
|
||||
await msg.remove_reaction(emoji_to_use, self._discord_client.user)
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.debug(f"Discord set_reaction 失败: {e}")
|
||||
return False
|
||||
|
||||
@@ -1346,3 +1346,30 @@ class OneBotAdapter(PlatformAdapter):
|
||||
|
||||
logger.info(f"[群分析相册] 未能找到名为 '{album_name}' 的相册 (群 {group_id})")
|
||||
return None
|
||||
|
||||
async def set_reaction(
|
||||
self, group_id: str, message_id: str, emoji: str | int, is_add: bool = True
|
||||
) -> bool:
|
||||
"""
|
||||
OneBot 实现消息回应 (set_msg_emoji_like)。
|
||||
支持 Go-CQHTTP, NapCat, Lagrange 等 OneBot 实现。
|
||||
"""
|
||||
try:
|
||||
# 语义化映射:根据用户喜好精细化 OneBot 端的降级
|
||||
emoji_id = str(emoji)
|
||||
if str(emoji) == "🔍":
|
||||
emoji_id = "289" # 🫣 表情 (表示任务已接收)
|
||||
elif str(emoji) == "📊":
|
||||
emoji_id = "124" # 👌 表情 (表示任务处理完成)
|
||||
|
||||
await self.bot.call_action(
|
||||
"set_msg_emoji_like",
|
||||
message_id=int(message_id),
|
||||
emoji_id=emoji_id,
|
||||
emoji_type="1", # 还原为最稳定的系统表情类型
|
||||
set=is_add,
|
||||
)
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.debug(f"OneBot set_reaction 失败 (API 可能不支持): {e}")
|
||||
return False
|
||||
|
||||
@@ -890,6 +890,50 @@ class TelegramAdapter(PlatformAdapter):
|
||||
pairs = await asyncio.gather(*(_fetch_avatar(uid) for uid in user_ids))
|
||||
return dict(pairs)
|
||||
|
||||
async def set_reaction(
|
||||
self, group_id: str, message_id: str, emoji: str | int, is_add: bool = True
|
||||
) -> bool:
|
||||
"""
|
||||
Telegram 实现消息回应。
|
||||
"""
|
||||
client = self._telegram_client
|
||||
if not client:
|
||||
return False
|
||||
|
||||
try:
|
||||
# 映射常见的表情 ID 为文字表情
|
||||
mapping = {289: "🔍", 424: "📊", 124: "✅"}
|
||||
emoji_to_use = emoji
|
||||
if isinstance(emoji, int) or (isinstance(emoji, str) and emoji.isdigit()):
|
||||
emoji_to_use = mapping.get(int(emoji), emoji)
|
||||
|
||||
chat_id, _ = self._parse_group_id(group_id)
|
||||
|
||||
# 只有开启了库支持且版本符合时才尝试。set_message_reaction 是 Bot API 7.0 (PTB 20.8+) 特性。
|
||||
if hasattr(client, "set_message_reaction"):
|
||||
try:
|
||||
from telegram import ReactionTypeEmoji
|
||||
|
||||
reaction = [ReactionTypeEmoji(emoji=emoji_to_use)] if is_add else []
|
||||
await client.set_message_reaction(
|
||||
chat_id=chat_id,
|
||||
message_id=int(message_id),
|
||||
reaction=reaction,
|
||||
)
|
||||
return True
|
||||
except ImportError:
|
||||
# 如果版本太低没有 ReactionTypeEmoji,尝试直接传字符串 (有些实现支持)
|
||||
await client.set_message_reaction(
|
||||
chat_id=chat_id,
|
||||
message_id=int(message_id),
|
||||
reaction=emoji_to_use if is_add else None,
|
||||
)
|
||||
return True
|
||||
return False
|
||||
except Exception as e:
|
||||
logger.debug(f"[Telegram] set_reaction 失败: {e}")
|
||||
return False
|
||||
|
||||
# ==================== 辅助方法 ====================
|
||||
|
||||
def _parse_group_id(self, group_id: str) -> tuple[str, str | None]:
|
||||
|
||||
@@ -89,3 +89,20 @@ class PlatformAdapter(
|
||||
list[dict]: 转换后的平台原生消息字典列表
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
async def set_reaction(
|
||||
self, group_id: str, message_id: str, emoji: str | int, is_add: bool = True
|
||||
) -> bool:
|
||||
"""
|
||||
对消息添加/移除表情回应。
|
||||
|
||||
Args:
|
||||
group_id (str): 群组/频道 ID
|
||||
message_id (str): 消息 ID
|
||||
emoji (str | int): 表情代码或字符
|
||||
is_add (bool): True 为添加,False 为移除
|
||||
|
||||
Returns:
|
||||
bool: 平台是否支持并成功执行
|
||||
"""
|
||||
return False
|
||||
|
||||
Reference in New Issue
Block a user