Skip to content
AstrBot
Main Navigation 主页博客路线图HTTP API

简体中文

English

简体中文

English

切换日光/暗黑模式

简介和部署接入消息平台接入 AI使用开发
Sidebar Navigation

简介

关于 AstrBot

社区

常见问题

部署

包管理器部署

雨云一键云部署

桌面客户端部署

启动器一键部署

Docker 部署

Kubernetes 部署

宝塔面板部署

1Panel 部署

手动部署

其他部署方式

CasaOS 部署

优云智算 GPU 部署

社区提供的部署方式

支持我们

接入消息平台

快速接入指南

QQ 官方机器人

Websockets 方式(推荐)

Webhook 方式

OneBot v11

NapCat

Lagrange

其他端

企微应用

企微智能机器人

微信公众号

飞书

钉钉

Telegram

LINE

Slack

Misskey

Discord

KOOK

Satori

使用 LLOneBot

使用 server-satori

社区提供

Matrix

VoceChat

接入 AI

✨ 接入模型服务

NewAPI

AIHubMix

PPIO 派欧云

硅基流动

小马算力

302.AI

Ollama

LMStudio

⚙️ Agent 执行器

内置 Agent 执行器

Dify

扣子 Coze

阿里云百炼应用

DeerFlow

使用

WebUI

插件

内置指令

工具使用 Tools

技能 Skills

SubAgent 编排

主动型 Agent 能力

MCP

网页搜索

知识库

自定义规则

Agent 执行器

统一 Webhook 模式

自动上下文压缩

Agent 沙箱环境

开发

插件开发

🌠 从这里开始

最小实例

接收消息事件

发送消息

插件配置

调用 AI

存储

文转图

会话控制器

杂项

发布插件

插件指南(旧)

接入平台适配器

AstrBot HTTP API

AstrBot 配置文件

其他

自部署文转图

插件下载不了?试试自建 GitHub 加速服务

开源之夏

OSPP 2025

目录

会话控制 ​

大于等于 v3.4.36

为什么需要会话控制?考虑一个 成语接龙 插件,某个/群用户需要和机器人进行多次对话,而不是一次性的指令。这时候就需要会话控制。

txt
用户: /成语接龙
机器人: 请发送一个成语
用户: 一马当先
机器人: 先见之明
用户: 明察秋毫
...

AstrBot 提供了开箱即用的会话控制功能:

导入:

py
import astrbot.api.message_components as Comp
from astrbot.core.utils.session_waiter import (
    session_waiter,
    SessionController,
)

handler 内的代码可以如下:

python
from astrbot.api.event import filter, AstrMessageEvent

@filter.command("成语接龙")
async def handle_empty_mention(self, event: AstrMessageEvent):
    """成语接龙具体实现"""
    try:
        yield event.plain_result("请发送一个成语~")

        # 具体的会话控制器使用方法
        @session_waiter(timeout=60, record_history_chains=False) # 注册一个会话控制器,设置超时时间为 60 秒,不记录历史消息链
        async def empty_mention_waiter(controller: SessionController, event: AstrMessageEvent):
            idiom = event.message_str # 用户发来的成语,假设是 "一马当先"

            if idiom == "退出":   # 假设用户想主动退出成语接龙,输入了 "退出"
                await event.send(event.plain_result("已退出成语接龙~"))
                controller.stop()    # 停止会话控制器,会立即结束。
                return

            if len(idiom) != 4:   # 假设用户输入的不是4字成语
                await event.send(event.plain_result("成语必须是四个字的呢~"))  # 发送回复,不能使用 yield
                return
                # 退出当前方法,不执行后续逻辑,但此会话并未中断,后续的用户输入仍然会进入当前会话

            # ...
            message_result = event.make_result()
            message_result.chain = [Comp.Plain("先见之明")] # import astrbot.api.message_components as Comp
            await event.send(message_result) # 发送回复,不能使用 yield

            controller.keep(timeout=60, reset_timeout=True) # 重置超时时间为 60s,如果不重置,则会继续之前的超时时间计时。

            # controller.stop() # 停止会话控制器,会立即结束。
            # 如果记录了历史消息链,可以通过 controller.get_history_chains() 获取历史消息链

        try:
            await empty_mention_waiter(event)
        except TimeoutError as _: # 当超时后,会话控制器会抛出 TimeoutError
            yield event.plain_result("你超时了!")
        except Exception as e:
            yield event.plain_result("发生错误,请联系管理员: " + str(e))
        finally:
            event.stop_event()
    except Exception as e:
        logger.error("handle_empty_mention error: " + str(e))

当激活会话控制器后,该发送人之后发送的消息会首先经过上面你定义的 empty_mention_waiter 函数处理,直到会话控制器被停止或者超时。

SessionController ​

用于开发者控制这个会话是否应该结束,并且可以拿到历史消息链。

  • keep(): 保持这个会话
    • timeout (float): 必填。会话超时时间。
    • reset_timeout (bool): 设置为 True 时, 代表重置超时时间, timeout 必须 > 0, 如果 <= 0 则立即结束会话。设置为 False 时, 代表继续维持原来的超时时间, 新 timeout = 原来剩余的 timeout + timeout (可以 < 0)
  • stop(): 结束这个会话
  • get_history_chains() -> List[List[Comp.BaseMessageComponent]]: 获取历史消息链

自定义会话 ID 算子 ​

默认情况下,AstrBot 会话控制器会将基于 sender_id (发送人的 ID)作为识别不同会话的标识,如果想将一整个群作为一个会话,则需要自定义会话 ID 算子。

py
import astrbot.api.message_components as Comp
from astrbot.core.utils.session_waiter import (
    session_waiter,
    SessionFilter,
    SessionController,
)

# 沿用上面的 handler
# ...
class CustomFilter(SessionFilter):
    def filter(self, event: AstrMessageEvent) -> str:
        return event.get_group_id() if event.get_group_id() else event.unified_msg_origin

await empty_mention_waiter(event, session_filter=CustomFilter()) # 这里传入 session_filter
# ...

这样之后,当群内一个用户发送消息后,会话控制器会将这个群作为一个会话,群内其他用户发送的消息也会被认为是同一个会话。

甚至,可以使用这个特性来让群内组队!

发现文档有问题?在 GitHub 上编辑此页

Last updated:

Pager
上一篇文转图
下一篇杂项

Deployed on Rainyun Logo