diff --git a/coolq/api.go b/coolq/api.go index a291ea2..1c87d76 100644 --- a/coolq/api.go +++ b/coolq/api.go @@ -1,11 +1,13 @@ package coolq import ( + "fmt" "github.com/Mrs4s/MiraiGo/binary" "github.com/Mrs4s/MiraiGo/client" "github.com/Mrs4s/MiraiGo/message" "github.com/Mrs4s/go-cqhttp/global" log "github.com/sirupsen/logrus" + "github.com/tidwall/gjson" "io/ioutil" "os" "path" @@ -232,6 +234,63 @@ func (bot *CQBot) CQDeleteMessage(messageId int32) MSG { return OK(nil) } +// https://cqhttp.cc/docs/4.15/#/API?id=-handle_quick_operation-%E5%AF%B9%E4%BA%8B%E4%BB%B6%E6%89%A7%E8%A1%8C%E5%BF%AB%E9%80%9F%E6%93%8D%E4%BD%9C +// https://github.com/richardchien/coolq-http-api/blob/master/src/cqhttp/plugins/web/http.cpp#L376 +func (bot *CQBot) CQHandleQuickOperation(context, operation gjson.Result) MSG { + postType := context.Get("post_type").Str + switch postType { + case "message": + msgType := context.Get("message_type").Str + reply := operation.Get("reply").Str + if reply != "" { + at := true + if operation.Get("at_sender").Exists() { + at = operation.Get("at_sender").Bool() + } + if msgType == "group" && at { + if at { + reply = fmt.Sprintf("[CQ:at,qq=%d]%s", context.Get("user_id").Int(), reply) + } + bot.CQSendGroupMessage(context.Get("group_id").Int(), reply) + } + if msgType == "private" { + bot.CQSendPrivateMessage(context.Get("user_id").Int(), reply) + } + } + if msgType == "group" { + anonymous := context.Get("anonymous") + isAnonymous := anonymous.Type == gjson.Null + if operation.Get("delete").Bool() { + bot.CQDeleteMessage(int32(context.Get("message_id").Int())) + } + if operation.Get("kick").Bool() && !isAnonymous { + bot.CQSetGroupKick(context.Get("group_id").Int(), context.Get("user_id").Int(), "") + } + if operation.Get("ban").Bool() { + var duration uint32 = 30 * 60 + if operation.Get("ban_duration").Exists() { + duration = uint32(operation.Get("ban_duration").Uint()) + } + // unsupported anonymous ban yet + if !isAnonymous { + bot.CQSetGroupBan(context.Get("group_id").Int(), context.Get("user_id").Int(), duration) + } + } + } + case "request": + reqType := context.Get("request_type").Str + if context.Get("approve").Bool() { + if reqType == "friend" { + bot.CQProcessFriendRequest(context.Get("flag").Str, true) + } + if reqType == "group" { + bot.CQProcessGroupRequest(context.Get("flag").Str, context.Get("sub_type").Str, true) + } + } + } + return OK(nil) +} + func (bot *CQBot) CQGetImage(file string) MSG { if !global.PathExists(path.Join(global.IMAGE_PATH, file)) { return Failed(100) diff --git a/server/http.go b/server/http.go index 208ab39..5177a85 100644 --- a/server/http.go +++ b/server/http.go @@ -142,6 +142,8 @@ func (s *httpServer) Run(addr, authToken string, bot *coolq.CQBot) { s.engine.Any("/get_version_info", s.GetVersionInfo) s.engine.Any("/get_version_info_async", s.GetVersionInfo) + s.engine.Any("/.handle_quick_operation", s.HandleQuickOperation) + go func() { log.Infof("CQ HTTP 服务器已启动: %v", addr) log.Fatal(s.engine.Run(addr)) @@ -161,7 +163,8 @@ func (c *httpClient) Run(addr, secret string, bot *coolq.CQBot) { } func (c *httpClient) onBotPushEvent(m coolq.MSG) { - err := gout.POST(c.addr).SetJSON(m).SetHeader(func() gout.H { + var res string + err := gout.POST(c.addr).SetJSON(m).BindBody(&res).SetHeader(func() gout.H { h := gout.H{ "X-Self_ID": c.bot.Client.Uin, "X-Client-Role": "Universal", @@ -176,6 +179,10 @@ func (c *httpClient) onBotPushEvent(m coolq.MSG) { }()).SetTimeout(time.Second * 5).Do() if err != nil { log.Warnf("上报Event数据到 %v 失败: %v", c.addr, err) + return + } + if gjson.Valid(res) { + c.bot.CQHandleQuickOperation(gjson.Parse(m.ToJson()), gjson.Parse(res)) } } @@ -278,8 +285,8 @@ func (s *httpServer) SetGroupKick(c *gin.Context) { func (s *httpServer) SetGroupBan(c *gin.Context) { gid, _ := strconv.ParseInt(getParam(c, "group_id"), 10, 64) uid, _ := strconv.ParseInt(getParam(c, "user_id"), 10, 64) - time, _ := strconv.ParseInt(getParam(c, "duration"), 10, 64) - c.JSON(200, s.bot.CQSetGroupBan(gid, uid, uint32(time))) + i, _ := strconv.ParseInt(getParam(c, "duration"), 10, 64) + c.JSON(200, s.bot.CQSetGroupBan(gid, uid, uint32(i))) } func (s *httpServer) SetWholeBan(c *gin.Context) { @@ -313,6 +320,17 @@ func (s *httpServer) GetVersionInfo(c *gin.Context) { c.JSON(200, s.bot.CQGetVersionInfo()) } +func (s *httpServer) HandleQuickOperation(c *gin.Context) { + if c.Request.Method != "POST" { + c.AbortWithStatus(404) + return + } + if i, ok := c.Get("json_body"); ok { + body := i.(gjson.Result) + c.JSON(200, s.bot.CQHandleQuickOperation(body.Get("context"), body.Get("operation"))) + } +} + func getParamOrDefault(c *gin.Context, k, def string) string { r := getParam(c, k) if r != "" { diff --git a/server/websocket.go b/server/websocket.go index 45ad310..2e5c2da 100644 --- a/server/websocket.go +++ b/server/websocket.go @@ -238,4 +238,7 @@ var wsApi = map[string]func(*coolq.CQBot, gjson.Result) string{ "get_version_info": func(bot *coolq.CQBot, p gjson.Result) string { return bot.CQGetVersionInfo().ToJson() }, + ".handle_quick_operation": func(bot *coolq.CQBot, p gjson.Result) string { + return bot.CQHandleQuickOperation(p.Get("context"), p.Get("operation")).ToJson() + }, }