Skip to content

编写WeChatBc插件

zsh edited this page Feb 27, 2024 · 14 revisions

并不建议您直接将wechatbc嵌入你的项目,而是建议以docker容器运行,并通过编写插件的方式来扩展您自己的逻辑。

快速开始,第一个WeChatBc插件

写过bukkit插件的朋友应该会很容易上手这套流程,我们的目的是开发一个插件

当接收到消息 "今夕是何年" 的时候回复 "当前的年份"

首先,新建一个java项目,选择maven作为构建工具

image

注意,为了避免不必要的错误,jdk请选择 java8

引入wechatbc作为依赖

打开pom.xml,导入依赖

    <repositories>
        <repository>
            <id>jitpack.io</id>
            <url>https://jitpack.io</url>
        </repository>
    </repositories>
    <dependencies>
        <dependency>
            <groupId>com.github.meteorOSS</groupId>
            <artifactId>wechat-bc</artifactId>
            <version>[版本号]</version>
        </dependency>
    </dependencies>

具体的版本号请查阅 https://jitpack.io/#meteorOSS/wechat-bc

此时你的pom.xml可能长这样

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.meteor</groupId>
    <artifactId>TestPlugin</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <repositories>
        <repository>
            <id>jitpack.io</id>
            <url>https://jitpack.io</url>
        </repository>
    </repositories>
    <dependencies>
        <dependency>
            <groupId>com.github.meteorOSS</groupId>
            <artifactId>wechat-bc</artifactId>
            <version>v1.1.3</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

</project>

点击右上角的小图标,刷新一下

image

插件主类

新增一个类 PluginMain (其实叫什么都好啦) ,这是插件的入口类

public class PluginMain extends BasePlugin {
    @Override
    public void onLoad() {
    }

    // 插件启动时
    @Override
    public void onEnable() {
        getLogger().info("插件载入啦");
    }

    // 插件卸载时
    @Override
    public void onDisable() {
        getLogger().info("插件卸载啦");
    }
}

作为插件的主类,必须继承自BasePlugin,这样才会被WeChatBc所识别,getLogger()会取得插件的日志对象,打印一行输出

接下来是最重要的一步,我们必须要让WeChatBc知道它是一个插件,怎么做呢?

声明插件

wechatbc通过插件资源文件下的 plugin.yml 来识别,在 resources 下新建一个 plugin.yml

# 插件名
name: 'TestPlugin'
# 主类
main: com.meteor.testplugin.PluginMain
# 版本号
version: 1.0
# 作者列表
authors:
  - 'meteor'
# 描述
description: '这是一个示例插件,展示了怎么编写wechatbc插件'

这里最关键的是 main ,它告诉wechatbc插件的入口类是哪里,这里必须是完整的路径

示例中的 main: com.meteor.testplugin.PluginMain 指向下图

image

实现功能

还记得我们要干什么吗?想要让bot根据特定的消息回复内容,我们只需要监听 ReceiveMessageEvent 事件就好了

监听器,事件

wechatbc将 接收消息 拍一拍 等封装成了一系列事件,ReceiveMessageEvent 为接收消息时传唤

新增一个类 ReceiveMessageListener

public class ReceiveMessageListener implements Listener {

    // 插件主类
    private PluginMain pluginMain;

    public ReceiveMessageListener(PluginMain pluginMain){
        this.pluginMain = pluginMain;
    }

    @EventHandler
    public void onReceiveMessage(ReceiveMessageEvent receiveMessageEvent){
        // 获取消息文本
        String content = receiveMessageEvent.getContent();

        // 消息的完整响应
        Message message = receiveMessageEvent.getMessage();

        // 取得消息的发送者
        String fromUserName = message.getFromUserName();

        if("今夕是何年".equalsIgnoreCase(content)){

            // 获得客户端对象
            WeChatClient weChatClient = pluginMain.getWeChatClient();

            // 获得当前年份
            Calendar instance = Calendar.getInstance();
            int year = instance.get(Calendar.YEAR);

            // 回复消息给发送者
            weChatClient.getWeChatCore().getHttpAPI().sendMessage(fromUserName,String.valueOf(year));
            
        }

    }
}

等等,这一大坨是什么?且听小生慢慢道来

作为监听器类必须要实现 Listener 接口

@EventHandler 注解指定该方法为事件监听

ReceiveMessageEvent 是具体监听的事件

在方法体内编写你的逻辑,如上便实现了我们的需求,当事件触发时,判断消息是否为 "今夕是何年",如果是则回复当前的年份

接下来,把监听器注册到插件上,修改主类的 onEnable 方法

    @Override
    public void onEnable() {
        getLogger().info("插件载入啦");
        // 注册监听器
        ReceiveMessageListener receiveMessageListener = new ReceiveMessageListener(this);
        getWeChatClient().getEventManager().registerPluginListener(this,receiveMessageListener);
    }

如此,就大功告成了,此时我们的插件结构长这样

image

载入插件

打包为jar,放入wechatbc的plugins文件夹

image

重启服务

image

可以看到,我们的插件已经载入了。效果如下

dc215c3298cf6edb432e6aeafaedc9b

其他

如果你仍有疑惑或想要制作更多的效果。可以参考随wechatbc一同发布的插件 WeChatSetu

其中展示了指令注册,视频,图片发送等。文档的篇幅再长也未必有代码的说服力强

指令注册

指令,即是特殊的消息,不同的是他可以被控制台输入而不止是微信用户

插件编写指令非常简单,首先在 plugins.yml 下引入注册的指令

name: TestPlugin
...其他内容省略
commands:
  - "test"
  # - '你也可以写更多'

任务的具体逻辑委托给 CommandExecutor 接口进行,你需要编写一个实现类

public interface CommandExecutor {
    void onCommand(CommandSender sender, String[] args);
}

重写 onCommand 方法来实现你自己的逻辑,其中的参数解释如下

指令执行者

CommandSender sender 指令的执行者,区分有 控制台(ConsoleSender) 微信用户(ContactSender)

例如你只想让控制台执行

    @Override
    public void onCommand(CommandSender commandSender, String[] strings) {
        if(!(commandSender instanceof ConsoleSender)){
            commandSender.sendMessage("该指令仅能由控制台执行");
            return;
        }
    }

或者你想看看是不是用户操作的,并确定其是否有具体的权限

    @Override
    public void onCommand(CommandSender commandSender, String[] strings) {
        if(commandSender instanceof ContactSender){
            ContactSender contactSender = (ContactSender) commandSender;
            // 获得执行指令的用户
            Contact contact = contactSender.getContact();
            // 权限判断 (这里只是举个例子,我们判断了用户的微信昵称是不是 mmeteor
            if(!contact.getNickName().equalsIgnoreCase("mmeteor")){
                contactSender.sendMessage("你没有权限进行!");
                return;
            }
            // 通过后的逻辑....
        }
    }

指令参数

args 为指令的参数,例如对于指令 /test arg arg1 参数便是[arg,arg1]

合理使用args属性,能让你以 *子指令 的形式少注册很多coomands

完成指令注册

最后,为你的指令委托处理类

getCommand("test").setCommandExecutor(CommandExecutor);

就大功告成了,最后,如果指令是由用户发出,需要以 /指令 参数 的格式 (例如 /test arg1)