重启戳一戳并优化

pull/65/head
foxplaying 2025-10-14 22:39:49 +08:00 committed by GitHub
parent 3ca99d8490
commit 3a930c4150
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 88 additions and 65 deletions

View File

@ -115,7 +115,32 @@ class NoticeHandler:
user_id, group_id, False, False user_id, group_id, False, False
): ):
logger.info("处理戳一戳消息") logger.info("处理戳一戳消息")
handled_message, user_info = await self.handle_poke_notify(raw_message, group_id, user_id) handled_message, user_info, is_target_self = await self.handle_poke_notify(
raw_message, group_id, user_id
)
if handled_message and user_info:
if is_target_self:
await message_send_instance.message_send(
MessageBase(
message_info=BaseMessageInfo(
platform=global_config.maibot_server.platform_name,
message_id="poke",
time=time.time(),
user_info=user_info,
group_info=None,
template_info=None,
format_info=FormatInfo(
content_format=["text"],
accept_format=ACCEPT_FORMAT,
),
),
message_segment=handled_message,
raw_message=json.dumps(raw_message),
)
)
return
else:
logger.info("忽略其他事件")
else: else:
logger.warning("戳一戳消息被禁用,取消戳一戳处理") logger.warning("戳一戳消息被禁用,取消戳一戳处理")
case _: case _:
@ -287,70 +312,53 @@ class NoticeHandler:
) -> Tuple[Seg | None, UserInfo | None]: ) -> Tuple[Seg | None, UserInfo | None]:
# sourcery skip: merge-comparisons, merge-duplicate-blocks, remove-redundant-if, remove-unnecessary-else, swap-if-else-branches # sourcery skip: merge-comparisons, merge-duplicate-blocks, remove-redundant-if, remove-unnecessary-else, swap-if-else-branches
self_info: dict = await get_self_info(self.server_connection) self_info: dict = await get_self_info(self.server_connection)
if not self_info: if not self_info:
logger.error("自身信息获取失败") logger.error("自身信息获取失败")
return None, None return None, None
self_id = raw_message.get("self_id") self_id = raw_message.get("self_id")
target_id = raw_message.get("target_id") target_id = raw_message.get("target_id")
target_name: str = None
raw_info: list = raw_message.get("raw_info") raw_info: list = raw_message.get("raw_info")
if group_id: if group_id:
user_qq_info: dict = await get_member_info(self.server_connection, group_id, user_id) user_qq_info: dict = await get_member_info(self.server_connection, group_id, user_id)
else: else:
user_qq_info: dict = await get_stranger_info(self.server_connection, user_id) user_qq_info: dict = await get_stranger_info(self.server_connection, user_id)
if user_qq_info:
user_name = user_qq_info.get("nickname")
user_cardname = user_qq_info.get("card")
else:
user_name = "QQ用户"
user_cardname = "QQ用户"
logger.info("无法获取戳一戳对方的用户昵称")
# 计算Seg user_name = user_qq_info.get("nickname") if user_qq_info and user_qq_info.get("nickname") else "QQ用户"
if self_id == target_id: user_cardname = user_qq_info.get("card") if user_qq_info else None
display_name = ""
target_name = self_info.get("nickname")
elif self_id == user_id: if target_id == self_id:
# 让ada不发送麦麦戳别人的消息 # 别人戳我 → 触发回应
return None, None display_name = user_name
target_name = self_info.get("nickname") or ""
first_txt: str = "戳了戳"
second_txt: str = ""
try:
first_txt = raw_info[2].get("txt", "戳了戳")
second_txt = raw_info[4].get("txt", "")
except Exception as e:
logger.warning(f"解析戳一戳消息失败: {str(e)},将使用默认文本")
text_str = f"{display_name}{first_txt}{target_name}{second_txt}这是QQ的一个功能用于提及某人但没那么明显"
seg_data: Seg = Seg(type="text", data=text_str)
user_info: UserInfo = UserInfo(
platform=global_config.maibot_server.platform_name,
user_id=user_id,
user_nickname=user_name,
user_cardname=user_cardname,
)
return seg_data, user_info, True
elif user_id == self_id:
# bot戳别人 → 忽略,防止循环
return None, None, False
else: else:
# 老实说这一步判定没啥意义,毕竟私聊是没有其他人之间的戳一戳,但是感觉可以有这个判定来强限制群聊环境 # 群内用户互戳、私聊他人戳他人 → 忽略
if group_id: return None, None, False
fetched_member_info: dict = await get_member_info(self.server_connection, group_id, target_id)
if fetched_member_info:
target_name = fetched_member_info.get("nickname")
else:
target_name = "QQ用户"
logger.info("无法获取被戳一戳方的用户昵称")
display_name = user_name
else:
return None, None
first_txt: str = "戳了戳"
second_txt: str = ""
try:
first_txt = raw_info[2].get("txt", "戳了戳")
second_txt = raw_info[4].get("txt", "")
except Exception as e:
logger.warning(f"解析戳一戳消息失败: {str(e)},将使用默认文本")
user_info: UserInfo = UserInfo(
platform=global_config.maibot_server.platform_name,
user_id=user_id,
user_nickname=user_name,
user_cardname=user_cardname,
)
seg_data: Seg = Seg(
type="text",
data=f"{display_name}{first_txt}{target_name}{second_txt}这是QQ的一个功能用于提及某人但没那么明显",
)
return seg_data, user_info
async def handle_ban_notify(self, raw_message: dict, group_id: int) -> Tuple[Seg, UserInfo] | Tuple[None, None]: async def handle_ban_notify(self, raw_message: dict, group_id: int) -> Tuple[Seg, UserInfo] | Tuple[None, None]:
if not group_id: if not group_id:
@ -596,7 +604,7 @@ class NoticeHandler:
platform=global_config.maibot_server.platform_name, platform=global_config.maibot_server.platform_name,
message_id="notice", message_id="notice",
time=time.time(), time=time.time(),
user_info=None, # 自然解除禁言没有操作者 user_info=None, # 自然解除禁言没有操作者
group_info=group_info, group_info=group_info,
template_info=None, template_info=None,
format_info=None, format_info=None,
@ -643,6 +651,11 @@ class NoticeHandler:
user_nickname = fetched_member_info.get("nickname") user_nickname = fetched_member_info.get("nickname")
user_cardname = fetched_member_info.get("card") user_cardname = fetched_member_info.get("card")
self_info = await get_self_info(self.server_connection)
self_id = self_info.get("user_id") if self_info else None
if self_id and user_id == self_id:
user_nickname = f"{user_nickname} (我)"
lifted_user_info: UserInfo = UserInfo( lifted_user_info: UserInfo = UserInfo(
platform=global_config.maibot_server.platform_name, platform=global_config.maibot_server.platform_name,
user_id=user_id, user_id=user_id,
@ -664,6 +677,8 @@ class NoticeHandler:
async def auto_lift_detect(self) -> None: async def auto_lift_detect(self) -> None:
while True: while True:
self_info = await get_self_info(self.server_connection)
self_id = self_info.get("user_id") if self_info else None
if len(self.banned_list) == 0: if len(self.banned_list) == 0:
await asyncio.sleep(5) await asyncio.sleep(5)
continue continue
@ -673,7 +688,8 @@ class NoticeHandler:
if ban_record.lift_time <= int(time.time()): if ban_record.lift_time <= int(time.time()):
if ban_record.user_id == self_id: if ban_record.user_id == self_id:
logger.info(f"检测到 Bot 自身在群 {ban_record.group_id} 的禁言已解除") logger.info(f"检测到 Bot 自身在群 {ban_record.group_id} 的禁言已解除")
await self.handle_self_mute_lift(ban_record.group_id) if hasattr(self, "handle_self_mute_lift"):
await self.handle_self_mute_lift(ban_record.group_id)
else: else:
logger.info(f"检测到用户 {ban_record.user_id} 在群 {ban_record.group_id} 的禁言已解除") logger.info(f"检测到用户 {ban_record.user_id} 在群 {ban_record.group_id} 的禁言已解除")
self.lifted_list.append(ban_record) self.lifted_list.append(ban_record)
@ -685,30 +701,37 @@ class NoticeHandler:
发送通知消息到Napcat 发送通知消息到Napcat
""" """
while True: while True:
if not unsuccessful_notice_queue.empty(): try:
to_be_send: MessageBase = await unsuccessful_notice_queue.get() if not unsuccessful_notice_queue.empty():
to_be_send: MessageBase = await unsuccessful_notice_queue.get()
try:
send_status = await message_send_instance.message_send(to_be_send)
if send_status:
unsuccessful_notice_queue.task_done()
else:
await unsuccessful_notice_queue.put(to_be_send)
except Exception as e:
logger.error(f"发送通知消息失败: {str(e)}")
await unsuccessful_notice_queue.put(to_be_send)
await asyncio.sleep(1)
continue
to_be_send: MessageBase = await notice_queue.get()
try: try:
send_status = await message_send_instance.message_send(to_be_send) send_status = await message_send_instance.message_send(to_be_send)
if send_status: if send_status:
unsuccessful_notice_queue.task_done() notice_queue.task_done()
else: else:
await unsuccessful_notice_queue.put(to_be_send) await unsuccessful_notice_queue.put(to_be_send)
except Exception as e: except Exception as e:
logger.error(f"发送通知消息失败: {str(e)}") logger.error(f"发送通知消息失败: {str(e)}")
await unsuccessful_notice_queue.put(to_be_send) await unsuccessful_notice_queue.put(to_be_send)
await asyncio.sleep(1) await asyncio.sleep(1)
continue except asyncio.CancelledError:
to_be_send: MessageBase = await notice_queue.get() logger.warning("send_notice 任务被取消,安全退出循环")
try: break
send_status = await message_send_instance.message_send(to_be_send)
if send_status:
notice_queue.task_done()
else:
await unsuccessful_notice_queue.put(to_be_send)
except Exception as e: except Exception as e:
logger.error(f"发送通知消息失败: {str(e)}") logger.error(f"通知循环出现异常: {e}")
await unsuccessful_notice_queue.put(to_be_send) await asyncio.sleep(3)
await asyncio.sleep(1)
notice_handler = NoticeHandler() notice_handler = NoticeHandler()