fix: unique session config cannot be applied in non-default astrbot config (#4232)

* fix: unique session config cannot be applied in non-default astrbot config

fixes: #4195

* perf: sesison id
This commit is contained in:
Soulter
2025-12-28 15:01:43 +08:00
committed by GitHub
parent f51810997a
commit fc61f7ad32
11 changed files with 61 additions and 85 deletions

View File

@@ -1,9 +1,10 @@
from collections.abc import AsyncGenerator
from collections.abc import AsyncGenerator, Callable
from astrbot import logger
from astrbot.core.message.components import At, AtAll, Reply
from astrbot.core.message.message_event_result import MessageChain, MessageEventResult
from astrbot.core.platform.astr_message_event import AstrMessageEvent
from astrbot.core.platform.message_type import MessageType
from astrbot.core.star.filter.command_group import CommandGroupFilter
from astrbot.core.star.filter.permission import PermissionTypeFilter
from astrbot.core.star.session_plugin_manager import SessionPluginManager
@@ -13,6 +14,23 @@ from astrbot.core.star.star_handler import EventType, star_handlers_registry
from ..context import PipelineContext
from ..stage import Stage, register_stage
UNIQUE_SESSION_ID_BUILDERS: dict[str, Callable[[AstrMessageEvent], str | None]] = {
"aiocqhttp": lambda e: f"{e.get_sender_id()}_{e.get_group_id()}",
"slack": lambda e: f"{e.get_sender_id()}_{e.get_group_id()}",
"dingtalk": lambda e: e.get_sender_id(),
"qq_official": lambda e: e.get_sender_id(),
"qq_official_webhook": lambda e: e.get_sender_id(),
"lark": lambda e: f"{e.get_sender_id()}%{e.get_group_id()}",
"misskey": lambda e: f"{e.get_session_id()}_{e.get_sender_id()}",
"wechatpadpro": lambda e: f"{e.get_group_id()}#{e.get_sender_id()}",
}
def build_unique_session_id(event: AstrMessageEvent) -> str | None:
platform = event.get_platform_name()
builder = UNIQUE_SESSION_ID_BUILDERS.get(platform)
return builder(event) if builder else None
@register_stage
class WakingCheckStage(Stage):
@@ -53,18 +71,27 @@ class WakingCheckStage(Stage):
self.disable_builtin_commands = self.ctx.astrbot_config.get(
"disable_builtin_commands", False
)
platform_settings = self.ctx.astrbot_config.get("platform_settings", {})
self.unique_session = platform_settings.get("unique_session", False)
async def process(
self,
event: AstrMessageEvent,
) -> None | AsyncGenerator[None, None]:
# apply unique session
if self.unique_session and event.message_obj.type == MessageType.GROUP_MESSAGE:
sid = build_unique_session_id(event)
if sid:
event.session_id = sid
# ignore bot self message
if (
self.ignore_bot_self_message
and event.get_self_id() == event.get_sender_id()
):
# 忽略机器人自己发送的消息
event.stop_event()
return
# 设置 sender 身份
event.message_str = event.message_str.strip()
for admin_id in self.ctx.astrbot_config["admins_id"]:

View File

@@ -41,7 +41,6 @@ class AiocqhttpAdapter(Platform):
super().__init__(platform_config, event_queue)
self.settings = platform_settings
self.unique_session = platform_settings["unique_session"]
self.host = platform_config["ws_reverse_host"]
self.port = platform_config["ws_reverse_port"]
@@ -136,14 +135,11 @@ class AiocqhttpAdapter(Platform):
abm.group_id = str(event.group_id)
else:
abm.type = MessageType.FRIEND_MESSAGE
if self.unique_session and abm.type == MessageType.GROUP_MESSAGE:
abm.session_id = str(abm.sender.user_id) + "_" + str(event.group_id)
else:
abm.session_id = (
str(event.group_id)
if abm.type == MessageType.GROUP_MESSAGE
else abm.sender.user_id
)
abm.session_id = (
str(event.group_id)
if abm.type == MessageType.GROUP_MESSAGE
else abm.sender.user_id
)
abm.message_str = ""
abm.message = []
abm.timestamp = int(time.time())
@@ -164,16 +160,11 @@ class AiocqhttpAdapter(Platform):
abm.type = MessageType.GROUP_MESSAGE
else:
abm.type = MessageType.FRIEND_MESSAGE
if self.unique_session and abm.type == MessageType.GROUP_MESSAGE:
abm.session_id = (
str(abm.sender.user_id) + "_" + str(event.group_id)
) # 也保留群组 id
else:
abm.session_id = (
str(event.group_id)
if abm.type == MessageType.GROUP_MESSAGE
else abm.sender.user_id
)
abm.session_id = (
str(event.group_id)
if abm.type == MessageType.GROUP_MESSAGE
else abm.sender.user_id
)
abm.message_str = ""
abm.message = []
abm.raw_message = event
@@ -210,16 +201,11 @@ class AiocqhttpAdapter(Platform):
abm.group.group_name = event.get("group_name", "N/A")
elif event["message_type"] == "private":
abm.type = MessageType.FRIEND_MESSAGE
if self.unique_session and abm.type == MessageType.GROUP_MESSAGE:
abm.session_id = (
abm.sender.user_id + "_" + str(event.group_id)
) # 也保留群组 id
else:
abm.session_id = (
str(event.group_id)
if abm.type == MessageType.GROUP_MESSAGE
else abm.sender.user_id
)
abm.session_id = (
str(event.group_id)
if abm.type == MessageType.GROUP_MESSAGE
else abm.sender.user_id
)
abm.message_id = str(event.message_id)
abm.message = []

View File

@@ -50,8 +50,6 @@ class DingtalkPlatformAdapter(Platform):
) -> None:
super().__init__(platform_config, event_queue)
self.unique_session = platform_settings["unique_session"]
self.client_id = platform_config["client_id"]
self.client_secret = platform_config["client_secret"]
@@ -129,10 +127,7 @@ class DingtalkPlatformAdapter(Platform):
if id := self._id_to_sid(user.dingtalk_id):
abm.message.append(At(qq=id))
abm.group_id = message.conversation_id
if self.unique_session:
abm.session_id = abm.sender.user_id
else:
abm.session_id = abm.group_id
abm.session_id = abm.group_id
else:
abm.session_id = abm.sender.user_id

View File

@@ -44,8 +44,6 @@ class LarkPlatformAdapter(Platform):
) -> None:
super().__init__(platform_config, event_queue)
self.unique_session = platform_settings["unique_session"]
self.appid = platform_config["app_id"]
self.appsecret = platform_config["app_secret"]
self.domain = platform_config.get("domain", lark.FEISHU_DOMAIN)
@@ -317,14 +315,8 @@ class LarkPlatformAdapter(Platform):
user_id=event.event.sender.sender_id.open_id,
nickname=event.event.sender.sender_id.open_id[:8],
)
# 独立会话
if not self.unique_session:
if abm.type == MessageType.GROUP_MESSAGE:
abm.session_id = abm.group_id
else:
abm.session_id = abm.sender.user_id
elif abm.type == MessageType.GROUP_MESSAGE:
abm.session_id = f"{abm.sender.user_id}%{abm.group_id}" # 也保留群组id
if abm.type == MessageType.GROUP_MESSAGE:
abm.session_id = abm.group_id
else:
abm.session_id = abm.sender.user_id

View File

@@ -91,8 +91,6 @@ class MisskeyPlatformAdapter(Platform):
except Exception:
self.max_download_bytes = None
self.unique_session = platform_settings["unique_session"]
self.api: MisskeyAPI | None = None
self._running = False
self.client_self_id = ""
@@ -641,7 +639,6 @@ class MisskeyPlatformAdapter(Platform):
sender_info,
self.client_self_id,
is_chat=False,
unique_session=self.unique_session,
)
cache_user_info(
self._user_cache,
@@ -690,7 +687,6 @@ class MisskeyPlatformAdapter(Platform):
sender_info,
self.client_self_id,
is_chat=True,
unique_session=self.unique_session,
)
cache_user_info(
self._user_cache,
@@ -720,7 +716,6 @@ class MisskeyPlatformAdapter(Platform):
self.client_self_id,
is_chat=False,
room_id=room_id,
unique_session=self.unique_session,
)
cache_user_info(

View File

@@ -338,7 +338,6 @@ def create_base_message(
client_self_id: str,
is_chat: bool = False,
room_id: str | None = None,
unique_session: bool = False,
) -> AstrBotMessage:
"""创建基础消息对象"""
message = AstrBotMessage()
@@ -353,8 +352,6 @@ def create_base_message(
if room_id:
session_prefix = "room"
session_id = f"{session_prefix}%{room_id}"
if unique_session:
session_id += f"_{sender_info['sender_id']}"
message.type = MessageType.GROUP_MESSAGE
message.group_id = room_id
elif is_chat:

View File

@@ -44,11 +44,8 @@ class botClient(Client):
message,
MessageType.GROUP_MESSAGE,
)
abm.session_id = (
abm.sender.user_id
if self.platform.unique_session
else cast(str, message.group_openid)
)
abm.group_id = cast(str, message.group_openid)
abm.session_id = abm.group_id
self._commit(abm)
# 收到频道消息
@@ -57,9 +54,8 @@ class botClient(Client):
message,
MessageType.GROUP_MESSAGE,
)
abm.session_id = (
abm.sender.user_id if self.platform.unique_session else message.channel_id
)
abm.group_id = message.channel_id
abm.session_id = abm.group_id
self._commit(abm)
# 收到私聊消息
@@ -104,7 +100,6 @@ class QQOfficialPlatformAdapter(Platform):
self.appid = platform_config["appid"]
self.secret = platform_config["secret"]
self.unique_session: bool = platform_settings["unique_session"]
qq_group = platform_config["enable_group_c2c"]
guild_dm = platform_config["enable_guild_direct_message"]

View File

@@ -35,11 +35,8 @@ class botClient(Client):
message,
MessageType.GROUP_MESSAGE,
)
abm.session_id = (
abm.sender.user_id
if self.platform.unique_session
else cast(str, message.group_openid)
)
abm.group_id = cast(str, message.group_openid)
abm.session_id = abm.group_id
self._commit(abm)
# 收到频道消息
@@ -48,9 +45,8 @@ class botClient(Client):
message,
MessageType.GROUP_MESSAGE,
)
abm.session_id = (
abm.sender.user_id if self.platform.unique_session else message.channel_id
)
abm.group_id = message.channel_id
abm.session_id = abm.group_id
self._commit(abm)
# 收到私聊消息
@@ -95,7 +91,6 @@ class QQOfficialWebhookPlatformAdapter(Platform):
self.appid = platform_config["appid"]
self.secret = platform_config["secret"]
self.unique_session = platform_settings["unique_session"]
self.unified_webhook_mode = platform_config.get("unified_webhook_mode", False)
intents = botpy.Intents(

View File

@@ -41,7 +41,6 @@ class SlackAdapter(Platform):
) -> None:
super().__init__(platform_config, event_queue)
self.settings = platform_settings
self.unique_session = platform_settings.get("unique_session", False)
self.bot_token = platform_config.get("bot_token")
self.app_token = platform_config.get("app_token")
@@ -147,12 +146,10 @@ class SlackAdapter(Platform):
abm.group_id = channel_id
# 设置会话ID
if self.unique_session and abm.type == MessageType.GROUP_MESSAGE:
abm.session_id = f"{user_id}_{channel_id}"
if abm.type == MessageType.GROUP_MESSAGE:
abm.session_id = abm.group_id
else:
abm.session_id = (
channel_id if abm.type == MessageType.GROUP_MESSAGE else user_id
)
abm.session_id = user_id
abm.message_id = event.get("client_msg_id", uuid.uuid4().hex)
abm.timestamp = int(float(event.get("ts", time.time())))

View File

@@ -79,7 +79,6 @@ class WebChatAdapter(Platform):
super().__init__(platform_config, event_queue)
self.settings = platform_settings
self.unique_session = platform_settings["unique_session"]
self.imgs_dir = os.path.join(get_astrbot_data_path(), "webchat", "imgs")
os.makedirs(self.imgs_dir, exist_ok=True)

View File

@@ -47,7 +47,6 @@ class WeChatPadProAdapter(Platform):
self._shutdown_event = None
self.wxnewpass = None
self.settings = platform_settings
self.unique_session = platform_settings.get("unique_session", False)
self.metadata = PlatformMetadata(
name="wechatpadpro",
@@ -509,11 +508,10 @@ class WeChatPadProAdapter(Platform):
if accurate_nickname:
abm.sender.nickname = accurate_nickname
# 对于群聊session_id 可以是群聊 ID 或发送者 ID + 群聊 ID (如果 unique_session 为 True)
if self.unique_session:
abm.session_id = f"{from_user_name}#{abm.sender.user_id}"
if abm.type == MessageType.GROUP_MESSAGE:
abm.session_id = abm.group_id
else:
abm.session_id = from_user_name
abm.session_id = abm.sender.user_id
msg_source = raw_message.get("msg_source", "")
if self.wxid in msg_source: