使用go语言编写一个qq群机器人

34

之前一直使用sihuan/XZZ 的机器人项目,使用的 Python,后端使用的 go-cqhttp,最近在学习 go 语言,就想着把 Python 的重新实现一遍,而且由于 go-cqhttp 在发布 NTQQ后一直不更新,年久失修,部分 api已经失效,所以一起更换,使用napcat 实现登录,因为都实现了 Onebot11的标准,api 基本不需要修改。下面介绍从部署无头QQ客户端,到运行此项目,再到编写插件的教程。

当前项目的功能都在 workers目录下。同时所有接收到的消息都保存在一个 sqlite 数据库中,文件名为 data.db 保存在项目根目录。

部署服务:

  1. 先使用docker部署 napcat ,然后修改配置文件,将机器人的token替换为 napcattoken,然后运行项目即可。 部署 napcat 可参考下面的 docker-compose.yml文件:

    version: '3'
    services:
      napcat:
        image: mlikiowa/napcat-docker:latest
        container_name: napcat
        environment:
          - ACCOUNT=<QQ号>
          - 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
    

    然后使用 docker-compose -f ./docker-compose.yml up -d 启动 docker-compose.yml文件即可。

  2. 运行本项目前需要先修改配置文件,将本项目目录下的 config example.toml 重命名为 config.toml,然后修改配置文件,默认的配置端口跟上面的 docker-compose.yml 文件一致,不需要修改。如果需要使用 ai功能,需要修改配置文件里的 MODEL,OPENAI_API_KEYOPENAI_BaseURL这三个字段。

  3. 启动项目:安装 go 环境,然后运行 go run main.go即可。你也可以使用 go build main/go -o go-bot编译为可执行文件,

使用说明:

  1. 默认的配置端口是5580,如果需要修改,请修改配置文件里的 APIURL字段。默认获取以 !开头的消息,如果需要修改,请修改配置文件里的 Prefix字段。

当前拥有的插件:

  • ping:判断程序运行,会响应 Pong!
  • ip:查询一个ip的详细信息,使用方法 ip <域名/ip>
  • lsp:请求 api.lolicon.app获取 Pixiv壁纸,暂时只简单实现获取随机壁纸。
  • hhsh:“能不能好好说话”,使用方式:hhsh <拼音简写>,如:hhsh awsl
  • pkg:用于查询 ArchLinux软件包信息,包含官方仓库和 AUR的软件包,使用方式:pkg linux
  • ai:加入 ChatGPT,支持文字和图片识别,图片识别需要 GPT4相关模型,使用方式:ai 你好,图片识别需要选中回复群聊的图片,然后使用如:ai 图片上有什么内容来调用。

pkg

ai

编写插件:

所有的插件放在 workers目录下,并且都要有下面的代码:

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 命令的:

func (a *Ping) GetMsg() string {
  return "Pong!"
}