1
0
mirror of https://github.com/Mrs4s/go-cqhttp.git synced 2025-05-05 03:23:49 +08:00

http post supported.

This commit is contained in:
Mrs4s 2020-07-23 20:58:17 +08:00
parent 2c8d941cee
commit 82e2ea8466
9 changed files with 94 additions and 25 deletions

View File

@ -4,7 +4,7 @@
# 兼容性
#### 接口
- [x] HTTP API
- [ ] 反向HTTP POST (开发中)
- [x] 反向HTTP POST (暂不支持回复)
- [x] 正向Websocket
- [ ] 反向Websocket (开发中)
#### 实现

View File

@ -19,7 +19,7 @@ import (
type CQBot struct {
Client *client.QQClient
events []func(string)
events []func(MSG)
db *nutsdb.DB
friendReqCache sync.Map
invitedReqCache sync.Map
@ -62,7 +62,7 @@ func NewQQBot(cli *client.QQClient, conf *global.JsonConfig) *CQBot {
return bot
}
func (bot *CQBot) OnEventPush(f func(m string)) {
func (bot *CQBot) OnEventPush(f func(m MSG)) {
bot.events = append(bot.events, f)
}
@ -157,7 +157,7 @@ func (bot *CQBot) Release() {
_ = bot.db.Close()
}
func (bot *CQBot) dispatchEventMessage(m string) {
func (bot *CQBot) dispatchEventMessage(m MSG) {
for _, f := range bot.events {
f(m)
}

View File

@ -35,7 +35,7 @@ func (bot *CQBot) privateMessageEvent(c *client.QQClient, m *message.PrivateMess
"age": 0,
},
}
bot.dispatchEventMessage(fm.ToJson())
bot.dispatchEventMessage(fm)
}
func (bot *CQBot) groupMessageEvent(c *client.QQClient, m *message.GroupMessage) {
@ -92,7 +92,7 @@ func (bot *CQBot) groupMessageEvent(c *client.QQClient, m *message.GroupMessage)
ms["card"] = mem.CardName
ms["title"] = mem.SpecialTitle
}
bot.dispatchEventMessage(gm.ToJson())
bot.dispatchEventMessage(gm)
}
func (bot *CQBot) tempMessageEvent(c *client.QQClient, m *message.TempMessage) {
@ -117,7 +117,7 @@ func (bot *CQBot) tempMessageEvent(c *client.QQClient, m *message.TempMessage) {
"age": 0,
},
}
bot.dispatchEventMessage(tm.ToJson())
bot.dispatchEventMessage(tm)
}
func (bot *CQBot) groupMutedEvent(c *client.QQClient, e *client.GroupMuteEvent) {
@ -144,7 +144,7 @@ func (bot *CQBot) groupMutedEvent(c *client.QQClient, e *client.GroupMuteEvent)
}
return "lift_ban"
}(),
}.ToJson())
})
}
func (bot *CQBot) groupRecallEvent(c *client.QQClient, e *client.GroupMessageRecalledEvent) {
@ -161,7 +161,7 @@ func (bot *CQBot) groupRecallEvent(c *client.QQClient, e *client.GroupMessageRec
"operator_id": e.OperatorUin,
"time": e.Time,
"message_id": gid,
}.ToJson())
})
}
func (bot *CQBot) joinGroupEvent(c *client.QQClient, group *client.GroupInfo) {
@ -193,7 +193,7 @@ func (bot *CQBot) memberPermissionChangedEvent(c *client.QQClient, e *client.Mem
"user_id": e.Member.Uin,
"time": time.Now().Unix(),
"self_id": c.Uin,
}.ToJson())
})
}
func (bot *CQBot) memberJoinEvent(c *client.QQClient, e *client.MemberJoinGroupEvent) {
@ -222,7 +222,7 @@ func (bot *CQBot) friendRequestEvent(c *client.QQClient, e *client.NewFriendRequ
"flag": flag,
"time": time.Now().Unix(),
"self_id": c.Uin,
}.ToJson())
})
}
func (bot *CQBot) groupInvitedEvent(c *client.QQClient, e *client.GroupInvitedRequest) {
@ -239,7 +239,7 @@ func (bot *CQBot) groupInvitedEvent(c *client.QQClient, e *client.GroupInvitedRe
"flag": flag,
"time": time.Now().Unix(),
"self_id": c.Uin,
}.ToJson())
})
}
func (bot *CQBot) groupJoinReqEvent(c *client.QQClient, e *client.UserJoinGroupRequest) {
@ -256,10 +256,10 @@ func (bot *CQBot) groupJoinReqEvent(c *client.QQClient, e *client.UserJoinGroupR
"flag": flag,
"time": time.Now().Unix(),
"self_id": c.Uin,
}.ToJson())
})
}
func (bot *CQBot) groupIncrease(groupCode, operatorUin, userUin int64) string {
func (bot *CQBot) groupIncrease(groupCode, operatorUin, userUin int64) MSG {
return MSG{
"post_type": "notice",
"notice_type": "group_increase",
@ -269,10 +269,10 @@ func (bot *CQBot) groupIncrease(groupCode, operatorUin, userUin int64) string {
"sub_type": "approve",
"time": time.Now().Unix(),
"user_id": userUin,
}.ToJson()
}
}
func (bot *CQBot) groupDecrease(groupCode, userUin int64, operator *client.GroupMemberInfo) string {
func (bot *CQBot) groupDecrease(groupCode, userUin int64, operator *client.GroupMemberInfo) MSG {
return MSG{
"post_type": "notice",
"notice_type": "group_decrease",
@ -295,7 +295,7 @@ func (bot *CQBot) groupDecrease(groupCode, userUin int64, operator *client.Group
}(),
"time": time.Now().Unix(),
"user_id": userUin,
}.ToJson()
}
}
func checkImage(e []message.IMessageElement) {

View File

@ -39,6 +39,7 @@ type GoCQHttpConfig struct {
Enabled bool `json:"enabled"`
Host string `json:"host"`
Port uint16 `json:"port"`
PostUrls map[string]string `json:"post_urls"`
}
type GoCQWebsocketConfig struct {
@ -54,6 +55,7 @@ func DefaultConfig() *JsonConfig {
Enabled: true,
Host: "0.0.0.0",
Port: 5700,
PostUrls: map[string]string{},
},
WSConfig: &GoCQWebsocketConfig{
Enabled: true,

1
go.mod
View File

@ -6,6 +6,7 @@ require (
github.com/Mrs4s/MiraiGo v0.0.0-20200721195252-2accd73f8b8e
github.com/gin-gonic/gin v1.6.3
github.com/gorilla/websocket v1.4.2
github.com/guonaihong/gout v0.1.1
github.com/lestrrat-go/file-rotatelogs v2.3.0+incompatible
github.com/lestrrat-go/strftime v1.0.1 // indirect
github.com/pkg/errors v0.9.1 // indirect

14
go.sum
View File

@ -24,11 +24,14 @@ github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.m
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-gonic/gin v1.5.0/go.mod h1:Nd6IXA8m5kNZdNEHMBd93KT+mdY3+bewLgRvmCsR2Do=
github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14=
github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.12.1/go.mod h1:IUMDtCfWo/w/mtMfIE/IG2K+Ey3ygWanZIBtBW0W2TM=
github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
github.com/go-playground/universal-translator v0.16.0/go.mod h1:1AnU7NaIRDWWzGEKwgtJRd2xk99HeFyHw3yid4rvQIY=
github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no=
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
github.com/go-playground/validator/v10 v10.2.0 h1:KgJ0snyC2R9VXYN2rneOtQcw5aHQB1Vv0sFl1UcHBOY=
@ -53,13 +56,18 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/guonaihong/gout v0.1.1 h1:2i3eqQ1KUhTlj7AFeIHqVUFku5QwUhwE2wNgYTVpbxQ=
github.com/guonaihong/gout v0.1.1/go.mod h1:vXvv5Kxr70eM5wrp4F0+t9lnLWmq+YPW2GByll2f/EA=
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8=
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/leodido/go-urn v1.1.0/go.mod h1:+cyI34gQWZcE1eQU7NVgKkkzdXDQHr1dBMtdAPozLkw=
github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
github.com/lestrrat-go/envload v0.0.0-20180220234015-a3eb8ddeffcc/go.mod h1:kopuH9ugFRkIXf3YoqHKyrJ9YfUFsckUU9S7B+XP+is=
@ -67,6 +75,7 @@ github.com/lestrrat-go/file-rotatelogs v2.3.0+incompatible h1:4mNlp+/SvALIPFpbXV
github.com/lestrrat-go/file-rotatelogs v2.3.0+incompatible/go.mod h1:ZQnN8lSECaebrkQytbHj4xNgtg8CR7RYXnPok8e0EHA=
github.com/lestrrat-go/strftime v1.0.1 h1:o7qz5pmLzPDLyGW4lG6JvTKPUfTFXwe+vOamIYWtnVU=
github.com/lestrrat-go/strftime v1.0.1/go.mod h1:E1nN3pCbtMSu1yjSVeyuRFVm/U0xoR76fd03sz+Qz4g=
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@ -116,6 +125,8 @@ golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73r
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa h1:F+8P+gmewFQYRk6JoLQLwjBCTu3mcIURZfNkVweuRKA=
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@ -124,6 +135,7 @@ golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20181221143128-b4a75ba826a6/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42 h1:vEOn+mP2zCOVzKckCZy6YsCtDblrpj/w7B9nxGNELpg=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae h1:Ih9Yo4hSPImZOpfGuA4bR/ORKTAbhZo2AbWNRCnevdo=
@ -155,6 +167,8 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD
google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE=
gopkg.in/go-playground/validator.v9 v9.29.1/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

View File

@ -53,9 +53,13 @@ func init() {
goConf.HttpConfig.Port = conf.Port
goConf.WSConfig.Host = conf.WSHost
goConf.WSConfig.Port = conf.WSPort
if conf.PostUrl != "" {
goConf.HttpConfig.PostUrls[conf.PostUrl] = conf.Secret
}
if err := goConf.Save("config.json"); err != nil {
log.Fatalf("保存 config.json 时出现错误: %v", err)
}
_ = os.Remove("cqhttp.json")
}
}
@ -126,6 +130,9 @@ func main() {
b := coolq.NewQQBot(cli, conf)
if conf.HttpConfig != nil && conf.HttpConfig.Enabled {
server.HttpServer.Run(fmt.Sprintf("%s:%d", conf.HttpConfig.Host, conf.HttpConfig.Port), conf.AccessToken, b)
for k, v := range conf.HttpConfig.PostUrls {
server.NewClient().Run(k, v, b)
}
}
if conf.WSConfig != nil && conf.WSConfig.Enabled {
server.WebsocketServer.Run(fmt.Sprintf("%s:%d", conf.WSConfig.Host, conf.WSConfig.Port), conf.AccessToken, b)

View File

@ -1,12 +1,17 @@
package server
import (
"crypto/hmac"
"crypto/sha1"
"encoding/hex"
"github.com/Mrs4s/go-cqhttp/coolq"
"github.com/gin-gonic/gin"
"github.com/guonaihong/gout"
log "github.com/sirupsen/logrus"
"github.com/tidwall/gjson"
"strconv"
"strings"
"time"
)
type httpServer struct {
@ -14,6 +19,12 @@ type httpServer struct {
bot *coolq.CQBot
}
type httpClient struct {
bot *coolq.CQBot
secret string
addr string
}
var HttpServer = &httpServer{}
func (s *httpServer) Run(addr, authToken string, bot *coolq.CQBot) {
@ -137,6 +148,37 @@ func (s *httpServer) Run(addr, authToken string, bot *coolq.CQBot) {
}()
}
func NewClient() *httpClient {
return &httpClient{}
}
func (c *httpClient) Run(addr, secret string, bot *coolq.CQBot) {
c.bot = bot
c.secret = secret
c.addr = addr
bot.OnEventPush(c.onBotPushEvent)
log.Infof("HTTP POST上报器已启动: %v", addr)
}
func (c *httpClient) onBotPushEvent(m coolq.MSG) {
err := gout.POST(c.addr).SetJSON(m).SetHeader(func() gout.H {
h := gout.H{
"X-Self_ID": c.bot.Client.Uin,
"X-Client-Role": "Universal",
"User-Agent": "CQHttp/4.15.0",
}
if c.secret != "" {
mac := hmac.New(sha1.New, []byte(c.secret))
mac.Write([]byte(m.ToJson()))
h["X-Signature"] = "sha1=" + hex.EncodeToString(mac.Sum(nil))
}
return h
}()).SetTimeout(time.Second * 5).Do()
if err != nil {
log.Warnf("上报Event数据到 %v 失败: %v", c.addr, err)
}
}
func (s *httpServer) GetLoginInfo(c *gin.Context) {
c.JSON(200, s.bot.CQGetLoginInfo())
}

View File

@ -20,6 +20,9 @@ type websocketServer struct {
handshake string
}
type websocketClient struct {
}
var WebsocketServer = &websocketServer{}
var upgrader = websocket.Upgrader{
CheckOrigin: func(r *http.Request) bool {
@ -119,12 +122,12 @@ func (s *websocketServer) listenApi(c *websocket.Conn) {
}
}
func (s *websocketServer) onBotPushEvent(m string) {
func (s *websocketServer) onBotPushEvent(m coolq.MSG) {
s.pushLock.Lock()
defer s.pushLock.Unlock()
pos := 0
for _, conn := range s.eventConn {
err := conn.WriteMessage(websocket.TextMessage, []byte(m))
err := conn.WriteMessage(websocket.TextMessage, []byte(m.ToJson()))
if err != nil {
_ = conn.Close()
s.eventConn = append(s.eventConn[:pos], s.eventConn[pos+1:]...)