diff --git a/README.md b/README.md index c5b0b71..ed324fa 100644 --- a/README.md +++ b/README.md @@ -1,33 +1,56 @@ # 使用Go语言重新实现 [sihuan/XZZ](https://github.com/sihuan/XZZ) 机器人项目 +本项目是一个使用Go语言重新实现 [sihuan/XZZ](https://github.com/sihuan/XZZ) 机器人项目。原使用go-cqhttp的机器人项目,由于go-cqhttp不再维护,有众多bug,无法使用,所以更换使用 [napcat](https://github.com/NapNeko/NapCatQQ) 实现。 -## 使用方式: - -- 下载一个`go-cqhttp` 配置http模式,修改为下面类似配置 +当前项目的功能都在`workers`目录下。同时所有接收到的消息都保存在一个sqllite数据库中,文件名为`data.db`保存在项目根目录。 +## 部署服务: +1. 先使用docker部署[napcat](https://github.com/NapNeko/NapCatQQ),然后修改配置文件,将机器人的token替换为napcat的token,然后运行项目即可。 +部署[napcat](https://github.com/NapNeko/NapCatQQ)可参考下面的docker-compose.yml文件: ```yaml - - http: # HTTP 通信设置 - address: 0.0.0.0:5700 # HTTP监听地址 - version: 11 # OneBot协议版本, 支持 11/12 - timeout: 5 # 反向 HTTP 超时时间, 单位秒,<5 时将被忽略 - long-polling: # 长轮询拓展 - enabled: false # 是否开启 - max-queue-size: 2000 # 消息队列大小,0 表示不限制队列大小,谨慎使用 - middlewares: - <<: *default # 引用默认中间件 - post: # 反向HTTP POST地址列表 - - url: http://0.0.0.0:5580 # 地址 + version: '3' + services: + napcat: + image: mlikiowa/napcat-docker:latest + container_name: napcat + environment: + - ACCOUNT= + - HTTP_ENABLE=true + - HTTP_POST_ENABLE=true + - HTTP_URLS=["http://172.17.0.1:5580/"] + ports: + - "5700:3000" + - "6099:6099" + volumes: + - ~/dockerfile/napcat/config:/usr/src/app/napcat/config + - ~/dockerfile/napcat/QQ:/root/.config/QQ ``` -- 配置事件过滤规则 - ```json - { - "message_type": "group", - "raw_message":{ - ".regex":"^!" - } - } - ``` - 表示只接收以 ! 开头的指令,同时修改配置文件默认中间件锚点的事件过滤器文件目录 `filter: filter.json` ,还要修改上报数据类型为 `array` 。 + 然后启动docker-compose.yml文件即可。 -- 自定义配置 - 修改项目目录下的 `config.toml` 文件,`APIURL` 配置为 `go-cqhttp` 的 `post` 配置的 `url` 地址。 - `POSTURL` 配置为 `go-cqhttp` 的 `http` 配置的 `address` 地址,需要加协议前缀 `http://`。 - 后面的 [Group] 按需求配置,注意里面的群名要加双引号,因为程序里读取的是 `string` 类型。 \ No newline at end of file +2. 运行本项目前需要先修改配置文件,将本项目目录下的`config example.toml` 重命名为`config.toml`,然后修改配置文件,默认的配置端口跟上面的 docker-compose.yml文件一致,不需要修改。如果需要使用ai功能,需要修改配置文件里的`MODEL`,`OPENAI_API_KEY`和`OPENAI_BaseURL`这三个字段。 +3. 启动项目:安装go环境,然后运行`go run main.go`即可。你也可以使用`go build main/go -o go-bot`编译为可执行文件, +## 使用说明: +1. 默认的配置端口是5580,如果需要修改,请修改配置文件里的`APIURL`字段。默认获取以`!`开头的消息,如果需要修改,请修改配置文件里的`Prefix`字段。 + +## 编写插件: +所有的插件放在`workers`目录下,并且都要有下面的代码: +```go +package workers + +func init() { + RegisterWorkerFactory("ping", func(parms []string, uid, gid, role, mid, rawMsg string) Worker { + return &Ping{ + StdAns: NewStdAns(parms, uid, gid, role, mid, rawMsg), + } + }) +} + +type Ping struct { + *StdAns +} +``` +上面的例子是实现里`ping`这个插件的注册,在群组中以`!ping`指令激活。 +同时所有的功能需要写在实现的`GetMsg()`方法里,如`!ping` 命令的: +```go +func (a *Ping) GetMsg() string { + return "Pong!" +} +``` \ No newline at end of file diff --git a/config example.toml b/config example.toml index 13f6038..e774f6c 100644 --- a/config example.toml +++ b/config example.toml @@ -1,9 +1,14 @@ APIURL = "0.0.0.0:5580" POSTURL = "http://0.0.0.0:5700" - +Prefix = "!" AllowGroup = [] AllowUser = [] AllowRole = [] BlockGroup = [] -BlockUser = [] \ No newline at end of file +BlockUser = [] +Master = [] +MODEL = "gpt-4o" +OPENAI_API_KEY = "https://api.openai.com/v1" +OPENAI_BaseURL = "sk-xxxx" +PROMPT = "## Role : \nQQ群Linux助手\n\n## Background : \n该角色是一位专门为QQ群提供Linux相关技术支持的助手,熟悉各种Linux发行版的使用和问题解决,旨在帮助群友解决他们在使用Linux过程中遇到的各种问题。\n\n## Preferences : \n该角色偏好简洁明了的回答风格,注重解决方案的精确性和有效性。喜欢友好和尊重的互动方式,致力于营造一个技术交流的和谐环境。\n\n## Profile :\n- language: 中文\n- description: 为QQ群友提供Linux相关问题的简洁、精确解决方案\n\n## Goals :\n1. 回答Linux相关问题\n2. 提供简短、精确的解决方案\n3. 鼓励群友提出问题并尊重他们\n\n## Constrains :\n1. 避免回答政治相关内容\n2. 每个问题只回答一次,确保回复简短、精确\n\n## Skills :\n1. 熟悉各种Linux发行版的使用和问题解决\n2. 能够提供简洁明了的技术支持\n3. 友好回复群友的提问\n\n## Examples :\n1. 问题:如何查看当前Linux系统的内核版本?\n 答案:可以使用命令`uname -r`来查看当前的内核版本。\n \n2. 问题:如何安装一个软件包?\n 答案:可以使用`sudo pacman -S <软件包名>`来安装软件包(适用于Archlinux系)。\n\n## OutputFormat :\n1. 接收用户输入的问题。\n2. 提供简洁、精确的解决方案。\n\n## Initialization : \n作为 QQ群Linux助手, 拥有 熟悉各种Linux发行版的使用和问题解决, 能够提供简洁明了的技术支持, 友好回复群友的提问, 避免回答政治相关内容, 每个问题只回答一次,确保回复简短、精确, 使用默认 中文 与用户对话,友好的欢迎用户。然后介绍自己,并提示用户输入。\n" diff --git a/main.go b/main.go index 8fd2bfd..3808538 100644 --- a/main.go +++ b/main.go @@ -7,7 +7,9 @@ import ( "go-bot/utils" "io" "log" + "net" "net/http" + "strings" "time" "github.com/gin-gonic/gin" @@ -122,6 +124,12 @@ func main() { fmt.Println("Server listening on", APIURL, "...") if err := r.Run(APIURL); err != nil { - log.Fatal("服务器启动失败:", err) + if opError, ok := err.(*net.OpError); ok && opError.Op == "listen" { + log.Fatal("服务器启动失败:端口被占用。") + } else if strings.Contains(err.Error(), "address already in use") { + log.Fatal("服务器启动失败:端口被占用。") + } else { + log.Fatal("服务器启动失败:", err) + } } } diff --git a/utils/router.go b/utils/router.go index a00a310..7389854 100644 --- a/utils/router.go +++ b/utils/router.go @@ -2,6 +2,7 @@ package utils import ( "fmt" + "go-bot/config" "go-bot/workers" "regexp" "strings" @@ -32,9 +33,13 @@ func Router(data map[string]interface{}) { raw_msg = raw_msg + " " + fullMatch } } + prefix, err := config.GetConfig()["Prefix"].(string) + if !err { + panic("Prefix设置异常!") - fmt.Println("raw_msg:", string(raw_msg)) - if len(raw_msg) > 1 && raw_msg[0] == '!' { + } + // fmt.Println("raw_msg:", string(raw_msg)) + if len(raw_msg) > 1 && string(raw_msg[0]) == prefix { // 去除'!' raw_msg = raw_msg[1:] parms := strings.Fields(raw_msg) diff --git a/workers/ai.go b/workers/ai.go index 0823087..237011b 100644 --- a/workers/ai.go +++ b/workers/ai.go @@ -104,9 +104,9 @@ func (a *AI) GetMsg() string { fmt.Println("获取图片大小失败:", err) return "获取图片大小失败" } - if fileSize/1024/1024 > 1.0 { - log.Println("文件大小超过1M") - return "文件大小超过1M" + if fileSize/1024/1024 > 2.0 { + log.Println("文件大小超过2M") + return "文件大小超过2M" } filePath := a.GetImage(file) // println("filePath:", filePath)