feat: prefer qq group cards across messaging

pull/1334/head
magisk317 2025-10-29 18:10:03 +08:00
parent 4d5456ed4b
commit ae1a1d4a56
8 changed files with 58 additions and 22 deletions

View File

@ -81,12 +81,14 @@ class HeartFCMessageReceiver:
# if not processed_plain_text:
# print(message)
logger.info(f"[{mes_name}]{userinfo.user_nickname}:{processed_plain_text}") # type: ignore
display_name = userinfo.user_cardname or userinfo.user_nickname # type: ignore
logger.info(f"[{mes_name}]{display_name}:{processed_plain_text}") # type: ignore
preferred_name = display_name or userinfo.user_nickname # type: ignore
_ = Person.register_person(
platform=message.message_info.platform, # type: ignore
user_id=message.message_info.user_info.user_id, # type: ignore
nickname=userinfo.user_nickname, # type: ignore
nickname=preferred_name, # type: ignore
)
except Exception as e:

View File

@ -40,7 +40,8 @@ def _check_ban_words(text: str, userinfo: UserInfo, group_info: Optional[GroupIn
for word in global_config.message_receive.ban_words:
if word in text:
chat_name = group_info.group_name if group_info else "私聊"
logger.info(f"[{chat_name}]{userinfo.user_nickname}:{text}")
display_name = userinfo.user_cardname or userinfo.user_nickname
logger.info(f"[{chat_name}]{display_name}:{text}")
logger.info(f"[过滤词识别]消息中含有{word}filtered")
return True
return False
@ -64,7 +65,8 @@ def _check_ban_regex(text: str, userinfo: UserInfo, group_info: Optional[GroupIn
for pattern in global_config.message_receive.ban_msgs_regex:
if re.search(pattern, text):
chat_name = group_info.group_name if group_info else "私聊"
logger.info(f"[{chat_name}]{userinfo.user_nickname}:{text}")
display_name = userinfo.user_cardname or userinfo.user_nickname
logger.info(f"[{chat_name}]{display_name}:{text}")
logger.info(f"[正则表达式过滤]消息匹配到{pattern}filtered")
return True
return False
@ -206,6 +208,13 @@ class ChatBot:
group_info = message.message_info.group_info
user_info = message.message_info.user_info
if (
group_info
and user_info
and (not user_info.user_cardname or not str(user_info.user_cardname).strip())
):
user_info.user_cardname = user_info.user_nickname or ""
continue_flag, modified_message = await events_manager.handle_mai_events(
EventType.ON_MESSAGE_PRE_PROCESS, message
)

View File

@ -313,8 +313,10 @@ class ChatManager:
if stream.group_info and stream.group_info.group_name:
return stream.group_info.group_name
elif stream.user_info and stream.user_info.user_nickname:
return f"{stream.user_info.user_nickname}的私聊"
elif stream.user_info:
display_name = stream.user_info.user_cardname or stream.user_info.user_nickname
if display_name:
return f"{display_name}的私聊"
else:
return None

View File

@ -283,7 +283,11 @@ class MessageProcessBase(Message):
if self.reply and hasattr(self.reply, "processed_plain_text"):
# print(f"self.reply.processed_plain_text: {self.reply.processed_plain_text}")
# print(f"reply: {self.reply}")
return f"[回复<{self.reply.message_info.user_info.user_nickname}:{self.reply.message_info.user_info.user_id}> 的消息:{self.reply.processed_plain_text}]" # type: ignore
reply_user_info = self.reply.message_info.user_info # type: ignore
reply_name = reply_user_info.user_cardname or reply_user_info.user_nickname # type: ignore
return (
f"[回复<{reply_name}:{reply_user_info.user_id}> 的消息:{self.reply.processed_plain_text}]"
) # type: ignore
return ""
else:
return f"[{segment.type}:{str(segment.data)}]"

View File

@ -413,7 +413,8 @@ def _build_readable_messages_internal(
if message.is_action_record:
# 对于动作记录也处理图片ID
content = process_pic_ids(message.display_message)
detailed_messages_raw.append((message.time, message.user_nickname, content, True))
action_name = message.user_cardname or message.user_nickname or "系统"
detailed_messages_raw.append((message.time, action_name, content, True))
continue
platform = message.user_platform
@ -434,9 +435,9 @@ def _build_readable_messages_internal(
person = Person(platform=platform, user_id=user_id)
# 根据 replace_bot_name 参数决定是否替换机器人名称
person_name = (
person.person_name or f"{user_nickname}" or (f"昵称:{user_cardname}" if user_cardname else "某人")
)
preferred_display = user_cardname or user_nickname
fallback_display = user_nickname or user_cardname or "某人"
person_name = person.person_name or preferred_display or fallback_display
if replace_bot_name and (
(platform == global_config.bot.platform and user_id == global_config.bot.qq_account)
or (platform == "telegram" and user_id == getattr(global_config.bot, "telegram_account", ""))

View File

@ -480,7 +480,7 @@ class StatisticOutputTask(AsyncTask):
elif message.user_id: # Fallback to sender's info for chat_id if not a group_info based chat
# This uses the message SENDER's ID as per original logic's fallback
chat_id = f"u{message.user_id}" # SENDER's user_id
chat_name = message.user_nickname # SENDER's nickname
chat_name = message.user_cardname or message.user_nickname # SENDER's display name
else:
# If neither group_id nor sender_id is available for chat identification
logger.warning(
@ -704,7 +704,7 @@ class StatisticOutputTask(AsyncTask):
if group_name and group_name.strip():
return group_name.strip()
elif stream.user_info and hasattr(stream.user_info, "user_nickname"):
user_name = stream.user_info.user_nickname
user_name = stream.user_info.user_cardname or stream.user_info.user_nickname
if user_name and user_name.strip():
return user_name.strip()
@ -1293,7 +1293,7 @@ class StatisticOutputTask(AsyncTask):
if message.chat_info_group_id:
chat_name = message.chat_info_group_name or f"{message.chat_info_group_id}"
elif message.user_id:
chat_name = message.user_nickname or f"用户{message.user_id}"
chat_name = (message.user_cardname or message.user_nickname) or f"用户{message.user_id}"
else:
continue

View File

@ -585,10 +585,11 @@ def get_chat_type_and_target_info(chat_id: str) -> Tuple[bool, Optional["TargetP
from src.common.data_models.info_data_model import TargetPersonInfo # 解决循环导入问题
# Initialize target_info with basic info
display_name = user_info.user_cardname or user_info.user_nickname # type: ignore
target_info = TargetPersonInfo(
platform=platform,
user_id=user_id,
user_nickname=user_info.user_nickname, # type: ignore
user_nickname=display_name, # type: ignore
person_id=None,
person_name=None,
)
@ -597,7 +598,7 @@ def get_chat_type_and_target_info(chat_id: str) -> Tuple[bool, Optional["TargetP
try:
person = Person(platform=platform, user_id=user_id)
if not person.is_known:
logger.warning(f"用户 {user_info.user_nickname} 尚未认识")
logger.warning(f"用户 {display_name} 尚未认识")
# 如果用户尚未认识则返回False和None
return False, None
if person.person_id:

View File

@ -173,7 +173,11 @@ class Person:
Returns:
Person: 新注册的Person实例
"""
if not platform or not user_id or not nickname:
display_name = (nickname or "").strip()
if not display_name:
display_name = f"用户{user_id}" if user_id else "未知用户"
if not platform or not user_id:
logger.error("注册用户失败platform、user_id 和 nickname 都是必需参数")
return None
@ -181,8 +185,21 @@ class Person:
person_id = get_person_id(platform, user_id)
if is_person_known(person_id=person_id):
logger.debug(f"用户 {nickname} 已存在")
return Person(person_id=person_id)
person = Person(person_id=person_id)
if not person or not person.is_known:
return person
old_nickname = person.nickname or ""
old_person_name = person.person_name
if display_name != old_nickname:
person.nickname = display_name
if not old_person_name or old_person_name == old_nickname:
person.person_name = display_name
person.sync_to_database()
logger.debug(
f"更新用户 {person_id} 的昵称信息: '{old_nickname}' -> '{display_name}'"
)
return person
# 创建Person实例
person = cls.__new__(cls)
@ -191,11 +208,11 @@ class Person:
person.person_id = person_id
person.platform = platform
person.user_id = user_id
person.nickname = nickname
person.nickname = display_name
# 初始化默认值
person.is_known = True # 注册后立即标记为已认识
person.person_name = nickname # 使用nickname作为初始person_name
person.person_name = display_name # 使用nickname作为初始person_name
person.name_reason = "用户注册时设置的昵称"
person.know_times = 1
person.know_since = time.time()
@ -205,7 +222,7 @@ class Person:
# 同步到数据库
person.sync_to_database()
logger.info(f"成功注册新用户:{person_id},平台:{platform},昵称:{nickname}")
logger.info(f"成功注册新用户:{person_id},平台:{platform},昵称:{display_name}")
return person