# 组件：事件监听器

Source: https://langbot.app/docs/zh/plugin/dev/components/event-listener

> info:
>
> 本组件用于扩展流水线的处理流程。如果您需要处理机器人收到的消息、成员入群等事件，请参阅[事件处理器](https://langbot.app/docs/zh/plugin/dev/components/runner.md)。

LangBot 的流水线在运行期间会产生一些事件，供插件 Hook 并处理。每个插件中只允许添加一个事件监听器(components/event\_listener/default.yaml)，但在其中可以注册任意数量的事件。

## 添加事件监听器组件

请在插件目录执行命令`lbp comp EventListener`，创建事件监听器组件不需要填写任何配置。

```bash
➜  HelloPlugin > lbp comp EventListener
Generating component EventListener...
Component EventListener generated successfully.
组件 EventListener 生成成功。
```

现在即会在`components/event_listener/`目录下生成`default.yaml`和`default.py`文件，`.yaml`定义了事件监听器的基础信息，`.py`是该事件监听器的处理程序：

```bash
➜  HelloPlugin > tree
...
├── components
│   ├── __init__.py
│   └── event_listener
│       ├── __init__.py
│       ├── default.py
│       └── default.yaml
...
```

## 清单文件：事件监听器

由于每个插件仅允许添加一个事件监听器，故清单文件中不需要修改任何内容。

## 插件处理

默认会生成如下代码(components/event\_listener/default.py)，您需要在`DefaultEventListener`类的`initialize`方法中注册并实现事件的处理逻辑。

```python
# Auto generated by LangBot Plugin SDK.
# Please refer to https://langbot.app/docs/en/plugin/dev/tutor.html for more details.
from __future__ import annotations

from langbot_plugin.api.definition.components.common.event_listener import EventListener
from langbot_plugin.api.entities import events, context


class DefaultEventListener(EventListener):

    async def initialize(self):
        await super().initialize()

        "Fill with your code here"
```

添加对特定事件的监听：

```python
...
class DefaultEventListener(EventListener):

    async def initialize(self):
        await super().initialize()
        
        @self.handler(events.PersonMessageReceived)
        async def handler(event_context: context.EventContext):
            print("Hello LangBot Plugin!")
            print(event_context)
            
            await event_context.reply(
                platform_message.MessageChain([
                    platform_message.Plain(text=f"Hello from Nahida Plugin!"),
                ])
            )
```

此代码将注册对`PersonMessageReceived（收到来自私聊的任何消息）`事件的监听，并在事件触发时打印事件的上下文（EventContext）信息，并调用事件上下文 API 回复一条消息。

EventContext 保存了该此事件触发的通用上下文信息，而 EventContext.event 为 PersonMessageReceived （或其他对应的事件类型）的对象，保存了该事件的详细信息。

```python
# EventContext 的定义摘要
class EventContext(pydantic.BaseModel):
    """事件上下文, 保存此次事件运行的信息"""
    ...

    event: pydantic.SerializeAsAny[BaseEventModel]
    """此次事件的对象，具体类型为handler注册时指定监听的类型，可查看events.py中的定义"""
    
    ...
```

## 事件注册

事件注册通过装饰器`@self.handler`实现，装饰器参数为事件类型。可监听的事件均在`langbot_plugin.api.entities.builtin.events`中定义。

## 一个安装，多份用法

同一个事件监听器会被**多个工作区、多个事件并发调用**：

- 不要在实例上按事件累积状态（计数、最近事件、会话映射等），并发回调会互相覆盖。
- 回调只从当前 `EventContext` 取数据，不要跨调用复用上下文或其字段。
- 需要跨调用保留的数据放 Host 存储，键包含安装标识与事件相关的身份（工作区、会话等）。
- 如果按安装维护了进程内状态，请在 `on_installation_revoked(binding)` 中释放。

以上约束的完整说明见[认证插件与共享运行](https://langbot.app/docs/zh/plugin/certified-plugins.md)。

## 接下来做什么

您已经了解了事件监听器的基本信息，接下来可以：

- 在[流水线事件](https://langbot.app/docs/zh/plugin/dev/apis/pipeline-events.md)中查看可监听的事件及字段
- 查看完整的 [`EventContext` 上下文 API](https://langbot.app/docs/zh/plugin/dev/apis/agent-run.md#eventlistener)
- 查看 [LangBot API](https://langbot.app/docs/zh/plugin/dev/apis/common.md)
