# wechat-bot **Repository Path**: LeftJson/wechat-bot ## Basic Information - **Project Name**: wechat-bot - **Description**: 微信机器人 - **Primary Language**: Java - **License**: Apache-2.0 - **Default Branch**: 2.2 - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 42 - **Created**: 2024-11-01 - **Last Updated**: 2024-11-01 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # wechat-bot ### 免责声明 本仓库仅供学习交流使用,请勿用于商业用途,否则后果自负,作者不承担任何责任。 请遵守相关法律法规,请勿将本仓库代码、release文件等用于灰黑产领域。 请遵守腾讯公司微信使用协议,请勿用于非法用途。 如您使用本仓库代码及release文件,则默认您同意以上声明及协议。 ### 介绍 此仓库是bot本体及基础插件仓库,为了便于维护,bot本体和插件实现不在同一仓库,如需要插件请移步 [**插件仓库**](https://gitee.com/ilooli/wechat-bot-plugins)。 微信机器人,基于web微信接口Java实现,bot的核心流程如下: ``` +--------------+ +---------------+ +---------------+ | | | | | | | Get UUID | | Get Contact | | Status Notify | | | | | | | +-------+------+ +-------^-------+ +-------^-------+ | | | | +-------+ +--------+ | | | +-------v------+ +-----+--+------+ +--------------+ | | | | | | | Get QRCode | | Weixin Init +------> Sync Check <----+ | | | | | | | +-------+------+ +-------^-------+ +-------+------+ | | | | | | | +-----------+ | | | +-------v------+ +-------+--------+ +-------v-------+ | | Confirm Login | | | | +------> Login +---------------> New Login Page | | Weixin Sync | | | | | | | | | +------+-------+ +----------------+ +---------------+ | | |QRCode Scaned| +-------------+ ``` 目前已实现的功能: 1、登录(扫码登录、push登录[存在bug]、自动登录) 2、心跳同步,并拉取新消息消费,转换为对应的消息对象(`Message`) 3、消息发送,包括文本、图片、视频、图片表情、文件 4、插件机制,可以自定义消息处理器,实现自定义消息消费,接收到消息后转换处理后,会发布消息事件,可自行订阅消息事件实现所需功能 5、缓存机制,包括联系人缓存、群聊缓存 6、心跳超时重启,此功能需配合docker的`on failure`重启机制,代码中只是监控心跳是否超时,超时后结束进程返回code 1 ### 软件架构 - JDK: 17+ - http: OkHttp - 日志: Slf4j + logback - 工具库: hutool - emoji处理: emoji-java - 命令行解析: picocli - yaml解析: snakeyaml - 终端二维码输出: com.google.zxing ### 安装教程 ##### 一、下载jar包运行 进入[Release](https://gitee.com/ilooli/wechat-bot/releases)下载`wechat-bot.jar`包,运行`java -jar wechat-bot.jar`即可。 如需插件管理和命令权限管理功能,请同时下载`wecaht-bot-plugin-pm.jar`和`wechat-bot-plugin-cm.jar`放入和`wechat-bot.jar` 同级的`plugin`目录下,并运行`java -jar wechat-bot.jar`即可。 ##### 二、拉取源码编译运行 使用`git clone https://gitee.com/ilooli/wechat-bot.git` 拉取本仓库,使用`mvn clean install`编译`wechat-bot-core` 模块并安装到本地maven仓库, 在IDEA中执行`wechat-bot-implement`模块的`main`方法即可,或使用`mvn clean package`打包生成`wechat-bot.jar` 包,运行`java -jar wechat-bot.jar`即可。 注: `wecaht-bot.jar`第一次运行时,若无相关所需文件夹,会自动创建。 ##### 三、Docker部署 1、下载`wechat-bot-implment`模块下的`docker/Dockerfile`文件,并放置到任意目录,如`/opt/wechat-bot`。 2、将`docker`文件夹下的`simfang.ttf`文件复制到`/opt/wechat-bot`目录下(如果不需要词云生成,此步骤可省略)。 3、将最新的`wechat-bot.jar`文件复制到`/opt/wechat-bot`目录下。 4、使用`docker build -t wechat-bot .`命令构建镜像。 5、使用`docker run -itd -v /opt/wechat-bot:/app wechat-bot`命令启动容器。 如果需要http插件向外提供http服务,则需要在创建容器时指定`-p`参数暴露端口,http默认端口为12345,可自行修改。 ### 详细说明 ##### bot配置文件 `config.yml`配置文件,默认在`conf`目录下,可自行修改。配置类声明在`wechat-bot-implement`模块的`config`包下。 ```yaml # bot相关配置 bot: # 是否在启动时打印欢迎横幅。 printBanner: true # 是否保存接收到的媒体数据(图片、语音、视频),不建议开启。 saveMedia: false # 心跳超时时间,单位为分,默认为1分钟,当心跳超时后,bot进程会结束 heatbeatTimeout: 5 # bot所有者,建议修改为自己的微信备注,若无备注则会判断昵称,否则执行命令时会提示无权限。 owner: Ooops # 登录相关配置 login: # 是否启用自动登录功能。 autoLogin: true # 是否打印二维码,用于扫描登录。 printQrCode: true # 是否加密登录信息,强烈建议开启 encryptLoginInfo: true # 登录失败时的重试次数。 reteyCount: 3 # 保存登录信息时的加密密钥,建议自行修改。 encryptKey: wechat::bot # 指令相关配置 command: # 没有权限时的提示 noPermissionTip: "你没有权限执行此命令" # 是否显示没有权限时的提示 showNoPermissionTip: true ``` 其中`encryptKey`用于保存登录信息时的加密密钥,默认为`wechat::bot`,可通过`-DencryptKey=xxxx`参数修改,但`config.yml` 文件中的`encryptKey`优先级高于`-DencryptKey=xxxx`参数。 `owner`用于设置bot所有者(拥有执行命令的权限,如果不设置则无法执行命令),可通过`-Downer=xxxx`参数修改, 但`config.yml`文件中的`owner`优先级高于`-Downer=xxxx`参数。 ##### 日志配置文件 `logback.xml`配置文件,默认使用内置的`logback.xml`配置文件,可自行修改后存放于`config`目录下,即`config/logback.xml` 优先级高于内置配置文件。
日志配置文件 ```xml ${CONSOLE_LEVEL} ${CONSOLE_PATTERN} ${LOG_HOME}/wecht-bot.log INFO ${FILE_PATTERN} UTF-8 10MB ${LOG_HOME}/wecht-bot.${DATE_PATTERN} 10 1GB ${LOG_HOME}/debug.log DEBUG ${FILE_PATTERN} UTF-8 10MB ${LOG_HOME}/debug.${DATE_PATTERN} 10 1GB ${LOG_HOME}/info.log INFO ACCEPT DENY ${FILE_PATTERN} UTF-8 10MB ${LOG_HOME}/info.${DATE_PATTERN} 10 1GB ${LOG_HOME}/error.log ERROR ACCEPT DENY %msg%n UTF-8 10MB ${LOG_HOME}/error.${DATE_PATTERN} 10 1GB ```
##### 上下文Context 上下文为单例设计模式,所有模块都可以通过Context获取到上下文信息。其中存放了bot的运行状态、登录状态以及各管理器和api。
Context 代码 ```java @Getter public enum Context { INSTANCE; /** bot 运行状态 */ @Setter private boolean running; /** 登录状态 */ @Setter private boolean logedin; /** 自动登录状态 */ @Setter private boolean autoLogedin; /** 最后一次心跳时间 */ @Setter private volatile long lastHeartbeat; /** bot */ @Setter private Contact me; /** bot管理员 */ @Setter private Contact owner; /** api */ @Setter private WechatApi api; /** session */ @Setter private Session session; /** 封装的http引擎 */ @Setter private HttpEngine httpEngine; /** 下载器 */ @Setter private Downloader downloader; /** 事件管理器 */ @Setter private EventManager eventManager; /** 插件管理器 */ @Setter private PluginManager pluginManager; /** 命令管理器 */ @Setter private CommandManager commandManager; /** 联系人管理器 */ @Setter private ContactManager contactManager; } ```
##### 插件机制&如何创建一个插件 bot只保证基础功能,即登录、心跳保持、收发转换消息、发布事件等,插件机制提供了一套完整的插件机制,可以方便的扩展bot的功能。 当bot接收到消息,会创建一个消息事件并发送,事件管理器中存放了所有监听器(按优先级从小到大排序),当收到消息时,会遍历所有监听器,如果监听器支持该事件,则执行监听器中的功能逻辑。 那么,如何创建一个插件呢? 你可以直接继承本仓库内的`wechat-bot-plugin-base`模块,此模块引入了`wechat-bot-core`的依赖和`shade` 打包插件,当然你也可以自己创建一个模块并引入`wechat-bot-core`模块,自行引入`shade`打包模块和配置, 然后继承`Plugin`,`Plugin`类提供了插件的必要信息,比如插件名称、版本、作者、描述等,但不执行具体的功能逻辑。 监听事件需要你创建一个监听器,继承`EventListener, S>`,`E`为事件类型,`S`为事件源类型。 然后实现`support(@NonNull E event, S source)`方法和实现`onEvent(@NonNull E event, S source)`方法, `support`方法用于判断监听器是否支持该事件,`onEvent`方法用于执行监听器中的功能逻辑。 如果这个插件监听某个事件且执行完成之后,不需要其他插件再监听这个事件并执行,则需要重写`boolean executeNext()` 方法使其返回`false`,这样事件管理器将不再遍历其他监听器。 你可以参考`wechat-bot-plugin`模块下的`wechat-bot-plugin-push`插件来实现自己的命令监听器。 命令机制和事件监听机制类似,不同的是命令机制需要继承`CommandExcutor`类,该类提供了命令执行器所属的插件信息、上下文、触发此命令的文本消息对象以及命令的相关元数据。 由于命令解析采用了picocli,因此你可以参考[picocli](https://picocli.info/)的文档来编写命令。 一个命令执行器处理需要继承`CommandExcutor`类,还需要定义`@Command`注解,该注解用于定义命令的名称、描述、参数等。 如果你的命令执行器不包含子命令,那么还需要实现`Runnable`或`Callable`接口,`Runnable`用于执行命令,`Callable`用于执行命令并返回结果。 你可以参考`wechat-bot-plugin`模块下的`wechat-bot-plugin-pm`和`wechat-bot-plugin-cm`两个插件来实现自己的命令执行器。 ### 参与贡献 1. Fork 本仓库 2. 新建 Feat_xxx 分支 3. 提交代码 4. 新建 Pull Request ### 鸣谢 本仓库的许多功能都是基于开源项目,感谢开源社区提供的开源项目。 - [picocli](https://picocli.info/) - [logback](https://logback.qos.ch/) - [slf4j](https://www.slf4j.org/) - [Urinx/WeixinBot](https://github.com/Urinx/WeixinBot) - [meteorOSS/wechat-bc](https://github.com/meteorOSS/wechat-bc) - [hellokaton/wechat-api](https://github.com/hellokaton/wechat-api) ### 加入我们或者联系作者 扫描下方二维码添加机器人,验证信息填写“wechat-bot”或者通过好友验证后私聊发送“wechat-bot”即可加入交流群。
img.png