# 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”即可加入交流群。