Simple Robot v4.6.0 Help

开始使用

安装

安装依赖

  1. 安装simbot核心库实现

    implementation("love.forte.simbot:simbot-core:4.6.0")

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

    implementation("love.forte.simbot:simbot-core-jvm:4.6.0")
    implementation 'love.forte.simbot:simbot-core:4.6.0'

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

    implementation 'love.forte.simbot:simbot-core-jvm:4.6.0'
    <dependency> <groupId>love.forte.simbot</groupId> <artifactId>simbot-core-jvm</artifactId> <version>4.6.0</version> </dependency>
    implementation("love.forte.simbot:simbot-core-spring-boot-starter:4.6.0")
    implementation 'love.forte.simbot:simbot-core-spring-boot-starter:4.6.0'
    <dependency> <groupId>love.forte.simbot</groupId> <artifactId>simbot-core-spring-boot-starter</artifactId> <version>4.6.0</version> </dependency>
  2. 安装组件库

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

    implementation("love.forte.simbot.component:simbot-component-qq-guild-core:4.0.1")

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

    implementation("love.forte.simbot.component:simbot-component-qq-guild-core-jvm:4.0.1")
    implementation 'love.forte.simbot.component:simbot-component-qq-guild-core:4.0.1'

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

    implementation 'love.forte.simbot.component:simbot-component-qq-guild-core-jvm:4.0.1'
    <dependency> <groupId>love.forte.simbot.component</groupId> <artifactId>simbot-component-qq-guild-core-jvm</artifactId> <version>4.0.1</version> </dependency>
  3. 安装Ktor客户端引擎

    QQ机器人组件使用 Ktor 作为 HTTP 客户端实现, 但是默认不会依赖任何具体的引擎

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

    你可以前往 Ktor文档 处选择一个对应所用平台下合适的 Client Engine。 这里会根据不同平台提供几个示例,你可以选择其他可用目标。

    在 Java11+ 的环境下,可以选择 Java 引擎。

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

    如果不使用Kotlin的Gradle插件:

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

    如果不使用Kotlin的Gradle插件:

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

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

    OkHttp 引擎基于 OkHttp,是一个不错的库。

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

    如果不使用Kotlin的Gradle插件:

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

    如果不使用Kotlin的Gradle插件:

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

    CIO 是一个比较通用的引擎。 在不知道选什么的情况下,可以考虑使用它。

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

    如果不使用Kotlin的Gradle插件:

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

    如果不使用Kotlin的Gradle插件:

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

    JavaScript 平台下可以选择 Js 引擎。

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

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


    可以选择 WinHttp 引擎。

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

    Linux 下依旧可以选择 CIO 引擎。

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

    可以选择 Darwin 引擎。

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

使用

创建Application

simbot-core 中,提供了一个基础的 Application 实现类型: SimpleApplication

val app = launchSimpleApplication { // 使用QQ机器人组件相关的内容。 // 代表同时安装 `QQGuildComponent` 和 `QQGuildBotManager` useQQGuild() // 其他配置... } app.join() // 挂起app直到cancel它
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();
final var application = Applications.launchApplicationBlocking( Simple.INSTANCE, configurer -> { // 安装 `QQGuildComponent` 和 `QQGuildBotManager` configurer.install(QQGuildComponent.Factory); configurer.install(QQGuildBotManager.Factory); // 其他... } ); // 阻塞直到被cancel application.joinBlocking();
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 Boot 中,不需要你手动构建 Application。 你只需要在你的启动类上标记 @EnableSimbot 来启用 simbot 即可。

QQ机器人组件支持SPI自动加载,因此默认情况下不需要手动安装 QQGuildComponentQQGuildBotManager

@EnableSimbot @SpringBootApplication open class BotApplication fun main(vararg args: String) { runApplication<BotApplication>(*args) }
@EnableSimbot @SpringBootApplication public class BotApplication { public static void main(String[] args) { SpringApplication.run(BotApplication.class, args); } }

注册Bot

在 Application 构建完成后,即可从 Application.botManagers 中寻找你所需的管理器(比如组件的Bot管理器: QQGuildBotManager) 并注册你的Bot。

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 // 比如切换服务地址为沙箱频道的服务地址 useSandboxServerUrl() // 其他... } // 外层是独属于组件类型的某些配置 cacheConfig = null // 其他... } // 启动你的bot bot.start() }
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() ); }); // 外层是独属于组件类型的某些配置 config.setCacheConfig(null); // 其他... }); // 启动 final var future = bot.startAsync().whenComplete((r, ex) -> { // 在使用 Future 的时候,记得处理异常 if (ex != null) { Logger.getGlobal().log( Level.SEVERE, "bot启动出现异常!", ex ); } }); // 你可以选择处理等待这个future,也可以选择不管他,直接在异步中处理。 }
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(); }
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 中,通常可以选择使用 .bot.json 格式的配置文件来快速、自动地批量注册bot。

默认情况下,在你的项目的资源目录 resource 中创建目录 /simbot-bots/, 然后前往参考 Bot配置文件 并配置你的 JSON 格式的配置文件,例如 abc.bot.json

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

事件监听

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

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

// 省略构建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() } } }
// 省略构建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()); } ) ); }
// 省略构建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(); } ) ); }
// 省略构建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(); } ) ); }

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

@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("你也好") } }
@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 类型。 } }
@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("你也好"); } }
@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,其中包裹着响应式类型。 } }
Last modified: 12 September 2024