Categorygithub.com/ghostlee/qq-bot-api
modulepackage
0.0.0-20190915143611-7eed820cac55
Repository: https://github.com/ghostlee/qq-bot-api.git
Documentation: pkg.go.dev

# README

Golang bindings for the CoolQ HTTP API

GoDoc Build Status

This package is a golang SDK for CoolQ HTTP API. You can develop a QQ Bot that works based on CoolQ and CoolQ HTTP API plugin, with golang and this package.

The architectures and method names in this package are mainly inspired by go-telegram-bot-api. Meanwhile, we provide a couple of features like event emitter and chained api, inspired by other SDKs of CQHTTP. In most cases, this package gives you a friendly experience of developing bots in golang. You'll find it easy to navigate to this package, if you have once worked with go-telegram-bot-api or SDKs of CQHTTP in other languages. However, there are still use cases of CQHTTP that we do not cover with a good support ---- by design, for example, the scenario of using multiple CoolQ instance with one bot application.

Head through the following examples and godoc will give you a tutorial about how to use this package. If you still have problems, look up to the code or open an issue.

Communication Methods

CoolQ HTTP API provides several choices of communication method. The table below shows whether this SDK supports a kind of method.

MethodAPIEvent
HTTP√ *
WebHook (i.e. HTTP Reverse)√ **
WebSocket
WebSocket Reverse×

* CQHTTP LongPolling Plugin is required to use this feature.
** Only limited operations (e.g. reply, approve) are provided by CQHTTP, in response to an event.

Quick Guide

This is a very simple bot that just displays any gotten updates, then replies it to that chat.

func main() {
	bot, err := qqbotapi.NewBotAPI("MyCoolqHttpToken", "http://localhost:5700", "CQHTTP_SECRET")
	if err != nil {
		log.Fatal(err)
	}

	bot.Debug = true

	u := qqbotapi.NewWebhook("/webhook_endpoint")
	u.PreloadUserInfo = true

	// Use WebHook as event method
	updates := bot.ListenForWebhook(u)
	// Or if you love WebSocket Reverse
	// updates := bot.ListenForWebSocket(u)
	go http.ListenAndServe("0.0.0.0:8443", nil)

	for update := range updates {
		if update.Message == nil {
			continue
		}

		log.Printf("[%s] %s", update.Message.From.String(), update.Message.Text)

		bot.SendMessage(update.Message.Chat.ID, update.Message.Chat.Type, update.Message.Text)
	}
}

If you need to utilize a sync response, it will be slightly different.

func main() {
	bot, err := qqbotapi.NewBotAPI("MyCoolqHttpToken", "http://localhost:5700", "CQHTTP_SECRET")
	if err != nil {
		log.Fatal(err)
	}

	bot.Debug = true

	u := qqbotapi.NewWebhook("/webhook_endpoint")
	u.PreloadUserInfo = true
	bot.ListenForWebhookSync(u, func(update qqbotapi.Update) interface{} {

		log.Printf("[%s] %s", update.Message.From.String(), update.Message.Text)

		return map[string]interface{}{
			"reply": update.Message.Text,
		}
	})

	http.ListenAndServe("0.0.0.0:8443", nil)
}

It's as easy as well if you prefer WebSocket or LongPolling as event method.

func main() {
	// Whether to use WebSocket or LongPolling depends on the address.
	// To use WebSocket, the address should be something like "ws://localhost:6700"
	bot, err := qqbotapi.NewBotAPI("MyCoolqHttpToken", "http://localhost:5700", "CQHTTP_SECRET")
	if err != nil {
		log.Fatal(err)
	}

	bot.Debug = true

	u := qqbotapi.NewUpdate(0)
	u.PreloadUserInfo = true
	updates, err := bot.GetUpdatesChan(u)
	
	for update := range updates {
		if update.Message == nil {
			continue
		}

		log.Printf("[%s] %s", update.Message.From.String(), update.Message.Text)

		bot.SendMessage(update.Message.Chat.ID, update.Message.Chat.Type, update.Message.Text)
	}
}

Event Emitter

If you come from Python/JavaScript, you'll be probably looking for this feature. We at here provide it as a helper that you may choose to use or not on your taste.

var bot *qqbotapi.BotAPI

func Log(update qqbotapi.Update) {
	log.Printf("[%s] %s", update.Message.From.String(), update.Message.Text)
}

func Echo(update qqbotapi.Update) {
	bot.SendMessage(update.Message.Chat.ID, update.Message.Chat.Type, update.Message.Text)
}

func main() {
	var err error
	bot, err = qqbotapi.NewBotAPI("MyCoolqHttpToken", "http://localhost:5700", "CQHTTP_SECRET")
	if err != nil {
		log.Fatal(err)
	}
	u := qqbotapi.NewWebhook("/webhook_endpoint")
	updates := bot.ListenForWebhook(u)
	go http.ListenAndServe("0.0.0.0:8443", nil)

	ev := qqbotapi.NewEv(updates)
	// Function Echo will get triggered on receiving an update with
	// PostType `message`, MessageType `group` and SubType `normal`
	ev.On("message.group.normal")(Echo)
	// Function Log will get triggered on receiving an update with
	// PostType `message`
	ev.On("message")(Log)

	// Keep main thread alive
	<-make(chan bool)
}

Messages

Update.Message.Message is a group of Media, defined in package cqcode.

	for update := range updates {
		if update.Message == nil {
			continue
		}

		for _, media := range *update.Message.Message {
			switch m := media.(type) {
			case *cqcode.Image:
				fmt.Printf(
					"The message includes an image, id: %s, url: %s",
					m.FileID,
					m.URL,
				)
			}
		}
	}

There are some useful command helpers.

	for update := range updates {
		if update.Message == nil {
			continue
		}

		// If this is true, a valid command must start with a command prefix (default to "/"),
		// false by default.
		cqcode.StrictCommand = true
		// Set command prefix
		cqcode.CommandPrefix = "/"

		if update.Message.IsCommand() {
			// cmd string, args []string
			// In a StrictCommand mode, the command prefix will be stripped off.
			cmd, args := update.Message.Command()

			// Note that cmd and args are still media
			cmdMedia, _ := cqcode.ParseMessage(cmd)
			for _, v := range cmdMedia {
				switch v.(type) {
				case *cqcode.At:
					fmt.Print("The command includes an At!")
				case *cqcode.Face:
					fmt.Print("The command includes a Face!")
				}
			}
		}
	}

Send Messages

The easiest way to send a message is to use a chained api.

	// Send a text-img message
	s := bot.NewMessage(10000000, "group").
		At("1232332333").
		Text("嘤嘤嘤").
		NewLine().
		FaceByName("调皮").
		Text("这是一个测试").
		ImageBase64("img.jpg").
		Send()

	// Withdraw that message
	if s.Err == nil {
		bot.DeleteMessage(s.Result.MessageID)
	}

	// Send a stand-alone message (No need to call Send())
	bot.NewMessage(10000000, "private").
		Dice()

You can also use bot.SendMessage.

	// All media types defined in package cqcode can be sent directly.
	// e.g. Send a text message
	bot.SendMessage(10000000, "group", cqcode.Text{
		Text: "[<- These will be encoded ->]",
	})

	// Send a location
	bot.SendMessage(10000000, "group", cqcode.Location{
		Content:   "上海市徐汇区交通大学华山路1954号",
		Latitude:  31.198878,
		Longitude: 121.436381,
		Style:     1,
		Title:     "位置分享",
	})

	// Send a message that contains a number of media.
	message := make(cqcode.Message, 0)
	message.Append(&cqcode.At{QQ: "all"})
	message.Append(&cqcode.Text{Text:" 大家起来嗨"})
	face, _ := cqcode.NewFaceFromName("调皮")
	message.Append(face)
	bot.SendMessage(10000000, "group", message)

	// To send an image or a record, you may use a helper function.
	// Format a base64-encoded image (Recommended)
	image1, err := qqbotapi.NewImageBase64("/path/to/image.jpg")

	// Format an image in the web.
	u, err := url.Parse("https://img.rikako.moe/i/D1D.jpg")
	image2 := qqbotapi.NewImageWeb(u)
	image2.DisableCache()

	// Format a local image if CQHTTP and your bot are under the same host.
	u, err = url.Parse("file:///tmp/D1D.jpg")
	image3 := qqbotapi.NewImageWeb(u)

Or you can manually use the function bot.Send and bot.Do with a "config". You should find this quite familiar if you have once developed a Telegram bot.

	// An alternative to bot.SendMessage and bot.DeleteMessage
	message := qqbotapi.NewMessage(10000000, "group", "aaaaaa")
	m, err := bot.Send(message)
	if err == nil {
		config := qqbotapi.DeleteMessageConfig{MessageID: m.MessageID}
		bot.Do(config)
	}

# Packages

Package cqcode provides basic structs of cqcode media, and utilities of parsing and formatting cqcode.

# Functions

NewBotAPI creates a new BotAPI instance.
NewBotAPIWithClient creates a new BotAPI instance It requires a token, an API endpoint and a secret which you set in Coolq HTTP API.
NewBotAPIWithWSClient creates a new BotAPI instance It requires a token, an API endpoint which you set in Coolq HTTP API.
No description provided by the author
NewFileBase64 formats a file into base64 format.
NewFileLocal formats a file with the file path, returning the string.
NewImageBase64 formats an image in base64.
NewImageLocal formats an image with the file path, this requires CQ HTTP runs in the same host with your bot.
NewImageWeb formats an image with the URL.
NewMessage creates a new Message.
NewRecordBase64 formats a record in base64.
NewRecordLocal formats a record with the file path, this requires CQ HTTP runs in the same host with your bot.
NewRecordWeb formats a record with the URL.
No description provided by the author
NewUpdate gets updates since the last Offset.
NewWebhook registers a webhook.

# Structs

APIResponse is a response from the Coolq HTTP API with the result stored raw.
BaseChat is base type for all chat config types.
BaseUpdateConfig contains information about loading updates.
BotAPI allows you to interact with the Coolq HTTP API.
Chat contains information about the place a message was sent.
ChatMemberConfig contains information about a user in a chat for use with administrative functions such as kicking or unbanning a user.
DeleteMessageConfig contains information of a message in a chat to delete.
EnableAnonymousChatConfig contains fields to enable anonymous chat.
No description provided by the author
File is a file.
No description provided by the author
Group is a group on QQ.
GroupControlConfig contains fields as a configuration of a group.
HandleFriendRequestConfig contains fields to handle a friend request.
HandleGroupRequestConfig contains fields to handle a group adding request.
HandleRequestConfig contains fields to handle a request.
KickChatMemberConfig contains extra fields to kick user.
LeaveChatConfig contains fields to leave a chat.
LikeConfig contains information of a like (displayed on personal profile page) to send.
Message is returned by almost every request, and contains data about almost anything.
MessageConfig contains information about a SendMessage request.
NetImage is an image located in the Internet.
NetRecord is a record located in the Internet.
NetResource is a resource located in the Internet.
PromoteChatMemberConfig contains fields to promote members of chat.
RestrictAllChatMembersConfig contains fields to restrict all chat members.
RestrictChatMemberConfig contains fields to restrict members of chat.
No description provided by the author
SetChatMemberCardConfig contains fields to set members's 群名片.
SetChatMemberTitleConfig contains fields to set members's 专属头衔.
Update is an update response, from GetUpdates.
UpdateConfig contains information about a GetUpdates request.
User is a user on QQ.
WebhookConfig contains information about a webhook.
No description provided by the author

# Interfaces

Chattable is any config type that can be sent.

# Type aliases

No description provided by the author