mirror of
https://github.com/Mrs4s/go-cqhttp.git
synced 2025-05-05 03:23:49 +08:00
feat: routing api by version & inject version field
This commit is contained in:
parent
7349fd4b82
commit
f900fd62fb
@ -23,7 +23,10 @@ type Param struct {
|
|||||||
|
|
||||||
type Router struct {
|
type Router struct {
|
||||||
Func string
|
Func string
|
||||||
|
Version []uint16
|
||||||
Path []string
|
Path []string
|
||||||
|
PathV11 []string // v11 only
|
||||||
|
PathV12 []string // v12 only
|
||||||
Params []Param
|
Params []Param
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -31,29 +34,90 @@ type generator struct {
|
|||||||
out io.Writer
|
out io.Writer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
PathAll = 0
|
||||||
|
PathV11 = 11
|
||||||
|
PathV12 = 12
|
||||||
|
)
|
||||||
|
|
||||||
func (g *generator) WriteString(s string) {
|
func (g *generator) WriteString(s string) {
|
||||||
io.WriteString(g.out, s)
|
io.WriteString(g.out, s)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *generator) generate(routers []Router) {
|
func (g *generator) generate(routers []Router) {
|
||||||
|
var actions []string // for onebot v12 get_supported_actions
|
||||||
|
for _, router := range routers {
|
||||||
|
if len(router.PathV12) > 0 {
|
||||||
|
actions = append(actions, router.PathV12...)
|
||||||
|
}
|
||||||
|
if len(router.Path) > 0 {
|
||||||
|
actions = append(actions, router.Path...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for i := range actions {
|
||||||
|
actions[i] = `"` + actions[i] + `"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: v12 和 all 的 switch-case 由常量改为数组寻址, 以利用 get_supported_actions
|
||||||
g.WriteString("// Code generated by cmd/api-generator. DO NOT EDIT.\n\n")
|
g.WriteString("// Code generated by cmd/api-generator. DO NOT EDIT.\n\n")
|
||||||
g.WriteString("package api\n\nimport (\n\n")
|
g.WriteString("package api\n\nimport (\n\n")
|
||||||
g.WriteString("\"github.com/Mrs4s/go-cqhttp/coolq\"\n")
|
g.WriteString("\"github.com/Mrs4s/go-cqhttp/coolq\"\n")
|
||||||
g.WriteString("\"github.com/Mrs4s/go-cqhttp/global\"\n")
|
g.WriteString("\"github.com/Mrs4s/go-cqhttp/global\"\n")
|
||||||
g.WriteString(")\n\n")
|
g.WriteString(")\n\n")
|
||||||
g.WriteString(`func (c *Caller) call(action string, p Getter) global.MSG {
|
g.WriteString(fmt.Sprintf(`func (c *Caller) call(action string, version uint16, p Getter) global.MSG {
|
||||||
|
if version == 12 {
|
||||||
|
if action == "get_supported_actions" {
|
||||||
|
return coolq.OK([]string{%v})
|
||||||
|
}
|
||||||
switch action {
|
switch action {
|
||||||
default:
|
`, strings.Join(actions, ",")))
|
||||||
return coolq.Failed(404, "API_NOT_FOUND", "API不存在")` + "\n")
|
|
||||||
for _, router := range routers {
|
for _, router := range routers {
|
||||||
g.router(router)
|
g.router(router, PathV12)
|
||||||
}
|
}
|
||||||
io.WriteString(g.out, `}}`)
|
io.WriteString(g.out, `}}`)
|
||||||
|
io.WriteString(g.out, "\n")
|
||||||
|
g.WriteString(`if version == 11 {
|
||||||
|
switch action {
|
||||||
|
`)
|
||||||
|
for _, router := range routers {
|
||||||
|
g.router(router, PathV11)
|
||||||
|
}
|
||||||
|
io.WriteString(g.out, `}}`)
|
||||||
|
io.WriteString(g.out, "\n")
|
||||||
|
io.WriteString(g.out, "switch action {\n")
|
||||||
|
for _, router := range routers {
|
||||||
|
g.router(router, PathAll)
|
||||||
|
}
|
||||||
|
io.WriteString(g.out, `}`)
|
||||||
|
io.WriteString(g.out, "\n")
|
||||||
|
io.WriteString(g.out, "return coolq.Failed(404, \"API_NOT_FOUND\", \"API不存在\")}")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *generator) router(router Router, pathVersion int) {
|
||||||
|
/*
|
||||||
|
checkVersion := func(v uint16) bool {
|
||||||
|
for _, ver := range router.Version {
|
||||||
|
if ver == v {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
path := router.Path
|
||||||
|
if pathVersion == PathV11 {
|
||||||
|
path = router.PathV11
|
||||||
|
}
|
||||||
|
if pathVersion == PathV12 {
|
||||||
|
path = router.PathV12
|
||||||
|
}
|
||||||
|
if len(path) == 0 {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *generator) router(router Router) {
|
|
||||||
g.WriteString(`case `)
|
g.WriteString(`case `)
|
||||||
for i, p := range router.Path {
|
for i, p := range path {
|
||||||
if i != 0 {
|
if i != 0 {
|
||||||
g.WriteString(`, `)
|
g.WriteString(`, `)
|
||||||
}
|
}
|
||||||
@ -61,7 +125,19 @@ func (g *generator) router(router Router) {
|
|||||||
}
|
}
|
||||||
g.WriteString(":\n")
|
g.WriteString(":\n")
|
||||||
|
|
||||||
|
if len(router.Version) == 1 { // 目前来说只需要判断一个版本的情况
|
||||||
|
check := make([]string, 0, len(router.Version))
|
||||||
|
for _, ver := range router.Version {
|
||||||
|
check = append(check, fmt.Sprintf("version != %v", ver))
|
||||||
|
}
|
||||||
|
fmt.Fprintf(g.out, "if %v {\n", strings.Join(check, " && "))
|
||||||
|
fmt.Fprintf(g.out, "return coolq.Failed(405, \"VERSION_ERROR\", \"API版本不匹配\")}\n")
|
||||||
|
}
|
||||||
|
|
||||||
for i, p := range router.Params {
|
for i, p := range router.Params {
|
||||||
|
if p.Name == "version" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
if p.Default == "" {
|
if p.Default == "" {
|
||||||
v := "p.Get(" + strconv.Quote(p.Name) + ")"
|
v := "p.Get(" + strconv.Quote(p.Name) + ")"
|
||||||
fmt.Fprintf(g.out, "p%d := %s\n", i, conv(v, p.Type))
|
fmt.Fprintf(g.out, "p%d := %s\n", i, conv(v, p.Type))
|
||||||
@ -73,10 +149,14 @@ func (g *generator) router(router Router) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
g.WriteString("\t\treturn c.bot." + router.Func + "(")
|
g.WriteString("\t\treturn c.bot." + router.Func + "(")
|
||||||
for i := range router.Params {
|
for i, p := range router.Params {
|
||||||
if i != 0 {
|
if i != 0 {
|
||||||
g.WriteString(", ")
|
g.WriteString(", ")
|
||||||
}
|
}
|
||||||
|
if p.Name == "version" {
|
||||||
|
fmt.Fprintf(g.out, "version")
|
||||||
|
continue
|
||||||
|
}
|
||||||
fmt.Fprintf(g.out, "p%d", i)
|
fmt.Fprintf(g.out, "p%d", i)
|
||||||
}
|
}
|
||||||
g.WriteString(")\n")
|
g.WriteString(")\n")
|
||||||
@ -100,6 +180,8 @@ func conv(v, t string) string {
|
|||||||
return v + ".Uint()"
|
return v + ".Uint()"
|
||||||
case "uint32":
|
case "uint32":
|
||||||
return "uint32(" + v + ".Uint())"
|
return "uint32(" + v + ".Uint())"
|
||||||
|
case "uint16":
|
||||||
|
return "uint16(" + v + ".Uint())"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,7 +190,8 @@ func main() {
|
|||||||
src := flag.String("path", "", "source file")
|
src := flag.String("path", "", "source file")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
fset := token.NewFileSet()
|
fset := token.NewFileSet()
|
||||||
file, err := parser.ParseFile(fset, *src, nil, parser.ParseComments)
|
for _, s := range strings.Split(*src, ",") {
|
||||||
|
file, err := parser.ParseFile(fset, s, nil, parser.ParseComments)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
@ -145,6 +228,14 @@ func main() {
|
|||||||
for _, route := range strings.Split(args, ",") {
|
for _, route := range strings.Split(args, ",") {
|
||||||
router.Path = append(router.Path, unquote(route))
|
router.Path = append(router.Path, unquote(route))
|
||||||
}
|
}
|
||||||
|
case "route11":
|
||||||
|
for _, route := range strings.Split(args, ",") {
|
||||||
|
router.PathV11 = append(router.PathV11, unquote(route))
|
||||||
|
}
|
||||||
|
case "route12":
|
||||||
|
for _, route := range strings.Split(args, ",") {
|
||||||
|
router.PathV12 = append(router.PathV12, unquote(route))
|
||||||
|
}
|
||||||
case "default":
|
case "default":
|
||||||
for name, value := range parseMap(args, "=") {
|
for name, value := range parseMap(args, "=") {
|
||||||
for i, p := range router.Params {
|
for i, p := range router.Params {
|
||||||
@ -161,21 +252,47 @@ func main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
case "version":
|
||||||
|
version := strings.Split(args, ",")
|
||||||
|
for _, v := range version {
|
||||||
|
if i, err := strconv.ParseUint(v, 10, 16); err == nil {
|
||||||
|
router.Version = append(router.Version, uint16(i))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
sort.Slice(router.Path, func(i, j int) bool {
|
sort.Slice(router.Path, func(i, j int) bool {
|
||||||
return router.Path[i] < router.Path[j]
|
return router.Path[i] < router.Path[j]
|
||||||
})
|
})
|
||||||
|
sort.Slice(router.PathV11, func(i, j int) bool {
|
||||||
|
return router.PathV11[i] < router.PathV11[j]
|
||||||
|
})
|
||||||
|
sort.Slice(router.PathV12, func(i, j int) bool {
|
||||||
|
return router.PathV12[i] < router.PathV12[j]
|
||||||
|
})
|
||||||
}
|
}
|
||||||
if router.Path != nil {
|
if router.Path != nil || router.PathV11 != nil || router.PathV12 != nil {
|
||||||
routers = append(routers, router)
|
routers = append(routers, router)
|
||||||
} else {
|
} else {
|
||||||
println(decl.Name.Name)
|
println(decl.Name.Name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
sort.Slice(routers, func(i, j int) bool {
|
sort.Slice(routers, func(i, j int) bool {
|
||||||
return routers[i].Path[0] < routers[j].Path[0]
|
path := func(r Router) string {
|
||||||
|
if r.Path != nil {
|
||||||
|
return r.Path[0]
|
||||||
|
}
|
||||||
|
if r.PathV11 != nil {
|
||||||
|
return r.PathV11[0]
|
||||||
|
}
|
||||||
|
if r.PathV12 != nil {
|
||||||
|
return r.PathV12[0]
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return path(routers[i]) < path(routers[j])
|
||||||
})
|
})
|
||||||
|
|
||||||
out := new(bytes.Buffer)
|
out := new(bytes.Buffer)
|
||||||
|
29
coolq/api.go
29
coolq/api.go
@ -14,6 +14,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/Mrs4s/go-cqhttp/internal/base"
|
||||||
"github.com/segmentio/asm/base64"
|
"github.com/segmentio/asm/base64"
|
||||||
|
|
||||||
"github.com/Mrs4s/MiraiGo/binary"
|
"github.com/Mrs4s/MiraiGo/binary"
|
||||||
@ -25,7 +26,6 @@ import (
|
|||||||
|
|
||||||
"github.com/Mrs4s/go-cqhttp/db"
|
"github.com/Mrs4s/go-cqhttp/db"
|
||||||
"github.com/Mrs4s/go-cqhttp/global"
|
"github.com/Mrs4s/go-cqhttp/global"
|
||||||
"github.com/Mrs4s/go-cqhttp/internal/base"
|
|
||||||
"github.com/Mrs4s/go-cqhttp/internal/cache"
|
"github.com/Mrs4s/go-cqhttp/internal/cache"
|
||||||
"github.com/Mrs4s/go-cqhttp/internal/param"
|
"github.com/Mrs4s/go-cqhttp/internal/param"
|
||||||
"github.com/Mrs4s/go-cqhttp/modules/filter"
|
"github.com/Mrs4s/go-cqhttp/modules/filter"
|
||||||
@ -47,7 +47,8 @@ var defaultPageToken = guildMemberPageToken{
|
|||||||
// CQGetLoginInfo 获取登录号信息
|
// CQGetLoginInfo 获取登录号信息
|
||||||
//
|
//
|
||||||
// https://git.io/Jtz1I
|
// https://git.io/Jtz1I
|
||||||
// @route(get_login_info)
|
// @route11(get_login_info)
|
||||||
|
// @route12(get_self_info)
|
||||||
func (bot *CQBot) CQGetLoginInfo() global.MSG {
|
func (bot *CQBot) CQGetLoginInfo() global.MSG {
|
||||||
return OK(global.MSG{"user_id": bot.Client.Uin, "nickname": bot.Client.Nickname})
|
return OK(global.MSG{"user_id": bot.Client.Uin, "nickname": bot.Client.Nickname})
|
||||||
}
|
}
|
||||||
@ -655,7 +656,7 @@ func (bot *CQBot) CQGroupFileDeleteFile(groupID int64, id string, busID int32) g
|
|||||||
//
|
//
|
||||||
// https://docs.go-cqhttp.org/api/#%E8%8E%B7%E5%8F%96%E4%B8%AD%E6%96%87%E5%88%86%E8%AF%8D-%E9%9A%90%E8%97%8F-api
|
// https://docs.go-cqhttp.org/api/#%E8%8E%B7%E5%8F%96%E4%B8%AD%E6%96%87%E5%88%86%E8%AF%8D-%E9%9A%90%E8%97%8F-api
|
||||||
// @route(.get_word_slices)
|
// @route(.get_word_slices)
|
||||||
func (bot *CQBot) CQGetWordSlices(content string) global.MSG {
|
func (bot *CQBot) CQGetWordSlices(content string, version uint16) global.MSG {
|
||||||
slices, err := bot.Client.GetWordSegmentation(content)
|
slices, err := bot.Client.GetWordSegmentation(content)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return Failed(100, "WORD_SEGMENTATION_API_ERROR", err.Error())
|
return Failed(100, "WORD_SEGMENTATION_API_ERROR", err.Error())
|
||||||
@ -1342,7 +1343,8 @@ func (bot *CQBot) CQGetGroupHonorInfo(groupID int64, t string) global.MSG {
|
|||||||
// CQGetStrangerInfo 获取陌生人信息
|
// CQGetStrangerInfo 获取陌生人信息
|
||||||
//
|
//
|
||||||
// https://git.io/Jtz17
|
// https://git.io/Jtz17
|
||||||
// @route(get_stranger_info)
|
// @route11(get_stranger_info)
|
||||||
|
// @route12(get_user_info)
|
||||||
func (bot *CQBot) CQGetStrangerInfo(userID int64) global.MSG {
|
func (bot *CQBot) CQGetStrangerInfo(userID int64) global.MSG {
|
||||||
info, err := bot.Client.GetSummaryInfo(userID)
|
info, err := bot.Client.GetSummaryInfo(userID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -1755,7 +1757,7 @@ func (bot *CQBot) CQGetOnlineClients(noCache bool) global.MSG {
|
|||||||
// CQCanSendImage 检查是否可以发送图片(此处永远返回true)
|
// CQCanSendImage 检查是否可以发送图片(此处永远返回true)
|
||||||
//
|
//
|
||||||
// https://git.io/Jtz1N
|
// https://git.io/Jtz1N
|
||||||
// @route(can_send_image)
|
// @route11(can_send_image)
|
||||||
func (bot *CQBot) CQCanSendImage() global.MSG {
|
func (bot *CQBot) CQCanSendImage() global.MSG {
|
||||||
return OK(global.MSG{"yes": true})
|
return OK(global.MSG{"yes": true})
|
||||||
}
|
}
|
||||||
@ -1763,7 +1765,7 @@ func (bot *CQBot) CQCanSendImage() global.MSG {
|
|||||||
// CQCanSendRecord 检查是否可以发送语音(此处永远返回true)
|
// CQCanSendRecord 检查是否可以发送语音(此处永远返回true)
|
||||||
//
|
//
|
||||||
// https://git.io/Jtz1x
|
// https://git.io/Jtz1x
|
||||||
// @route(can_send_record)
|
// @route11(can_send_record)
|
||||||
func (bot *CQBot) CQCanSendRecord() global.MSG {
|
func (bot *CQBot) CQCanSendRecord() global.MSG {
|
||||||
return OK(global.MSG{"yes": true})
|
return OK(global.MSG{"yes": true})
|
||||||
}
|
}
|
||||||
@ -1831,7 +1833,8 @@ func (bot *CQBot) CQSetGroupAnonymousBan(groupID int64, flag string, duration in
|
|||||||
//
|
//
|
||||||
// https://git.io/JtzMe
|
// https://git.io/JtzMe
|
||||||
// @route(get_status)
|
// @route(get_status)
|
||||||
func (bot *CQBot) CQGetStatus() global.MSG {
|
func (bot *CQBot) CQGetStatus(version uint16) global.MSG {
|
||||||
|
if version == 11 {
|
||||||
return OK(global.MSG{
|
return OK(global.MSG{
|
||||||
"app_initialized": true,
|
"app_initialized": true,
|
||||||
"app_enabled": true,
|
"app_enabled": true,
|
||||||
@ -1842,6 +1845,12 @@ func (bot *CQBot) CQGetStatus() global.MSG {
|
|||||||
"stat": bot.Client.GetStatistics(),
|
"stat": bot.Client.GetStatistics(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
return OK(global.MSG{
|
||||||
|
"online": bot.Client.Online.Load(),
|
||||||
|
"good": bot.Client.Online.Load(),
|
||||||
|
"stat": bot.Client.GetStatistics(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// CQSetEssenceMessage 扩展API-设置精华消息
|
// CQSetEssenceMessage 扩展API-设置精华消息
|
||||||
//
|
//
|
||||||
@ -1917,7 +1926,7 @@ func (bot *CQBot) CQCheckURLSafely(url string) global.MSG {
|
|||||||
// CQGetVersionInfo 获取版本信息
|
// CQGetVersionInfo 获取版本信息
|
||||||
//
|
//
|
||||||
// https://git.io/JtwUs
|
// https://git.io/JtwUs
|
||||||
// @route(get_version_info)
|
// @route11(get_version_info)
|
||||||
func (bot *CQBot) CQGetVersionInfo() global.MSG {
|
func (bot *CQBot) CQGetVersionInfo() global.MSG {
|
||||||
wd, _ := os.Getwd()
|
wd, _ := os.Getwd()
|
||||||
return OK(global.MSG{
|
return OK(global.MSG{
|
||||||
@ -2044,7 +2053,7 @@ func (bot *CQBot) CQReloadEventFilter(file string) global.MSG {
|
|||||||
|
|
||||||
// OK 生成成功返回值
|
// OK 生成成功返回值
|
||||||
func OK(data interface{}) global.MSG {
|
func OK(data interface{}) global.MSG {
|
||||||
return global.MSG{"data": data, "retcode": 0, "status": "ok"}
|
return global.MSG{"data": data, "retcode": 0, "status": "ok", "message": ""}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Failed 生成失败返回值
|
// Failed 生成失败返回值
|
||||||
@ -2056,7 +2065,7 @@ func Failed(code int, msg ...string) global.MSG {
|
|||||||
if len(msg) > 1 {
|
if len(msg) > 1 {
|
||||||
w = msg[1]
|
w = msg[1]
|
||||||
}
|
}
|
||||||
return global.MSG{"data": nil, "retcode": code, "msg": m, "wording": w, "status": "failed"}
|
return global.MSG{"data": nil, "retcode": code, "msg": m, "wording": w, "message": w, "status": "failed"}
|
||||||
}
|
}
|
||||||
|
|
||||||
func limitedString(str string) string {
|
func limitedString(str string) string {
|
||||||
|
23
coolq/api_v12.go
Normal file
23
coolq/api_v12.go
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
package coolq
|
||||||
|
|
||||||
|
import (
|
||||||
|
"runtime"
|
||||||
|
|
||||||
|
"github.com/Mrs4s/go-cqhttp/global"
|
||||||
|
"github.com/Mrs4s/go-cqhttp/internal/base"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CQGetVersion 获取版本信息 OneBotV12
|
||||||
|
//
|
||||||
|
// https://git.io/JtwUs
|
||||||
|
// @route12(get_version)
|
||||||
|
func (bot *CQBot) CQGetVersion() global.MSG {
|
||||||
|
return OK(global.MSG{
|
||||||
|
"impl": "go_cqhttp",
|
||||||
|
"platform": "qq",
|
||||||
|
"version": base.Version,
|
||||||
|
"onebot_version": 12,
|
||||||
|
"runtime_version": runtime.Version(),
|
||||||
|
"runtime_os": runtime.GOOS,
|
||||||
|
})
|
||||||
|
}
|
@ -111,7 +111,7 @@ func NewQQBot(cli *client.QQClient) *CQBot {
|
|||||||
for {
|
for {
|
||||||
<-t.C
|
<-t.C
|
||||||
bot.dispatchEvent("meta_event/heartbeat", global.MSG{
|
bot.dispatchEvent("meta_event/heartbeat", global.MSG{
|
||||||
"status": bot.CQGetStatus()["data"],
|
"status": bot.CQGetStatus(11)["data"],
|
||||||
"interval": base.HeartbeatInterval.Milliseconds(),
|
"interval": base.HeartbeatInterval.Milliseconds(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -7,13 +7,40 @@ import (
|
|||||||
"github.com/Mrs4s/go-cqhttp/global"
|
"github.com/Mrs4s/go-cqhttp/global"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (c *Caller) call(action string, p Getter) global.MSG {
|
func (c *Caller) call(action string, version uint16, p Getter) global.MSG {
|
||||||
|
if version == 12 {
|
||||||
|
if action == "get_supported_actions" {
|
||||||
|
return coolq.OK([]string{".get_word_slices", ".handle_quick_operation", ".ocr_image", "ocr_image", "_get_group_notice", "_get_model_show", "_send_group_notice", "_set_model_show", "check_url_safely", "create_group_file_folder", "create_guild_role", "delete_essence_msg", "delete_friend", "delete_group_file", "delete_group_folder", "delete_guild_role", "delete_msg", "delete_unidirectional_friend", "download_file", "get_essence_msg_list", "get_forward_msg", "get_friend_list", "get_group_at_all_remain", "get_group_file_system_info", "get_group_file_url", "get_group_files_by_folder", "get_group_honor_info", "get_group_info", "get_group_list", "get_group_member_info", "get_group_member_list", "get_group_msg_history", "get_group_root_files", "get_group_system_msg", "get_guild_channel_list", "get_guild_list", "get_guild_member_list", "get_guild_member_profile", "get_guild_meta_by_guest", "get_guild_msg", "get_guild_roles", "get_guild_service_profile", "get_image", "get_self_info", "get_msg", "get_online_clients", "get_status", "get_user_info", "get_topic_channel_feeds", "get_unidirectional_friend_list", "get_version", "mark_msg_as_read", "qidian_get_account_info", "reload_event_filter", "send_forward_msg", "send_group_forward_msg", "send_group_msg", "send_group_sign", "send_guild_channel_msg", "send_msg", "send_private_forward_msg", "send_private_msg", "set_essence_msg", "set_friend_add_request", "set_group_add_request", "set_group_admin", "set_group_anonymous_ban", "set_group_ban", "set_group_card", "set_group_kick", "set_group_leave", "set_group_name", "set_group_portrait", "set_group_special_title", "set_group_whole_ban", "set_guild_member_role", "set_qq_profile", "update_guild_role", "upload_group_file"})
|
||||||
|
}
|
||||||
|
switch action {
|
||||||
|
case "get_self_info":
|
||||||
|
return c.bot.CQGetLoginInfo()
|
||||||
|
case "get_user_info":
|
||||||
|
p0 := p.Get("user_id").Int()
|
||||||
|
return c.bot.CQGetStrangerInfo(p0)
|
||||||
|
case "get_version":
|
||||||
|
return c.bot.CQGetVersion()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if version == 11 {
|
||||||
|
switch action {
|
||||||
|
case "can_send_image":
|
||||||
|
return c.bot.CQCanSendImage()
|
||||||
|
case "can_send_record":
|
||||||
|
return c.bot.CQCanSendRecord()
|
||||||
|
case "get_login_info":
|
||||||
|
return c.bot.CQGetLoginInfo()
|
||||||
|
case "get_stranger_info":
|
||||||
|
p0 := p.Get("user_id").Int()
|
||||||
|
return c.bot.CQGetStrangerInfo(p0)
|
||||||
|
case "get_version_info":
|
||||||
|
return c.bot.CQGetVersionInfo()
|
||||||
|
}
|
||||||
|
}
|
||||||
switch action {
|
switch action {
|
||||||
default:
|
|
||||||
return coolq.Failed(404, "API_NOT_FOUND", "API不存在")
|
|
||||||
case ".get_word_slices":
|
case ".get_word_slices":
|
||||||
p0 := p.Get("content").String()
|
p0 := p.Get("content").String()
|
||||||
return c.bot.CQGetWordSlices(p0)
|
return c.bot.CQGetWordSlices(p0, version)
|
||||||
case ".handle_quick_operation":
|
case ".handle_quick_operation":
|
||||||
p0 := p.Get("context")
|
p0 := p.Get("context")
|
||||||
p1 := p.Get("operation")
|
p1 := p.Get("operation")
|
||||||
@ -36,10 +63,6 @@ func (c *Caller) call(action string, p Getter) global.MSG {
|
|||||||
p0 := p.Get("model").String()
|
p0 := p.Get("model").String()
|
||||||
p1 := p.Get("model_show").String()
|
p1 := p.Get("model_show").String()
|
||||||
return c.bot.CQSetModelShow(p0, p1)
|
return c.bot.CQSetModelShow(p0, p1)
|
||||||
case "can_send_image":
|
|
||||||
return c.bot.CQCanSendImage()
|
|
||||||
case "can_send_record":
|
|
||||||
return c.bot.CQCanSendRecord()
|
|
||||||
case "check_url_safely":
|
case "check_url_safely":
|
||||||
p0 := p.Get("url").String()
|
p0 := p.Get("url").String()
|
||||||
return c.bot.CQCheckURLSafely(p0)
|
return c.bot.CQCheckURLSafely(p0)
|
||||||
@ -166,8 +189,6 @@ func (c *Caller) call(action string, p Getter) global.MSG {
|
|||||||
case "get_image":
|
case "get_image":
|
||||||
p0 := p.Get("file").String()
|
p0 := p.Get("file").String()
|
||||||
return c.bot.CQGetImage(p0)
|
return c.bot.CQGetImage(p0)
|
||||||
case "get_login_info":
|
|
||||||
return c.bot.CQGetLoginInfo()
|
|
||||||
case "get_msg":
|
case "get_msg":
|
||||||
p0 := int32(p.Get("message_id").Int())
|
p0 := int32(p.Get("message_id").Int())
|
||||||
return c.bot.CQGetMessage(p0)
|
return c.bot.CQGetMessage(p0)
|
||||||
@ -175,18 +196,13 @@ func (c *Caller) call(action string, p Getter) global.MSG {
|
|||||||
p0 := p.Get("no_cache").Bool()
|
p0 := p.Get("no_cache").Bool()
|
||||||
return c.bot.CQGetOnlineClients(p0)
|
return c.bot.CQGetOnlineClients(p0)
|
||||||
case "get_status":
|
case "get_status":
|
||||||
return c.bot.CQGetStatus()
|
return c.bot.CQGetStatus(version)
|
||||||
case "get_stranger_info":
|
|
||||||
p0 := p.Get("user_id").Int()
|
|
||||||
return c.bot.CQGetStrangerInfo(p0)
|
|
||||||
case "get_topic_channel_feeds":
|
case "get_topic_channel_feeds":
|
||||||
p0 := p.Get("guild_id").Uint()
|
p0 := p.Get("guild_id").Uint()
|
||||||
p1 := p.Get("channel_id").Uint()
|
p1 := p.Get("channel_id").Uint()
|
||||||
return c.bot.CQGetTopicChannelFeeds(p0, p1)
|
return c.bot.CQGetTopicChannelFeeds(p0, p1)
|
||||||
case "get_unidirectional_friend_list":
|
case "get_unidirectional_friend_list":
|
||||||
return c.bot.CQGetUnidirectionalFriendList()
|
return c.bot.CQGetUnidirectionalFriendList()
|
||||||
case "get_version_info":
|
|
||||||
return c.bot.CQGetVersionInfo()
|
|
||||||
case "mark_msg_as_read":
|
case "mark_msg_as_read":
|
||||||
p0 := int32(p.Get("message_id").Int())
|
p0 := int32(p.Get("message_id").Int())
|
||||||
return c.bot.CQMarkMessageAsRead(p0)
|
return c.bot.CQMarkMessageAsRead(p0)
|
||||||
@ -338,4 +354,5 @@ func (c *Caller) call(action string, p Getter) global.MSG {
|
|||||||
p3 := p.Get("folder").String()
|
p3 := p.Get("folder").String()
|
||||||
return c.bot.CQUploadGroupFile(p0, p1, p2, p3)
|
return c.bot.CQUploadGroupFile(p0, p1, p2, p3)
|
||||||
}
|
}
|
||||||
|
return coolq.Failed(404, "API_NOT_FOUND", "API不存在")
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ import (
|
|||||||
"github.com/Mrs4s/go-cqhttp/global"
|
"github.com/Mrs4s/go-cqhttp/global"
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:generate go run github.com/Mrs4s/go-cqhttp/cmd/api-generator -path=./../../coolq/api.go
|
//go:generate go run github.com/Mrs4s/go-cqhttp/cmd/api-generator -path=./../../coolq/api.go,./../../coolq/api_v12.go
|
||||||
|
|
||||||
// Getter 参数获取
|
// Getter 参数获取
|
||||||
type Getter interface {
|
type Getter interface {
|
||||||
@ -25,13 +25,13 @@ type Caller struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Call specific API
|
// Call specific API
|
||||||
func (c *Caller) Call(action string, p Getter) global.MSG {
|
func (c *Caller) Call(action string, version uint16, p Getter) global.MSG {
|
||||||
for _, fn := range c.handlers {
|
for _, fn := range c.handlers {
|
||||||
if ret := fn(action, p); ret != nil {
|
if ret := fn(action, p); ret != nil {
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return c.call(action, p)
|
return c.call(action, version, p)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use add handlers to the API caller
|
// Use add handlers to the API caller
|
||||||
|
@ -34,6 +34,7 @@ import (
|
|||||||
// HTTPServer HTTP通信相关配置
|
// HTTPServer HTTP通信相关配置
|
||||||
type HTTPServer struct {
|
type HTTPServer struct {
|
||||||
Disabled bool `yaml:"disabled"`
|
Disabled bool `yaml:"disabled"`
|
||||||
|
Version uint16 `yaml:"version"`
|
||||||
Address string `yaml:"address"`
|
Address string `yaml:"address"`
|
||||||
Host string `yaml:"host"`
|
Host string `yaml:"host"`
|
||||||
Port int `yaml:"port"`
|
Port int `yaml:"port"`
|
||||||
@ -57,6 +58,7 @@ type httpServerPost struct {
|
|||||||
type httpServer struct {
|
type httpServer struct {
|
||||||
api *api.Caller
|
api *api.Caller
|
||||||
accessToken string
|
accessToken string
|
||||||
|
version uint16
|
||||||
}
|
}
|
||||||
|
|
||||||
// HTTPClient 反向HTTP上报客户端
|
// HTTPClient 反向HTTP上报客户端
|
||||||
@ -81,6 +83,7 @@ type httpCtx struct {
|
|||||||
const httpDefault = `
|
const httpDefault = `
|
||||||
- http: # HTTP 通信设置
|
- http: # HTTP 通信设置
|
||||||
address: 0.0.0.0:5700 # HTTP监听地址
|
address: 0.0.0.0:5700 # HTTP监听地址
|
||||||
|
version: 11 # OneBot协议版本, 支持 11/12
|
||||||
timeout: 5 # 反向 HTTP 超时时间, 单位秒,<5 时将被忽略
|
timeout: 5 # 反向 HTTP 超时时间, 单位秒,<5 时将被忽略
|
||||||
long-polling: # 长轮询拓展
|
long-polling: # 长轮询拓展
|
||||||
enabled: false # 是否开启
|
enabled: false # 是否开启
|
||||||
@ -150,6 +153,13 @@ func (s *httpServer) ServeHTTP(writer http.ResponseWriter, request *http.Request
|
|||||||
contentType := request.Header.Get("Content-Type")
|
contentType := request.Header.Get("Content-Type")
|
||||||
switch request.Method {
|
switch request.Method {
|
||||||
case http.MethodPost:
|
case http.MethodPost:
|
||||||
|
// todo: msg pack
|
||||||
|
if s.version == 12 && strings.Contains(contentType, "application/msgpack") {
|
||||||
|
log.Warnf("请求 %v 数据类型暂不支持: MsgPack", request.RequestURI)
|
||||||
|
writer.WriteHeader(http.StatusUnsupportedMediaType)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if strings.Contains(contentType, "application/json") {
|
if strings.Contains(contentType, "application/json") {
|
||||||
body, err := io.ReadAll(request.Body)
|
body, err := io.ReadAll(request.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -190,12 +200,12 @@ func (s *httpServer) ServeHTTP(writer http.ResponseWriter, request *http.Request
|
|||||||
if request.URL.Path == "/" {
|
if request.URL.Path == "/" {
|
||||||
action := strings.TrimSuffix(ctx.Get("action").Str, "_async")
|
action := strings.TrimSuffix(ctx.Get("action").Str, "_async")
|
||||||
log.Debugf("HTTPServer接收到API调用: %v", action)
|
log.Debugf("HTTPServer接收到API调用: %v", action)
|
||||||
response = s.api.Call(action, ctx.Get("params"))
|
response = s.api.Call(action, s.version, ctx.Get("params"))
|
||||||
} else {
|
} else {
|
||||||
action := strings.TrimPrefix(request.URL.Path, "/")
|
action := strings.TrimPrefix(request.URL.Path, "/")
|
||||||
action = strings.TrimSuffix(action, "_async")
|
action = strings.TrimSuffix(action, "_async")
|
||||||
log.Debugf("HTTPServer接收到API调用: %v", action)
|
log.Debugf("HTTPServer接收到API调用: %v", action)
|
||||||
response = s.api.Call(action, &ctx)
|
response = s.api.Call(action, s.version, &ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.Header().Set("Content-Type", "application/json; charset=utf-8")
|
writer.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||||
@ -245,9 +255,11 @@ func runHTTP(bot *coolq.CQBot, node yaml.Node) {
|
|||||||
case conf.Disabled:
|
case conf.Disabled:
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if conf.Version != 11 && conf.Version != 12 {
|
||||||
|
conf.Version = 11
|
||||||
|
}
|
||||||
network, addr := "tcp", conf.Address
|
network, addr := "tcp", conf.Address
|
||||||
s := &httpServer{accessToken: conf.AccessToken}
|
s := &httpServer{accessToken: conf.AccessToken, version: conf.Version}
|
||||||
switch {
|
switch {
|
||||||
case conf.Address != "":
|
case conf.Address != "":
|
||||||
uri, err := url.Parse(conf.Address)
|
uri, err := url.Parse(conf.Address)
|
||||||
|
@ -470,7 +470,7 @@ func (c *wsConn) handleRequest(_ *coolq.CQBot, payload []byte) {
|
|||||||
j := gjson.Parse(utils.B2S(payload))
|
j := gjson.Parse(utils.B2S(payload))
|
||||||
t := strings.TrimSuffix(j.Get("action").Str, "_async")
|
t := strings.TrimSuffix(j.Get("action").Str, "_async")
|
||||||
log.Debugf("WS接收到API调用: %v 参数: %v", t, j.Get("params").Raw)
|
log.Debugf("WS接收到API调用: %v 参数: %v", t, j.Get("params").Raw)
|
||||||
ret := c.apiCaller.Call(t, j.Get("params"))
|
ret := c.apiCaller.Call(t, 11, j.Get("params"))
|
||||||
if j.Get("echo").Exists() {
|
if j.Get("echo").Exists() {
|
||||||
ret["echo"] = j.Get("echo").Value()
|
ret["echo"] = j.Get("echo").Value()
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user