# wechat-bot
**Repository Path**: jin2014/wechat-bot
## Basic Information
- **Project Name**: wechat-bot
- **Description**: 微信机器人
- **Primary Language**: Java
- **License**: Apache-2.0
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 42
- **Created**: 2024-09-05
- **Last Updated**: 2024-09-05
## 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`第一次运行时,若无相关所需文件夹,会自动创建。
### 详细说明
##### bot配置文件
`config.yml`配置文件,默认在`conf`目录下,可自行修改。配置类声明在`wechat-bot-implement`模块的`config`包下。
```
/** 是否启用自动登录功能。 */
private Boolean autoLogin = true;
/** 是否打印二维码,用于扫描登录。 */
private Boolean printQrCode = true;
/** 是否在启动时打印欢迎横幅。 */
private Boolean printBanner = true;
/** 是否保存接收到的媒体数据(图片、语音、视频)。 */
private Boolean saveMedia = false;
/** 是否加密登录信息 */
private Boolean encryptLoginInfo = true;
/** 登录失败时的重试次数。 */
private Integer reteyCount = 3;
/** 保存登录信息时的加密密钥。 */
private String encryptKey = System.getProperty("encryptKey", "wechat::bot");
/** bot所有者 */
private String owner = System.getProperty("owner", "");
```
其中`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
ACCEPT
DENY
${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
${FILE_PATTERN}
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;
// 微信api
@Setter
private WechatApi api;
// 登录会话
@Setter
private Session session;
// 事件管理器
@Setter
private EventManager eventManager;
// 插件管理器
@Setter
private PluginManager pluginManager;
// 命令管理器
@Setter
private CommandManager commandManager;
// 联系人管理器
@Setter
private ContactManager contactManager;
// 封装的http引擎
@Setter
private HttpEngine, ?> httpEngine;
}
```
##### 插件机制&如何创建一个插件
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”即可加入交流群。