fix: make bot identity platform-aware

This commit is contained in:
晴猫
2026-03-15 07:22:08 +09:00
parent 34ffc56b85
commit 267b42001e
15 changed files with 311 additions and 141 deletions

View File

@@ -1,18 +1,18 @@
import ast
import json
import os
import random
import re
import time
import jieba
import json
import ast
import os
from datetime import datetime
from typing import Optional, Tuple, List, TYPE_CHECKING
import jieba
from src.chat.message_receive.chat_manager import chat_manager as _chat_manager
from src.chat.message_receive.message import SessionMessage
from src.common.logger import get_logger
from src.config.config import global_config, model_config
from src.chat.message_receive.message import SessionMessage
from src.chat.message_receive.chat_manager import chat_manager as _chat_manager
from src.llm_models.utils_model import LLMRequest
from src.person_info.person_info import Person
from .typo_generator import ChineseTypoGenerator
@@ -37,33 +37,64 @@ def parse_platform_accounts(platforms: list[str]) -> dict[str, str]:
Returns:
字典,键为平台名,值为账号
"""
result = {}
result: dict[str, str] = {}
for platform_entry in platforms:
if ":" in platform_entry:
platform_name, account = platform_entry.split(":", 1)
result[platform_name.strip()] = account.strip()
normalized_platform = platform_name.lower().strip()
account_str = account.strip()
if normalized_platform and account_str:
result[normalized_platform] = account_str
return result
def get_current_platform_account(platform: str, platform_accounts: dict[str, str], qq_account: str) -> str:
"""根据当前平台获取对应的账号
def _get_configured_qq_account() -> str:
qq_account = str(getattr(global_config.bot, "qq_account", "")).strip()
if qq_account in {"", "0"}:
return ""
return qq_account
Args:
platform: 当前消息的平台
platform_accounts: 从 platforms 列表解析的平台账号映射
qq_account: QQ 账号(兼容旧配置)
Returns:
当前平台对应的账号
"""
if platform == "qq":
def get_bot_account(platform: str) -> str:
"""根据当前平台获取对应的机器人账号"""
normalized_platform = str(platform or "").strip().lower()
if not normalized_platform:
return ""
qq_account = _get_configured_qq_account()
if normalized_platform in {"qq", "webui"}:
return qq_account
elif platform == "telegram":
# 优先使用 tg其次使用 telegram
platforms_list = getattr(global_config.bot, "platforms", []) or []
platform_accounts = parse_platform_accounts(platforms_list)
if normalized_platform in {"tg", "telegram"}:
return platform_accounts.get("tg", "") or platform_accounts.get("telegram", "")
else:
# 其他平台直接使用平台名作为键
return platform_accounts.get(platform, "")
return platform_accounts.get(normalized_platform, "")
def get_all_bot_accounts() -> dict[str, str]:
"""获取所有已配置的机器人运行时身份。"""
bot_accounts: dict[str, str] = {}
qq_account = _get_configured_qq_account()
if qq_account:
bot_accounts["qq"] = qq_account
bot_accounts["webui"] = qq_account
platforms_list = getattr(global_config.bot, "platforms", []) or []
platform_accounts = parse_platform_accounts(platforms_list)
telegram_account = platform_accounts.get("tg", "") or platform_accounts.get("telegram", "")
if telegram_account:
bot_accounts["telegram"] = telegram_account
bot_accounts["tg"] = telegram_account
for platform_name, account in platform_accounts.items():
if platform_name in {"tg", "telegram"}:
continue
bot_accounts[platform_name] = account
return bot_accounts
def is_bot_self(platform: str, user_id: str) -> bool:
@@ -78,39 +109,21 @@ def is_bot_self(platform: str, user_id: str) -> bool:
Returns:
bool: 如果是机器人自己则返回 True否则返回 False
"""
if not platform or not user_id:
normalized_platform = str(platform or "").strip().lower()
if not normalized_platform or not user_id:
return False
# 将 user_id 转为字符串进行比较
user_id_str = str(user_id)
user_id_str = str(user_id).strip()
if not user_id_str:
return False
# 获取机器人的 QQ 账号(主账号)
qq_account = str(global_config.bot.qq_account or "")
bot_account = get_bot_account(normalized_platform)
if bot_account:
return user_id_str == bot_account
# QQ 平台:直接比较 QQ 账号
if platform == "qq":
return user_id_str == qq_account
# WebUI 平台:机器人回复时使用的是 QQ 账号,所以也比较 QQ 账号
if platform == "webui":
return user_id_str == qq_account
# 获取各平台账号映射
platforms_list = getattr(global_config.bot, "platforms", []) or []
platform_accounts = parse_platform_accounts(platforms_list)
# Telegram 平台
if platform == "telegram":
tg_account = platform_accounts.get("tg", "") or platform_accounts.get("telegram", "")
return user_id_str == tg_account if tg_account else False
# 其他平台:尝试从 platforms 配置中查找
platform_account = platform_accounts.get(platform, "")
if platform_account:
return user_id_str == platform_account
# 默认情况:与主 QQ 账号比较(兼容性)
return user_id_str == qq_account
logger.warning(f"平台 {normalized_platform} 未配置机器人账号,无法判断用户 {user_id_str} 是否为机器人自己")
return False
def is_mentioned_bot_in_message(message: SessionMessage) -> tuple[bool, bool, float]:
@@ -118,13 +131,8 @@ def is_mentioned_bot_in_message(message: SessionMessage) -> tuple[bool, bool, fl
text = message.processed_plain_text or ""
platform = message.platform or ""
# 获取各平台账号
platforms_list = getattr(global_config.bot, "platforms", []) or []
platform_accounts = parse_platform_accounts(platforms_list)
qq_account = str(getattr(global_config.bot, "qq_account", "") or "")
# 获取当前平台对应的账号
current_account = get_current_platform_account(platform, platform_accounts, qq_account)
current_account = get_bot_account(platform)
nickname = str(global_config.bot.nickname or "")
alias_names = list(getattr(global_config.bot, "alias_names", []) or [])