# 开始使用

> For the complete documentation index, see [llms.txt](https://simbot.forte.love/llms.txt).

## 安装

Procedure: 安装依赖

1. 安装simbot核心库实现

> **Note:**
> 在安装组件库之前，确保你已经安装了可用的核心库实现，比如 [核心库](start-use-core.html) 或 [Spring Boot starter](spring-boot.html) 。

核心库:

Gradle(Kotlin DSL):

```KOTLIN
implementation("love.forte.simbot:simbot-core:5.0.0-Alpha2")
```

如果使用 Java 而不配合使用 Gradle 的 [Kotlin 插件](https://kotlinlang.org/docs/gradle-configure-project.html#apply-the-plugin), 那么你需要指定依赖的后缀为 `-jvm`。

```KOTLIN
implementation("love.forte.simbot:simbot-core-jvm:5.0.0-Alpha2")
```

Gradle(Groovy):

```GROOVY
implementation 'love.forte.simbot:simbot-core:5.0.0-Alpha2'
```

如果使用 Java 而不配合使用 Gradle 的 [Kotlin 插件](https://kotlinlang.org/docs/gradle-configure-project.html#apply-the-plugin), 那么你需要指定依赖的后缀为 `-jvm`。

```GROOVY
implementation 'love.forte.simbot:simbot-core-jvm:5.0.0-Alpha2'
```

Maven:

```XML
<dependency>
    <groupId>love.forte.simbot</groupId>
    <artifactId>simbot-core-jvm</artifactId>
    <version>5.0.0-Alpha2</version>
</dependency>
```

> **Tip:**
> 前往 [核心库](start-use-core.html) 了解更多内容。

Spring Boot starter:

Spring Boot 3:

Gradle(Kotlin DSL):

```KOTLIN
implementation("love.forte.simbot:simbot-core-spring-boot-starter:5.0.0-Alpha2")
```

Gradle(Groovy):

```GROOVY
implementation 'love.forte.simbot:simbot-core-spring-boot-starter:5.0.0-Alpha2'
```

Maven:

```XML
<dependency>
    <groupId>love.forte.simbot</groupId>
    <artifactId>simbot-core-spring-boot-starter</artifactId>
    <version>5.0.0-Alpha2</version>
</dependency>
```

> **Tip:**
> 前往 [使用 Spring Boot 3](start-use-spring-boot-3.html) 或 [集成Spring Boot](spring-boot.html) 了解更多内容。

Spring Boot 2:

Gradle(Kotlin DSL):

```KOTLIN
implementation("love.forte.simbot:simbot-core-spring-boot-starter-v2:5.0.0-Alpha2")
```

Gradle(Groovy):

```GROOVY
implementation 'love.forte.simbot:simbot-core-spring-boot-starter-v2:5.0.0-Alpha2'
```

Maven:

```XML
<dependency>
    <groupId>love.forte.simbot</groupId>
    <artifactId>simbot-core-spring-boot-starter-v2</artifactId>
    <version>5.0.0-Alpha2</version>
</dependency>
```

> **Tip:**
> 前往 [使用 Spring Boot 2](start-use-spring-boot-2.html) 了解更多内容。

2. 安装组件库

`simbot-component-qq-core` 即为QQ机器人组件的核心库， 也就是作为simbot组件所使用的 组件库 。

Gradle(Kotlin DSL):

```KOTLIN
implementation("love.forte.simbot.component:simbot-component-qq-core:5.0.0-Alpha2")
```

如果使用 Java 而不配合使用 Gradle 的 `kotlin` 插件, 那么你需要指定依赖的后缀为 `-jvm`。

```KOTLIN
implementation("love.forte.simbot.component:simbot-component-qq-core-jvm:5.0.0-Alpha2")
```

Gradle(Groovy):

```GROOVY
implementation 'love.forte.simbot.component:simbot-component-qq-core:5.0.0-Alpha2'
```

如果使用 Java 而不配合使用 Gradle 的 `kotlin` 插件, 那么你需要指定依赖的后缀为 `-jvm`。

```GROOVY
implementation 'love.forte.simbot.component:simbot-component-qq-core-jvm:5.0.0-Alpha2'
```

Maven:

```XML
<dependency>
    <groupId>love.forte.simbot.component</groupId>
    <artifactId>simbot-component-qq-core-jvm</artifactId>
    <version>5.0.0-Alpha2</version>
</dependency>
```

3. 安装Ktor客户端引擎

QQ机器人组件使用 [Ktor](https://ktor.io) 作为 HTTP 客户端实现， 但是默认不会依赖任何具体的引擎。

因此，你需要选择并使用一个 Ktor Client 引擎实现。

> **Warning:**
> 如果你使用 `websocket` 订阅事件，需要选择一个支持 WebSocket 的引擎。 如果你只做 `webhook` 回调并自行处理服务端接入，则只需要满足 HTTP 客户端侧的依赖要求。

你可以前往 [Ktor文档](https://ktor.io/docs/http-client-engines.html) 处选择一个对应所用平台下合适的 `Client Engine`。 这里会根据不同平台提供几个示例，你可以选择其他可用目标。

> **Tip:**
> 注意应选择使用 `v2.x` 版本的 Ktor。5.0 后的版本会更新到 Ktor 3。

JVM:

Java:

在 Java11+ 的环境下，可以选择 [Java](https://ktor.io/docs/http-client-engines.html#java) 引擎。

Gradle Kotlin DSL:

```KOTLIN
runtimeOnly("io.ktor:ktor-client-java:$ktor_version")
```

如果不使用Kotlin的[Gradle插件](https://kotlinlang.org/docs/gradle-configure-project.html):

```KOTLIN
runtimeOnly("io.ktor:ktor-client-java-jvm:$ktor_version")
```

Gradle Groovy:

```GROOVY
runtimeOnly 'io.ktor:ktor-client-java:$ktor_version'
```

如果不使用Kotlin的[Gradle插件](https://kotlinlang.org/docs/gradle-configure-project.html):

```GROOVY
runtimeOnly 'io.ktor:ktor-client-java-jvm:$ktor_version'
```

Maven:

```XML
<dependency>
    <groupId>io.ktor</groupId>
    <artifactId>ktor-client-java-jvm</artifactId>
    <version>${ktor_version}</version>
    <scope>runtime</scope>
</dependency>
```

OkHttp:

[OkHttp](https://ktor.io/docs/client-engines.html#okhttp) 引擎基于 OkHttp，是一个不错的库。

Gradle Kotlin DSL:

```KOTLIN
runtimeOnly("io.ktor:ktor-client-okhttp:$ktor_version")
```

如果不使用Kotlin的[Gradle插件](https://kotlinlang.org/docs/gradle-configure-project.html):

```KOTLIN
runtimeOnly("io.ktor:ktor-client-okhttp-jvm:$ktor_version")
```

Gradle Groovy:

```GROOVY
runtimeOnly 'io.ktor:ktor-client-okhttp:$ktor_version'
```

如果不使用Kotlin的[Gradle插件](https://kotlinlang.org/docs/gradle-configure-project.html):

```GROOVY
runtimeOnly 'io.ktor:ktor-client-okhttp-jvm:$ktor_version'
```

Maven:

```XML
<dependency>
    <groupId>io.ktor</groupId>
    <artifactId>ktor-client-okhttp-jvm</artifactId>
    <version>${ktor_version}</version>
    <scope>runtime</scope>
</dependency>
```

CIO:

[CIO](https://ktor.io/docs/http-client-engines.html#cio) 是一个比较通用的引擎。 在不知道选什么的情况下，可以考虑使用它。

Gradle Kotlin DSL:

```KOTLIN
runtimeOnly("io.ktor:ktor-client-cio:$ktor_version")
```

如果不使用Kotlin的[Gradle插件](https://kotlinlang.org/docs/gradle-configure-project.html):

```KOTLIN
runtimeOnly("io.ktor:ktor-client-cio-jvm:$ktor_version")
```

Gradle Groovy:

```GROOVY
runtimeOnly 'io.ktor:ktor-client-cio:$ktor_version'
```

如果不使用Kotlin的[Gradle插件](https://kotlinlang.org/docs/gradle-configure-project.html):

```GROOVY
runtimeOnly 'io.ktor:ktor-client-cio-jvm:$ktor_version'
```

Maven:

```XML
<dependency>
    <groupId>io.ktor</groupId>
    <artifactId>ktor-client-cio-jvm</artifactId>
    <version>${ktor_version}</version>
    <scope>runtime</scope>
</dependency>
```

> **Tip:**
> 引擎大部分情况下可以 runtime only，除非你需要显式地定制化它。

JavaScript:

JavaScript 平台下可以选择 [Js](https://ktor.io/docs/http-client-engines.html#js) 引擎。

Gradle Kotlin DSL:

```KOTLIN
implementation("io.ktor:ktor-client-js:$ktor_version")
```

Gradle Groovy:

```GROOVY
implementation 'io.ktor:ktor-client-js:$ktor_version'
```

Native:

native 平台目标下，可能需要根据不同的平台类型选择不同的引擎。

Mingw:

可以选择 [WinHttp](https://ktor.io/docs/http-client-engines.html#winhttp) 引擎。

Gradle Kotlin DSL:

```KOTLIN
implementation("io.ktor:ktor-client-winhttp:$ktor_version")
```

Gradle Groovy:

```GROOVY
implementation 'io.ktor:ktor-client-winhttp:$ktor_version'
```

Linux:

Linux 下依旧可以选择 [CIO](https://ktor.io/docs/http-client-engines.html#cio) 引擎。

Gradle Kotlin DSL:

```KOTLIN
implementation("io.ktor:ktor-client-cio:$ktor_version")
```

Gradle Groovy:

```GROOVY
implementation 'io.ktor:ktor-client-cio:$ktor_version'
```

MacOS:

可以选择 [Darwin](https://ktor.io/docs/http-client-engines.html#darwin) 引擎。

Gradle Kotlin DSL:

```KOTLIN
implementation("io.ktor:ktor-client-darwin:$ktor_version")
```

Gradle Groovy:

```GROOVY
implementation 'io.ktor:ktor-client-darwin:$ktor_version'
```

> **Tip:**
> 参考 [安装](component-qq-guild.html#安装) 。

## 使用

### API 服务地址

QQ 开放平台自 `2026-08-10` 起将接口调用域名统一为 `https://api.bot.qq.com`，不再提供独立的沙箱接口域名。 组件默认使用此统一地址，无需额外配置。

旧的 `useSandboxServerUrl()` 和配置值 `"SANDBOX"` 仅为兼容已有项目而保留， 现已弃用，不应在新配置中继续使用。需要使用代理等自定义地址时， 可通过 `serverUrl` 显式配置。有关配置文件的完整说明，参考 [Bot配置文件](component-qq-guild-bot-config.html) 。

### 事件监听配置

如果你不使用 [webhook](component-qq-guild-webhook.html) 订阅事件， 那么你 可能 需要配置事件订阅的 `intents`，因为 `intents` 的默认值只有三个类型的事件。

代码配置:

Kotlin:

```KOTLIN
botManager.register("..", "..", "..") {
    botConfig {
        // 配置Intents，例如追加群聊事件支持
        intents += EventIntents.GroupAndC2CEvent.intents
    }
}
```

Java:

```JAVA
QQGuildBotManager manager = ...;
botManager.register("..", "..", "..", qgBotConfig -> {
    qgBotConfig.botConfig(botConfig -> {
        botConfig.addIntents(EventIntents.GroupAndC2CEvent.getIntents());
    });
});
```

配置文件(在Spring中):

示例中的 `intents` 的数值为在默认值的基础上添加了 `group_and_c2c_event` 类型事件的位值的最终数值。

```JSON
{
  "component": "simbot.qqguild",
  "ticket": {
    "appId": "...",
    "secret": "...",
    "token": "..."
  },
  "config": {
    "intents": {
      "type": "raw",
      "intents": 1107296259
    }
  }
}
```

> **Tip:**
> 有关配置文件更多内容和属性说明，参考 [Bot配置文件](component-qq-guild-bot-config.html) 。

### 创建Application

核心库:

在 `simbot-core` 中，提供了一个基础的 `Application` 实现类型：`SimpleApplication`。

Kotlin:

```KOTLIN
val app = launchSimpleApplication {
    // 使用QQ机器人组件相关的内容。
    // 代表同时安装 `QQGuildComponent` 和 `QQGuildBotManager`
    useQQGuild()
    // 其他配置...
}

app.join() // 挂起app直到cancel它
```

Java:

```JAVA
final var applicationAsync = Applications.launchApplicationAsync(
    Simple.INSTANCE,
    configurer -> {
        // 安装 `QQGuildComponent` 和 `QQGuildBotManager`
        configurer.install(QQGuildComponent.Factory);
        configurer.install(QQGuildBotManager.Factory);
        // 其他...
    }
);

applicationAsync
        .asFuture()
        // Application 转化为 Future
        .thenCompose(Application::asFuture)
        // 阻塞这个Future直到Application被cancel
        .join();
```

```JAVA
final var application = Applications.launchApplicationBlocking(
    Simple.INSTANCE,
    configurer -> {
        // 安装 `QQGuildComponent` 和 `QQGuildBotManager`
        configurer.install(QQGuildComponent.Factory);
        configurer.install(QQGuildBotManager.Factory);
        // 其他...
    }
);

// 阻塞直到被cancel
application.joinBlocking();
```

```JAVA
var applicationAsync = Applications.launchApplicationAsync(
        Simple.INSTANCE,
        configurer -> {
            // 安装 `QQGuildComponent` 和 `QQGuildBotManager`
            configurer.install(QQGuildComponent.Factory);
            configurer.install(QQGuildBotManager.Factory);
            // 其他...
        }
);

// 例如：转化为 reactor.core.publisher.Mono;
var mono = Mono.fromFuture(applicationAsync.asFuture())
        .flatMap(app ->
                app.joinReserve().transform(
                        SuspendReserves.mono()
                )
        );

// 使用这个响应式类型，例如阻塞它。
/// 阻塞直到被cancel
mono.block();
```

Spring:

在 Spring Boot 中，不需要你手动构建 `Application`。 你只需要在你的启动类上标记 `@EnableSimbot` 来启用 simbot 即可。

QQ机器人组件支持SPI自动加载，因此默认情况下不需要手动安装 `QQGuildComponent` 和 `QQGuildBotManager` 。

Kotlin:

```KOTLIN
@EnableSimbot
@SpringBootApplication
open class BotApplication

fun main(vararg args: String) {
    runApplication<BotApplication>(*args)
}
```

Java:

```JAVA
@EnableSimbot
@SpringBootApplication
public class BotApplication {
    public static void main(String[] args) {
        SpringApplication.run(BotApplication.class, args);
    }
}
```

### 注册Bot

核心库:

在 Application 构建完成后，即可从 `Application.botManagers` 中寻找你所需的管理器（比如组件的Bot管理器：`QQGuildBotManager`） 并注册你的Bot。

Kotlin:

```KOTLIN
suspend fun main() {
    val app = launchSimpleApplication {
        useQQGuild()
        // ...
    }

    app.configure()
    app.join()
}

suspend fun Application.configure() {
    // 寻找、获得所需的BotManager
    val botManager = botManagers.firstQQGuildBotManager()
    // 注册你所需的bot
    val bot = botManager.register(
        appId = "...",
        secret = "...",
        token = "...",
    ) {
        // 一些其他的可选配置属性
        // 大部分属性都在 botConfigure 内配置
        botConfigure = ConfigurerFunction {
            // 比如添加订阅QQ群聊和C2C的事件。
            // 如果不配置，默认情况下仅订阅：
            // - 频道相关事件
            // - 频道成员相关事件
            // - 公域消息相关事件
            intents += EventIntents.GroupAndC2CEvent.intents
            // 如果要使用 [[[Webhook|component-qq-guild-webhook.html]]] 的订阅方式，
            // 通过此属性取消 ws 的连接
            disableWs = true
            // 其他...
        }
        // 外层是独属于组件类型的某些配置
        cacheConfig = null
        // 其他...
    }
    
    // 启动你的bot
    bot.start()
}
```

Java:

```JAVA
public static void main(String[] args) {
    final var applicationAsync = Applications.launchApplicationAsync(
        Simple.INSTANCE,
        configurer -> {
            // 安装QQGuild组件相关内容
            configurer.install(QQGuildComponent.Factory);
            configurer.install(QQGuildBotManager.Factory);
            // 其他...
        }
    );

    applicationAsync
        .asFuture()
        // Application 转化为 Future
        .thenApply(app -> {
            // 配置
            configure(app);
            return app;
        })
        .thenCompose(Application::asFuture)
        // 阻塞这个Future直到Application被cancel
        .join();
}

public static void configure(Application application) {
    // 寻找所需的BotManager
    // 可以选择遍历寻找
    final var found = application.getBotManagers().stream()
            .filter(it -> it instanceof QQGuildBotManager)
            .map(it -> (QQGuildBotManager) it)
            .findFirst()
            .orElseThrow();

    // 也可以选择使用辅助API
    final var qqGuildBotManager = QQGuildBotManagerUsageKt
            .firstQQGuildBotManager(application.getBotManagers());

    // 注册Bot
    // 注册
    final var bot = qqGuildBotManager.register(
            "appid",
            "secret",
            "token",
            config -> {
                // 一些其他的可选配置属性
                // 大部分属性都在 botConfigure 内配置
                config.botConfig(botConfig -> {
                    // 比如添加订阅QQ群聊和C2C的事件。
                    // 如果不配置，默认情况下仅订阅：
                    // - 频道相关事件
                    // - 频道成员相关事件
                    // - 公域消息相关事件
                    botConfig.setIntentsValue(
                            // 位运算合并 QQ群聊和C2C事件 的intents值
                            botConfig.getIntentsValue() | EventIntents.GroupAndC2CEvent.INSTANCE.getIntentsValue()
                    );
                    
                    // 如果要使用 [[[Webhook|component-qq-guild-webhook.html]]] 的订阅方式，
                    // 通过此属性取消 ws 的连接
                    botConfig.setDisableWs(true);
                });

                // 外层是独属于组件类型的某些配置
                config.setCacheConfig(null);
                // 其他...
            });
    // 启动
    final var future = bot.startAsync().whenComplete((r, ex) -> {
        // 在使用 Future 的时候，记得处理异常
        if (ex != null) {
            Logger.getGlobal().log(
                    Level.SEVERE,
                    "bot启动出现异常！",
                    ex
            );
        }
    });
    // 你可以选择处理等待这个future，也可以选择不管他，直接在异步中处理。
}
```

```JAVA
public static void main(String[] args) {
    final var application = Applications.launchApplicationBlocking(
            Simple.INSTANCE,
            configurer -> {
                // 安装QQGuild组件相关内容
                configurer.install(QQGuildComponent.Factory);
                configurer.install(QQGuildBotManager.Factory);
                // 其他...
            }
    );

    configure(application);
    application.joinBlocking();
}

public static void configure(Application application) {
    // 寻找所需的BotManager
    // 可以选择遍历寻找
    final var found = application.getBotManagers().stream()
            .filter(it -> it instanceof QQGuildBotManager)
            .map(it -> (QQGuildBotManager) it)
            .findFirst()
            .orElseThrow();

    // 也可以选择使用辅助API
    final var qqGuildBotManager = QQGuildBotManagerUsageKt
            .firstQQGuildBotManager(application.getBotManagers());

    // 注册Bot
    // 注册
    final var bot = qqGuildBotManager.register(
            "appid",
            "secret",
            "token",
            config -> {
                // 一些其他的可选配置属性
                // 大部分属性都在 botConfigure 内配置
                config.botConfig(botConfig -> {
                    // 比如添加订阅QQ群聊和C2C的事件。
                    // 如果不配置，默认情况下仅订阅：
                    // - 频道相关事件
                    // - 频道成员相关事件
                    // - 公域消息相关事件
                    botConfig.setIntentsValue(
                            // 位运算合并 QQ群聊和C2C事件 的intents值
                            botConfig.getIntentsValue() | EventIntents.GroupAndC2CEvent.INSTANCE.getIntentsValue()
                    );
                });

                // 外层是独属于组件类型的某些配置
                config.setCacheConfig(null);
                // 其他...
            });
    // 启动
    bot.startBlocking();
}
```

```JAVA
public static void main(String[] args) {
    var applicationAsync = Applications.launchApplicationAsync(
        Simple.INSTANCE,
        configurer -> {
            // 安装QQ机器人组件相关内容
            configurer.install(QQGuildComponent.Factory);
            configurer.install(QQGuildBotManager.Factory);
            // 其他...
        }
    );

    // 例如：转化为 reactor.core.publisher.Mono;
    var mono = Mono.fromFuture(applicationAsync.asFuture())
        // 配置 Application
        .doOnNext(CoreMain::configure)
        .flatMap(app ->
            app.joinReserve().transform(
                SuspendReserves.mono()
            )
        );

    // 使用这个响应式类型，例如阻塞它。
    /// 阻塞直到被cancel
    mono.block();
}

public static void configure(Application application) {
    // 寻找所需的BotManager
    // 可以选择遍历寻找
    final var found = application.getBotManagers().stream()
            .filter(it -> it instanceof QQGuildBotManager)
            .map(it -> (QQGuildBotManager) it)
            .findFirst()
            .orElseThrow();

    // 也可以选择使用辅助API
    final var qqGuildBotManager = QQGuildBotManagerUsageKt
            .firstQQGuildBotManager(application.getBotManagers());

    // 注册Bot
    // 注册
    final var bot = qqGuildBotManager.register(
            "appid",
            "secret",
            "token",
            config -> {
                // 一些其他的可选配置属性
                // 大部分属性都在 botConfigure 内配置
                config.botConfig(botConfig -> {
                    // 比如添加订阅QQ群聊和C2C的事件。
                    // 如果不配置，默认情况下仅订阅：
                    // - 频道相关事件
                    // - 频道成员相关事件
                    // - 公域消息相关事件
                    botConfig.setIntentsValue(
                            // 位运算合并 QQ群聊和C2C事件 的intents值
                            botConfig.getIntentsValue() | EventIntents.GroupAndC2CEvent.INSTANCE.getIntentsValue()
                    );
                });

                // 外层是独属于组件类型的某些配置
                config.setCacheConfig(null);
                // 其他...
            });
    // 启动
    bot.startReserve()
            .transform(SuspendReserves.mono())
            // 在使用响应式编程的时候，记得处理异常
            .doOnError(ex -> {
                Logger.getGlobal().log(
                        Level.SEVERE,
                        "bot启动出现异常！",
                        ex
                );
            })
            // 你也可以选择返回Mono然后做进一步处理
            // 此处直接使其在异步中运行。
            .subscribe();
}
```

Spring:

在 Spring 中，通常可以选择使用 `.bot.json` 格式的配置文件来快速、自动地批量注册bot。

默认情况下，在你的项目的资源目录 `resource` 中创建目录 `/simbot-bots/` ， 然后前往参考  [Bot配置文件](component-qq-guild-bot-config.html)  并配置你的 JSON 格式的配置文件，例如 `abc.bot.json`。

默认情况下starter会自动扫描上述资源目录并加载、自动启动它们，这一切是在异步中进行的。

> **Tip:**
> 上述的 资源目录 `/simbot-bots/` 、自动启动、以及 在异步中启动 这些都是可配置的。
>
>
>
> 有关Spring Boot环境下可用的配置信息，可前往 [集成Spring Boot](spring-boot.html) 参考更多。

### Webhook

使用 Webhook 接收事件参考 [Webhook](component-qq-guild-webhook.html) 。

### 事件监听

核心库:

从 `Application` 中获取 `EventDispatcher` 即可注册事件监听函数。

Kotlin:

Kotlin 中，可以使用 `Application.listeners {}` 扩展函数。

```KOTLIN
// 省略构建Application相关内容...

suspend fun Application.configure() {
    // bot相关内容省略....

    // Kotlin 中，可以使用 Application.listeners 扩展函数。
    listeners {
        // 使用 listen 监听一个事件
        // 此处是一个标准库中通用的类型：聊天群消息事件
        listen<ChatGroupMessageEvent> { event ->
            println("Event: $event")
            if (event.messageContent.plainText?.trim() == "你好") {
                event.reply("你也好")
            }

            // 使用listen时必须返回一个EventResult类型的结果
            EventResult.empty()
        }

        // 使用 process 监听一个事件
        // 此处监听的是QQ机器人组件中的专属类型：文字子频道中的At消息事件
        process<QGAtMessageCreateEvent> { event ->
            println("Event: $event")
            if (event.messageContent.plainText.trim() == "你好") {
                event.reply("你也好")
            }

            // 使用 process 不需要返回 EventResult，默认视为返回 EventResult.empty()
        }
    }
}
```

Java:

```JAVA
// 省略构建Application相关内容...

public static void configure(Application application) {
    // bot相关内容省略....

    final var eventDispatcher = application.getEventDispatcher();

    // 监听一个QQ机器人组件中的专属类型：QQ频道中文字子频道的At消息事件
    eventDispatcher.register(
            EventListeners.async(
                    QGAtMessageCreateEvent.class,
                    (context, event) -> {
                        System.out.println("Event: " + event);
                        if ("你好".equals(event.getMessageContent().getPlainText())) {
                            // 返回一个异步的EventResult类型的结果
                            return event.replyAsync("你也好")
                                    .thenApply(result -> EventResult.empty());
                        }

                        // 返回一个异步的EventResult类型的结果
                        return CompletableFuture.completedFuture(EventResult.empty());
                    }
            )
    );
}
```

> **Tip:**
> 也可以使用 `EventListeners.nonBlock` 后返回一个内容为 `Future` 的 `CompletableFuture`:
>
>
>
>
> ```JAVA
> var future = ...
> return EventResult.of(future);
> ```
>
>
>
> 此方式与响应式风格的API方式类似。

```JAVA
// 省略构建Application相关内容...

public static void configure(Application application) {
    // bot相关内容省略....
    
    final var eventDispatcher = application.getEventDispatcher();

    // 监听一个QQ机器人组件中的专属类型：QQ频道中文字子频道的At消息事件
    eventDispatcher.register(
        EventListeners.block(
            QGAtMessageCreateEvent.class,
            (context, event) -> {
                System.out.println("Event: " + event);
                if ("你好".equals(event.getMessageContent().getPlainText())) {
                    event.replyBlocking("你也好");
                }

                // 返回一个EventResult类型的结果
                return EventResult.empty();
            }
        )
    );
}
```

```JAVA
// 省略构建Application相关内容...

public static void configure(Application application) {
    // bot相关内容省略....

    final var eventDispatcher = application.getEventDispatcher();

    // 监听一个QQ机器人组件中的专属类型：QQ频道中文字子频道的At消息事件
    eventDispatcher.register(
            EventListeners.nonBlock(
                    QGAtMessageCreateEvent.class,
                    (context, event) -> {
                        System.out.println("Event: " + event);
                        if ("你好".equals(event.getMessageContent().getPlainText())) {
                            // 返回一个内容是响应式类型的EventResult类型的结果
                            final var mono = event.replyReserve("你也好")
                                    .transform(SuspendReserves.mono())
                                    .then();

                            return EventResult.of(mono);
                        }

                        // 返回一个空的EventResult类型的结果
                        return EventResult.empty();
                    }
            )
    );
}
```

> **Tip:**
> `EventResult.of(...)` 的内容可以是异步的或响应式的， 事件处理器会对这种结果进行一次收集或挂起。

> **Note:**
> 更多有关 `EventResult` 的信息可参考 [EventResult](basic-event-listener.html#EventResult)

Spring:

在 Spring 中，使用注解 `@Listener` 注册一个监听函数。 可监听到的事件即为参数中的事件类型。 也因此，参数中的事件类型的参数应当最多只有1个。

> **Tip:**
> `@Listener` 需要在被Spring管理的bean中使用，例如需要在类上标记 `@Component`。

Kotlin:

```KOTLIN
@Component
class MyHandles {
    /**
     * 此处是一个标准库中通用的类型：聊天群消息事件
     * 在QQ机器人组件中，它的真实实现类型会是QGGroupAtMessageCreateEvent
     */
    @Listener
    suspend fun onGroupMessage(event: ChatGroupMessageEvent) {
        println("ChatGroupMessageEvent: $event")
    }
    
    /**
     * 此处监听的是QQ机器人组件中的专属类型：QQ频道中文字子频道的At消息。
     * 并且过滤消息：消息中的文本消息去除前后空字符后，等于 '你好'
     */
    @Listener
    @ContentTrim
    @Filter("你好")
    suspend fun onMessage(event: QGAtMessageCreateEvent) {
        println("QGAtMessageCreateEvent: $event")
        // 回复消息
        event.reply("你也好")
    }
}


```

Java:

```JAVA
@Component
public class MyHandles {
    /**
     * 此处是一个标准库中通用的类型：聊天群消息事件
     * 在QQ机器人组件中，它的真实实现类型会是QGGroupAtMessageCreateEvent
     */
    @Listener
    public void onGroupMessage(ChatGroupMessageEvent event) {
        System.out.println("ChatGroupMessageEvent: " + event);
    }

    /**
     * 此处监听的是QQ机器人组件中的专属类型：QQ频道中文字子频道的At消息。
     * 并且过滤消息：消息中的文本消息去除前后空字符后，等于 '你好'
     */
    @Listener
    @ContentTrim
    @Filter("你好")
    public CompletableFuture<?> onMessage(QGAtMessageCreateEvent event) {
        System.out.println("QGAtMessageCreateEvent: " + event);
        return event.replyAsync("你也好");
        // 可以直接返回任意 Future 类型，
        // 或者返回 EventResult，其中包裹着 Future 类型。
    }
}
```

```JAVA
@Component
public class MyHandles {
    /**
     * 此处是一个标准库中通用的类型：聊天群消息事件
     * 在QQ机器人组件中，它的真实实现类型会是QGGroupAtMessageCreateEvent
     */
    @Listener
    public void onGroupMessage(ChatGroupMessageEvent event) {
        System.out.println("ChatGroupMessageEvent: " + event);
    }

    /**
     * 此处监听的是QQ机器人组件中的专属类型：QQ频道中文字子频道的At消息。
     * 并且过滤消息：消息中的文本消息去除前后空字符后，等于 '你好'
     */
    @Listener
    @ContentTrim
    @Filter("你好")
    public void onMessage(QGAtMessageCreateEvent event) {
        System.out.println("QGAtMessageCreateEvent: " + event);
        event.replyBlocking("你也好");
    }
}
```

```JAVA
@Component
public class MyHandles {
    /**
     * 此处是一个标准库中通用的类型：聊天群消息事件
     * 在QQ机器人组件中，它的真实实现类型会是QGGroupAtMessageCreateEvent
     */
    @Listener
    public void onGroupMessage(ChatGroupMessageEvent event) {
        System.out.println("ChatGroupMessageEvent: " + event);
    }

    /**
     * 此处监听的是QQ机器人组件中的专属类型：QQ频道中文字子频道的At消息。
     * 并且过滤消息：消息中的文本消息去除前后空字符后，等于 '你好'
     */
    @Listener
    @ContentTrim
    @Filter("你好")
    public Mono<?> onMessage(QGAtMessageCreateEvent event) {
        System.out.println("QGAtMessageCreateEvent: " + event);
        return event.replyReserve("你也好")
            .transform(SuspendReserves.mono());
        // 可以直接返回任意(kotlinx.coroutines支持的)响应式类型，
        // 不过需要注意，确保运行时环境中有对应的依赖，
        // 以Mono为例，需要添加 [[[kotlinx-coroutines-reactor|https://github.com/Kotlin/kotlinx.coroutines/tree/master/reactive]]]
        // 也可以返回 EventResult，其中包裹着响应式类型。
    }
}
```

