GoroBot

Go语言编写的跨平台聊天机器人框架

快速入门

支持平台

特性

  • 高性能(我瞎说的反正 Go 怎么也比 Node 快)
  • 高扩展性(插件化设计)
  • 高自订性(插件想干啥都行.jpg)

能做什么

  • 方便地编写自己的插件
  • 所见即所得的命令格式
  • 以通用的方法回复消息

注意事项

如果有能力,请审查所有使用的代码!!! 由于语言的特性,开发者拥有极高的权限,请在使用不可信来源的插件时多加注意!

TODO

欢迎向本项目提交 Issue

Feature

  • 完善指令系统

Bugs

快速入门

安装框架

本框架仍然处于开发状态,代码迭代速度快,建议使用第二种安装方法。

从代码包导入

  • go get github.com/Jel1ySpot/GoroBot
  • main.go 中导入包

从仓库导入

Fork 并克隆仓库,在 main.go 文件与 plugins/ 文件夹中编写业务逻辑代码(已添加至 .gitignore)。 这样既能够适应框架的快速迭代,还可以更方便向本仓库提交 PR (对,我 鼓励任何人提交修复或功能代码,也欢迎在 github issue 中提出在使用过程中的任何问题与建议)

示范:

#/bin/bash
git clone https://github.com/PathtoYou/rRepo

cd rRpot
mkdir plugins
touch main.go

最小示例

这是一个最小示例:

package main

import (
	GoroBot "github.com/Jel1ySpot/GoroBot/pkg/core"
)

func main() {
	grb := GoroBot.Create()

	if err := grb.Run(); err != nil {
		panic(err)
	}
}

第一次运行上面的代码会报错,提示我们要填写配置文件(conf/config.json)。我们可以按照以下格式填写:

{
  "log_level": 1, // 日志等级。 0:Debug, 1:Info, 2:Warning, 3:Error
  "owner": { // 机器人所有者
    "qq": "你的QQ号" // 格式:"平台": "ID"
  }
}

填写完成后再次启动,可以发现报错消失了,但控制台没有输出。这是因为这段代码没有载入任何逻辑代码。在这段代码中,我们创建了一个 GoroBot 实例(为了方便,在文档中会用 grb 代表 GoroBot 实例),并通过 grb.Run() 运行了它。

引入适配器

GoroBot 框架使用适配器支持各种 IM 平台。具体支持列表见 支持平台。适配器也是一种插件。让我们尝试引入一个适配器:

import LgrClient "github.com/Jel1ySpot/GoroBot/pkg/lagrange" // 引入模块

// 在 main 函数中:
grb.Use(LgrClient.Create())

插件使用 Create() 创建一个服务,我们可以使用 grb.Use(*Service) 来使用一个服务。运行这段代码,如无意外还需要填写配置文件,详细请见 pkg/lagrange。 配置好服务后再次运行,没有意外的话机器人服务就启动成功了。

使用插件

同样是一个例子:

import "github.com/Jel1ySpot/GoroBot/example_plugin/message_logger" // 引入模块

// 在 main 函数中
grb.Use(message_logger.Create())

再次运行代码,尝试向机器人账号发送消息,如果控制台中出现了刚才发送的消息,代表框架已经搭建成功了!开始编写属于你自己的 IM Chatbot 吧!

接下来应该做什么

事件系统

GoroBot 通过事件系统实现了消息监听等功能。这一设计允许插件开发者和用户编写简洁、通用的代码来扩展和实现各种功能。

以消息事件举例

以下示例代码展示了如何使用事件系统注册和注销一个监听器:

import botc "github.com/Jel1ySpot/GoroBot/pkg/core/bot_context"

var del func()
del, _ = grb.On(GoroBot.MessageEvent(func(ctx botc.MessageContext) error {
	if ctx.String() == "ping" {
		_ = ctx.ReplyText("🏓")
		del()
	}
	return nil
}))

在这段代码中,通过调用 grb.On 方法,注册了一个监听消息事件的监听器。监听器的回调函数接收一个 ctx(消息内容上下文)参数。当接收到的消息内容为 "ping" 时,调用 ctx.ReplyText 方法回复 "🏓",并通过 del 函数注销该监听器,从而实现了单次响应特定消息的功能。

MessageEvent() 函数接受一个回调函数作为参数,并返回一个 Name 属性为 "message"EventHandler 实例。框架通过将用户提供的回调函数转换为 func(args ...any) error 的通用签名形式,简化了事件注册的流程。这种设计使开发者无需关心底层实现的细节,便可直观地使用框架或插件提供的事件注册器。

中间件

中间件使用 grb.Middleware(MiddlewareCallback) 注册。跟事件一样,这个方法返回一个函数用于注销该中间件。MiddlewareCallbakc 的签名为 func(bot BotContext, msg message.Context, next func(...MiddlewareCallback) error) error,跟消息事件不同的是,中间件的回调函数参数中有一个额外的参数 next,只有调用了它才会进入接下来的流程。

使用中间件实现的 ping

grb.Middleware(func(bot BotContext, msg message.Context, next func(...MiddlewareCallback) error) error {
	if msg.String() == "ping" {
		msg.ReplyText("🏓")
	}
	next()
})

API 文档

目前项目正处于开发初期,api 及其不稳定,建议参照 示例插件 中的使用方法。

资源文件管理

位于 pkg/core/resource.go,是 GoroBot 示例下的方法,为统一管理资源文件提供了接口。 文件存放于工作目录的 resources/ 下。

Resource

  • ID string 资源唯一标识符
  • FilePath string 资源文件保存路径
  • Downloaded time.Time 资源下载时间

grb.SaveResource(resourceID string, resourceURL string) error

保存资源文件。

grb.ResourceExists(resourceID string) bool

如果 ID 所指的资源存在,返回 true,否则返回 false

grb.GetResource(resourceID string) ([]byte, error)

获取 ID 所指向的资源信息

数据库操作

GoroBot 实例中存放着一个数据库接口。暴露了几个方法用于简易连接与操作。

grb.OpenDatabase(driverName string, dataSourceName string) error

打开数据库。同 sql.Open(driverName, dataSourceName)

grb.CloseDatabase() error

关闭数据库。

grb.Database() *sql.DB

获取数据库实例。

grb.DatabaseExist() bool

如果连接了数据库,返回 true,否则返回 false

message

message 包位于 pkg/core/message ,包含消息示例和上下文结构。

message.Context

消息的上下文,由适配器在触发消息事件时提供。

Context.Protocol() string

消息的协议,与 BotContext.Protocol() 相同,值可以为机器人所处的平台或所使用的协议。

Context.String() string

返回消息的文本预览。

Context.Message() *message.Base

返回消息结构。

Reply(message []*message.Element) error

在当前上下文中回复消息。具体实现由适配器决定。

ReplyText(text string) error

使用 Reply() 回复纯文本消息的便捷方法。

message.Base

消息的基本结构。含有以下属性:

  • MessageType message.Type 消息类型
  • ID string 消息 ID
  • Content string 显示文本
  • Elements []*Element 消息元素
  • Sender *entity.Sender 消息发送者
  • Time time.Time 消息发送(接收)时间

*Base.Marshall() string

序列化消息实体,使其能被保存以及使用 message.UnmarshallMessage(string) 读取。

message.Element

消息元素,消息的基本组成部分。

  • Type message.ElementType 元素类型
  • Content string 显示文本
  • Source string 多媒体索引,在资源一节中会提到

message.Text

  • Content: 显示文本
  • Source: ""

message.Quote

  • Content: [回复]
  • Source: 被引用消息的序列化对象

message.Mention

  • Content: @Somebody
  • Source: protocol:被提及用户的ID

message.Image

  • Content: [图片]
  • Source: 资源ID

message.Video

  • Content: [视频]
  • Source: 资源ID

message.File

  • Content: [文件]
  • Source: protocol:参数...

message.Voice

  • Content: [语音]
  • Source: 资源ID

message.Sticker

  • Content: [贴纸]([表情])
  • Source: protocol:参数...
  • Content: 百度一下,你就知道
  • Source: https://www.baidu.com

message.Other

  • Content: 奇怪的东西
  • Source: protocol:参数

message.Builder

构建消息元素链。

message.NewBuilder() *Builder

创建构建器。

*Builder.Append(elementType ElementType, content string, source string) *Builder

在消息链中添加元素。

*Builder.Build() []*message.Element

返回构造完成的元素链。

插件列表

欢迎在 issue 中提供你所写的插件信息。信息将会在维护者查看后加入列表。

注意事项

重申:如果有能力,请审查所有使用的代码!!! 由于语言的特性,开发者拥有极高的权限,请在使用不可信来源的插件时多加注意!

恶意插件可以做到的事情有:

  • 向恶意者发送消息
  • 发送恶意消息
  • 向恶意者传送账号信息以盗取账号
  • 盗取你的本机账号

插件

消息日志

import "github.com/Jel1ySpot/GoroBot/example_plugin/message_logger"

基础的消息事件监听。将消息预览打印到日志。

Ping

import "github.com/Jel1ySpot/GoroBot/example_plugin/ping

检测机器人连接状态,和一些调试命令

插件载入

import "github.com/Jel1ySpot/GoroBot/example_plugin/go_plugin

载入外部插件(限类 Unix 系统)