mirror of
https://github.com/Mrs4s/go-cqhttp.git
synced 2025-06-30 20:03:24 +00:00
Compare commits
9 Commits
Author | SHA1 | Date | |
---|---|---|---|
87beb55ca1 | |||
557400b343 | |||
0a6ddb0810 | |||
e6ffa9fbe5 | |||
56ca382a9b | |||
549525236d | |||
f19c76d4e1 | |||
700a056a17 | |||
2a6b9925f8 |
20
README.md
20
README.md
@ -2,17 +2,29 @@
|
|||||||
使用 [mirai](https://github.com/mamoe/mirai) 以及 [MiraiGo](https://github.com/Mrs4s/MiraiGo) 开发的cqhttp golang原生实现, 并在[cqhttp原版](https://github.com/richardchien/coolq-http-api)的基础上做了部分修改和拓展.
|
使用 [mirai](https://github.com/mamoe/mirai) 以及 [MiraiGo](https://github.com/Mrs4s/MiraiGo) 开发的cqhttp golang原生实现, 并在[cqhttp原版](https://github.com/richardchien/coolq-http-api)的基础上做了部分修改和拓展.
|
||||||
文档暂时可查看 `docs` 目录, 目前还在撰写中.
|
文档暂时可查看 `docs` 目录, 目前还在撰写中.
|
||||||
|
|
||||||
|
测试版可前往 Release 下载
|
||||||
|
|
||||||
# 兼容性
|
# 兼容性
|
||||||
|
|
||||||
#### 接口
|
#### 接口
|
||||||
- [x] HTTP API
|
- [x] HTTP API
|
||||||
- [x] 反向HTTP POST (暂不支持回复)
|
- [x] 反向HTTP POST
|
||||||
- [x] 正向Websocket
|
- [x] 正向Websocket
|
||||||
- [ ] 反向Websocket (开发中)
|
- [x] 反向Websocket (测试中)
|
||||||
|
|
||||||
|
#### 拓展支持
|
||||||
|
- [x] HTTP POST多点上报
|
||||||
|
- [x] 反向WS多点连接
|
||||||
|
- [x] 修改群名
|
||||||
|
- [x] 消息撤回事件
|
||||||
|
- [x] 解析/发送 回复消息
|
||||||
|
- [x] 解析合并转发
|
||||||
|
|
||||||
#### 实现
|
#### 实现
|
||||||
<details>
|
<details>
|
||||||
<summary>已实现API</summary>
|
<summary>已实现API</summary>
|
||||||
|
|
||||||
##### 注意: 部分API实现与CQHTTP原版略有差异,请参考WIKI
|
##### 注意: 部分API实现与CQHTTP原版略有差异,请参考文档
|
||||||
| API | 功能 |
|
| API | 功能 |
|
||||||
| ------------------------ | ------------------------------------------------------------ |
|
| ------------------------ | ------------------------------------------------------------ |
|
||||||
| /get_login_info | [获取登录号信息](https://cqhttp.cc/docs/4.15/#/API?id=get_login_info-获取登录号信息) |
|
| /get_login_info | [获取登录号信息](https://cqhttp.cc/docs/4.15/#/API?id=get_login_info-获取登录号信息) |
|
||||||
@ -45,7 +57,7 @@
|
|||||||
<details>
|
<details>
|
||||||
<summary>已实现Event</summary>
|
<summary>已实现Event</summary>
|
||||||
|
|
||||||
##### 注意: 部分Event数据与CQHTTP原版略有差异,请参考WIKI
|
##### 注意: 部分Event数据与CQHTTP原版略有差异,请参考文档
|
||||||
| Event |
|
| Event |
|
||||||
| ------------------------------------------------------------ |
|
| ------------------------------------------------------------ |
|
||||||
| [私聊信息](https://cqhttp.cc/docs/4.15/#/Post?id=私聊消息) |
|
| [私聊信息](https://cqhttp.cc/docs/4.15/#/Post?id=私聊消息) |
|
||||||
|
81
coolq/api.go
81
coolq/api.go
@ -1,11 +1,13 @@
|
|||||||
package coolq
|
package coolq
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"github.com/Mrs4s/MiraiGo/binary"
|
"github.com/Mrs4s/MiraiGo/binary"
|
||||||
"github.com/Mrs4s/MiraiGo/client"
|
"github.com/Mrs4s/MiraiGo/client"
|
||||||
"github.com/Mrs4s/MiraiGo/message"
|
"github.com/Mrs4s/MiraiGo/message"
|
||||||
"github.com/Mrs4s/go-cqhttp/global"
|
"github.com/Mrs4s/go-cqhttp/global"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
|
"github.com/tidwall/gjson"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
@ -232,6 +234,63 @@ func (bot *CQBot) CQDeleteMessage(messageId int32) MSG {
|
|||||||
return OK(nil)
|
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 {
|
func (bot *CQBot) CQGetImage(file string) MSG {
|
||||||
if !global.PathExists(path.Join(global.IMAGE_PATH, file)) {
|
if !global.PathExists(path.Join(global.IMAGE_PATH, file)) {
|
||||||
return Failed(100)
|
return Failed(100)
|
||||||
@ -248,6 +307,28 @@ func (bot *CQBot) CQGetImage(file string) MSG {
|
|||||||
return Failed(100)
|
return Failed(100)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (bot *CQBot) CQGetForwardMessage(resId string) MSG {
|
||||||
|
m := bot.Client.GetForwardMessage(resId)
|
||||||
|
if m == nil {
|
||||||
|
return Failed(100)
|
||||||
|
}
|
||||||
|
var r []MSG
|
||||||
|
for _, n := range m.Nodes {
|
||||||
|
checkImage(n.Message)
|
||||||
|
r = append(r, MSG{
|
||||||
|
"sender": MSG{
|
||||||
|
"user_id": n.SenderId,
|
||||||
|
"nick": n.SenderName,
|
||||||
|
},
|
||||||
|
"time": n.Time,
|
||||||
|
"content": ToStringMessage(n.Message, 0, false),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return OK(MSG{
|
||||||
|
"messages": r,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func (bot *CQBot) CQGetGroupMessage(messageId int32) MSG {
|
func (bot *CQBot) CQGetGroupMessage(messageId int32) MSG {
|
||||||
msg := bot.GetGroupMessage(messageId)
|
msg := bot.GetGroupMessage(messageId)
|
||||||
if msg == nil {
|
if msg == nil {
|
||||||
|
@ -38,7 +38,7 @@ func NewQQBot(cli *client.QQClient, conf *global.JsonConfig) *CQBot {
|
|||||||
opt.EntryIdxMode = nutsdb.HintBPTSparseIdxMode
|
opt.EntryIdxMode = nutsdb.HintBPTSparseIdxMode
|
||||||
db, err := nutsdb.Open(opt)
|
db, err := nutsdb.Open(opt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("打开数据库失败, 如果频繁遇到此问题请关闭数据库功能。")
|
log.Fatalf("打开数据库失败, 如果频繁遇到此问题请清理 data/db 文件夹或关闭数据库功能。")
|
||||||
}
|
}
|
||||||
bot.db = db
|
bot.db = db
|
||||||
gob.Register(message.Sender{})
|
gob.Register(message.Sender{})
|
||||||
|
@ -36,6 +36,8 @@ func ToStringMessage(e []message.IMessageElement, code int64, raw ...bool) (r st
|
|||||||
r += fmt.Sprintf("[CQ:at,qq=%d]", o.Target)
|
r += fmt.Sprintf("[CQ:at,qq=%d]", o.Target)
|
||||||
case *message.ReplyElement:
|
case *message.ReplyElement:
|
||||||
r += fmt.Sprintf("[CQ:reply,id=%d]", ToGlobalId(code, o.ReplySeq))
|
r += fmt.Sprintf("[CQ:reply,id=%d]", ToGlobalId(code, o.ReplySeq))
|
||||||
|
case *message.ForwardElement:
|
||||||
|
r += fmt.Sprintf("[CQ:forward,id=%s]", o.ResId)
|
||||||
case *message.FaceElement:
|
case *message.FaceElement:
|
||||||
r += fmt.Sprintf(`[CQ:face,id=%d]`, o.Index)
|
r += fmt.Sprintf(`[CQ:face,id=%d]`, o.Index)
|
||||||
case *message.ImageElement:
|
case *message.ImageElement:
|
||||||
|
@ -20,25 +20,41 @@ go-cqhttp 支持导入CQHTTP的配置文件, 具体步骤为:
|
|||||||
"password": "",
|
"password": "",
|
||||||
"enable_db": true,
|
"enable_db": true,
|
||||||
"access_token": "",
|
"access_token": "",
|
||||||
|
"relogin": false,
|
||||||
|
"relogin_delay": 0,
|
||||||
"http_config": {
|
"http_config": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"host": "0.0.0.0",
|
"host": "0.0.0.0",
|
||||||
"port": 5700
|
"port": 5700,
|
||||||
|
"post_urls": []
|
||||||
},
|
},
|
||||||
"ws_config": {
|
"ws_config": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"host": "0.0.0.0",
|
"host": "0.0.0.0",
|
||||||
"port": 6700
|
"port": 6700
|
||||||
}
|
},
|
||||||
|
"ws_reverse_servers": [
|
||||||
|
{
|
||||||
|
"enabled": false,
|
||||||
|
"reverse_url": "ws://you_websocket_universal.server",
|
||||||
|
"reverse_api_url": "ws://you_websocket_api.server",
|
||||||
|
"reverse_event_url": "ws://you_websocket_event.server",
|
||||||
|
"reverse_reconnect_interval": 3000
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
````
|
````
|
||||||
|
|
||||||
| 字段 | 类型 | 说明 |
|
| 字段 | 类型 | 说明 |
|
||||||
| ------------ | ------ | ------------------------------------------------------------ |
|
| ------------------ | -------- | ------------------------------------------------------------------- |
|
||||||
| uin | int64 | 登录用QQ号 |
|
| uin | int64 | 登录用QQ号 |
|
||||||
| password | string | 登录用密码 |
|
| password | string | 登录用密码 |
|
||||||
| enable_db | bool | 是否开启内置数据库, 关闭后将无法使用 **回复/撤回** 等上下文相关接口 |
|
| enable_db | bool | 是否开启内置数据库, 关闭后将无法使用 **回复/撤回** 等上下文相关接口 |
|
||||||
| access_token | string | 同CQHTTP的 `access_token` 用于身份验证 |
|
| access_token | string | 同CQHTTP的 `access_token` 用于身份验证 |
|
||||||
| http_config | object | HTTP API配置 |
|
| relogin | bool | 是否自动重新登录 |
|
||||||
| ws_config | object | Websocket API 配置 |
|
| relogin_delay | int | 重登录延时(秒) |
|
||||||
|
| http_config | object | HTTP API配置 |
|
||||||
|
| ws_config | object | Websocket API 配置 |
|
||||||
|
| ws_reverse_servers | object[] | 反向 Websocket API 配置 |
|
||||||
|
|
||||||
|
|
||||||
|
@ -4,9 +4,10 @@
|
|||||||
|
|
||||||
## CQCode
|
## CQCode
|
||||||
|
|
||||||
| Code | 示例 | 说明 |
|
| Code | 示例 | 说明 |
|
||||||
| ----- | -------------------- | ---------------------------------------------------------- |
|
| ------- | -------------------- | ------------------------------------------------------------ |
|
||||||
| reply | [CQ:reply,id=123456] | 回复ID为 `123456`的信息. 发送时一条 `message` 仅能使用一次 |
|
| reply | [CQ:reply,id=123456] | 回复ID为 `123456`的信息. 发送时一条 `message` 仅能使用一次 |
|
||||||
|
| forward | [CQ:forward,id=abcd] | ID为abcd的转发消息, 暂时仅能接收. 可通过 `/get_forward_msg` API获取具体信息 |
|
||||||
|
|
||||||
## API
|
## API
|
||||||
|
|
||||||
@ -55,6 +56,16 @@
|
|||||||
| `time` | int32 | 发送时间 |
|
| `time` | int32 | 发送时间 |
|
||||||
| `content` | message | 消息内容 |
|
| `content` | message | 消息内容 |
|
||||||
|
|
||||||
|
`/get_forward_msg` **获取转发消息信息**
|
||||||
|
|
||||||
|
参数
|
||||||
|
|
||||||
|
| 字段 | 类型 | 说明 |
|
||||||
|
| ------------ | ------ | ------ |
|
||||||
|
| `message_id` | string | 消息id |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## 事件
|
## 事件
|
||||||
|
|
||||||
#### 群消息撤回
|
#### 群消息撤回
|
||||||
|
@ -6,14 +6,15 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type JsonConfig struct {
|
type JsonConfig struct {
|
||||||
Uin int64 `json:"uin"`
|
Uin int64 `json:"uin"`
|
||||||
Password string `json:"password"`
|
Password string `json:"password"`
|
||||||
EnableDB bool `json:"enable_db"`
|
EnableDB bool `json:"enable_db"`
|
||||||
AccessToken string `json:"access_token"`
|
AccessToken string `json:"access_token"`
|
||||||
Reconnect bool `json:"reconnect"`
|
ReLogin bool `json:"relogin"`
|
||||||
ReconnectDelay int `json:"reconnect_delay"`
|
ReLoginDelay int `json:"relogin_delay"`
|
||||||
HttpConfig *GoCQHttpConfig `json:"http_config"`
|
HttpConfig *GoCQHttpConfig `json:"http_config"`
|
||||||
WSConfig *GoCQWebsocketConfig `json:"ws_config"`
|
WSConfig *GoCQWebsocketConfig `json:"ws_config"`
|
||||||
|
ReverseServers []*GoCQReverseWebsocketConfig `json:"ws_reverse_servers"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type CQHttpApiConfig struct {
|
type CQHttpApiConfig struct {
|
||||||
@ -48,6 +49,14 @@ type GoCQWebsocketConfig struct {
|
|||||||
Port uint16 `json:"port"`
|
Port uint16 `json:"port"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type GoCQReverseWebsocketConfig struct {
|
||||||
|
Enabled bool `json:"enabled"`
|
||||||
|
ReverseUrl string `json:"reverse_url"`
|
||||||
|
ReverseApiUrl string `json:"reverse_api_url"`
|
||||||
|
ReverseEventUrl string `json:"reverse_event_url"`
|
||||||
|
ReverseReconnectInterval uint16 `json:"reverse_reconnect_interval"`
|
||||||
|
}
|
||||||
|
|
||||||
func DefaultConfig() *JsonConfig {
|
func DefaultConfig() *JsonConfig {
|
||||||
return &JsonConfig{
|
return &JsonConfig{
|
||||||
EnableDB: true,
|
EnableDB: true,
|
||||||
@ -62,6 +71,15 @@ func DefaultConfig() *JsonConfig {
|
|||||||
Host: "0.0.0.0",
|
Host: "0.0.0.0",
|
||||||
Port: 6700,
|
Port: 6700,
|
||||||
},
|
},
|
||||||
|
ReverseServers: []*GoCQReverseWebsocketConfig{
|
||||||
|
{
|
||||||
|
Enabled: false,
|
||||||
|
ReverseUrl: "ws://you_websocket_universal.server",
|
||||||
|
ReverseApiUrl: "ws://you_websocket_api.server",
|
||||||
|
ReverseEventUrl: "ws://you_websocket_event.server",
|
||||||
|
ReverseReconnectInterval: 3000,
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
3
go.mod
3
go.mod
@ -3,7 +3,7 @@ module github.com/Mrs4s/go-cqhttp
|
|||||||
go 1.14
|
go 1.14
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/Mrs4s/MiraiGo v0.0.0-20200721195252-2accd73f8b8e
|
github.com/Mrs4s/MiraiGo v0.0.0-20200726203306-14d741fe9383
|
||||||
github.com/gin-gonic/gin v1.6.3
|
github.com/gin-gonic/gin v1.6.3
|
||||||
github.com/gorilla/websocket v1.4.2
|
github.com/gorilla/websocket v1.4.2
|
||||||
github.com/guonaihong/gout v0.1.1
|
github.com/guonaihong/gout v0.1.1
|
||||||
@ -15,5 +15,6 @@ require (
|
|||||||
github.com/tidwall/gjson v1.6.0
|
github.com/tidwall/gjson v1.6.0
|
||||||
github.com/xujiajun/nutsdb v0.5.0
|
github.com/xujiajun/nutsdb v0.5.0
|
||||||
golang.org/x/image v0.0.0-20200618115811-c13761719519
|
golang.org/x/image v0.0.0-20200618115811-c13761719519
|
||||||
|
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa
|
||||||
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae // indirect
|
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae // indirect
|
||||||
)
|
)
|
||||||
|
2
go.sum
2
go.sum
@ -14,6 +14,8 @@ github.com/Mrs4s/MiraiGo v0.0.0-20200720231612-a7e460246fbc h1:elEjdwOy2u+Gfz+1U
|
|||||||
github.com/Mrs4s/MiraiGo v0.0.0-20200720231612-a7e460246fbc/go.mod h1:M9wh1hjd0rie3+wm27tjPZkYMbD+MBV76CGqp2G7WSU=
|
github.com/Mrs4s/MiraiGo v0.0.0-20200720231612-a7e460246fbc/go.mod h1:M9wh1hjd0rie3+wm27tjPZkYMbD+MBV76CGqp2G7WSU=
|
||||||
github.com/Mrs4s/MiraiGo v0.0.0-20200721195252-2accd73f8b8e h1:68ol9TpLBwbFQU+S6VQ0CY6nQqN2xIPxHWD/rvBZxVI=
|
github.com/Mrs4s/MiraiGo v0.0.0-20200721195252-2accd73f8b8e h1:68ol9TpLBwbFQU+S6VQ0CY6nQqN2xIPxHWD/rvBZxVI=
|
||||||
github.com/Mrs4s/MiraiGo v0.0.0-20200721195252-2accd73f8b8e/go.mod h1:M9wh1hjd0rie3+wm27tjPZkYMbD+MBV76CGqp2G7WSU=
|
github.com/Mrs4s/MiraiGo v0.0.0-20200721195252-2accd73f8b8e/go.mod h1:M9wh1hjd0rie3+wm27tjPZkYMbD+MBV76CGqp2G7WSU=
|
||||||
|
github.com/Mrs4s/MiraiGo v0.0.0-20200726203306-14d741fe9383 h1:Z1z7pG9RJo5ynI1mW0r+PyK9wZ6xExY8cMS+kV0NUJ0=
|
||||||
|
github.com/Mrs4s/MiraiGo v0.0.0-20200726203306-14d741fe9383/go.mod h1:M9wh1hjd0rie3+wm27tjPZkYMbD+MBV76CGqp2G7WSU=
|
||||||
github.com/bwmarrin/snowflake v0.3.0 h1:xm67bEhkKh6ij1790JB83OujPR5CzNe8QuQqAgISZN0=
|
github.com/bwmarrin/snowflake v0.3.0 h1:xm67bEhkKh6ij1790JB83OujPR5CzNe8QuQqAgISZN0=
|
||||||
github.com/bwmarrin/snowflake v0.3.0/go.mod h1:NdZxfVWX+oR6y2K0o6qAYv6gIOP9rjG0/E9WsDpxqwE=
|
github.com/bwmarrin/snowflake v0.3.0/go.mod h1:NdZxfVWX+oR6y2K0o6qAYv6gIOP9rjG0/E9WsDpxqwE=
|
||||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||||
|
18
main.go
18
main.go
@ -56,6 +56,13 @@ func init() {
|
|||||||
if conf.PostUrl != "" {
|
if conf.PostUrl != "" {
|
||||||
goConf.HttpConfig.PostUrls[conf.PostUrl] = conf.Secret
|
goConf.HttpConfig.PostUrls[conf.PostUrl] = conf.Secret
|
||||||
}
|
}
|
||||||
|
if conf.UseWsReverse {
|
||||||
|
goConf.ReverseServers[0].Enabled = true
|
||||||
|
goConf.ReverseServers[0].ReverseUrl = conf.WSReverseUrl
|
||||||
|
goConf.ReverseServers[0].ReverseApiUrl = conf.WSReverseApiUrl
|
||||||
|
goConf.ReverseServers[0].ReverseEventUrl = conf.WSReverseEventUrl
|
||||||
|
goConf.ReverseServers[0].ReverseReconnectInterval = conf.WSReverseReconnectInterval
|
||||||
|
}
|
||||||
if err := goConf.Save("config.json"); err != nil {
|
if err := goConf.Save("config.json"); err != nil {
|
||||||
log.Fatalf("保存 config.json 时出现错误: %v", err)
|
log.Fatalf("保存 config.json 时出现错误: %v", err)
|
||||||
}
|
}
|
||||||
@ -131,18 +138,21 @@ func main() {
|
|||||||
if conf.HttpConfig != nil && conf.HttpConfig.Enabled {
|
if conf.HttpConfig != nil && conf.HttpConfig.Enabled {
|
||||||
server.HttpServer.Run(fmt.Sprintf("%s:%d", conf.HttpConfig.Host, conf.HttpConfig.Port), conf.AccessToken, b)
|
server.HttpServer.Run(fmt.Sprintf("%s:%d", conf.HttpConfig.Host, conf.HttpConfig.Port), conf.AccessToken, b)
|
||||||
for k, v := range conf.HttpConfig.PostUrls {
|
for k, v := range conf.HttpConfig.PostUrls {
|
||||||
server.NewClient().Run(k, v, b)
|
server.NewHttpClient().Run(k, v, b)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if conf.WSConfig != nil && conf.WSConfig.Enabled {
|
if conf.WSConfig != nil && conf.WSConfig.Enabled {
|
||||||
server.WebsocketServer.Run(fmt.Sprintf("%s:%d", conf.WSConfig.Host, conf.WSConfig.Port), conf.AccessToken, b)
|
server.WebsocketServer.Run(fmt.Sprintf("%s:%d", conf.WSConfig.Host, conf.WSConfig.Port), conf.AccessToken, b)
|
||||||
}
|
}
|
||||||
|
for _, rc := range conf.ReverseServers {
|
||||||
|
server.NewWebsocketClient(rc, conf.AccessToken, b).Run()
|
||||||
|
}
|
||||||
log.Info("资源初始化完成, 开始处理信息.")
|
log.Info("资源初始化完成, 开始处理信息.")
|
||||||
log.Info("アトリは、高性能ですから!")
|
log.Info("アトリは、高性能ですから!")
|
||||||
cli.OnDisconnected(func(bot *client.QQClient, e *client.ClientDisconnectedEvent) {
|
cli.OnDisconnected(func(bot *client.QQClient, e *client.ClientDisconnectedEvent) {
|
||||||
if conf.Reconnect {
|
if conf.ReLogin {
|
||||||
log.Warnf("Bot已离线,将在 %v 秒后尝试重连.", conf.ReconnectDelay)
|
log.Warnf("Bot已离线,将在 %v 秒后尝试重连.", conf.ReLoginDelay)
|
||||||
time.Sleep(time.Second * time.Duration(conf.ReconnectDelay))
|
time.Sleep(time.Second * time.Duration(conf.ReLoginDelay))
|
||||||
rsp, err := cli.Login()
|
rsp, err := cli.Login()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("重连失败: %v", err)
|
log.Fatalf("重连失败: %v", err)
|
||||||
|
@ -127,6 +127,8 @@ func (s *httpServer) Run(addr, authToken string, bot *coolq.CQBot) {
|
|||||||
s.engine.Any("/get_image", s.GetImage)
|
s.engine.Any("/get_image", s.GetImage)
|
||||||
s.engine.Any("/get_image_async", s.GetImage)
|
s.engine.Any("/get_image_async", s.GetImage)
|
||||||
|
|
||||||
|
s.engine.Any("/get_forward_msg", s.GetForwardMessage)
|
||||||
|
|
||||||
s.engine.Any("/get_group_msg", s.GetGroupMessage)
|
s.engine.Any("/get_group_msg", s.GetGroupMessage)
|
||||||
s.engine.Any("/get_group_msg_async", s.GetGroupMessage)
|
s.engine.Any("/get_group_msg_async", s.GetGroupMessage)
|
||||||
|
|
||||||
@ -142,13 +144,15 @@ func (s *httpServer) Run(addr, authToken string, bot *coolq.CQBot) {
|
|||||||
s.engine.Any("/get_version_info", s.GetVersionInfo)
|
s.engine.Any("/get_version_info", s.GetVersionInfo)
|
||||||
s.engine.Any("/get_version_info_async", s.GetVersionInfo)
|
s.engine.Any("/get_version_info_async", s.GetVersionInfo)
|
||||||
|
|
||||||
|
s.engine.Any("/.handle_quick_operation", s.HandleQuickOperation)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
log.Infof("CQ HTTP 服务器已启动: %v", addr)
|
log.Infof("CQ HTTP 服务器已启动: %v", addr)
|
||||||
log.Fatal(s.engine.Run(addr))
|
log.Fatal(s.engine.Run(addr))
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewClient() *httpClient {
|
func NewHttpClient() *httpClient {
|
||||||
return &httpClient{}
|
return &httpClient{}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -161,11 +165,11 @@ func (c *httpClient) Run(addr, secret string, bot *coolq.CQBot) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *httpClient) onBotPushEvent(m coolq.MSG) {
|
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{
|
h := gout.H{
|
||||||
"X-Self_ID": c.bot.Client.Uin,
|
"X-Self-ID": c.bot.Client.Uin,
|
||||||
"X-Client-Role": "Universal",
|
"User-Agent": "CQHttp/4.15.0",
|
||||||
"User-Agent": "CQHttp/4.15.0",
|
|
||||||
}
|
}
|
||||||
if c.secret != "" {
|
if c.secret != "" {
|
||||||
mac := hmac.New(sha1.New, []byte(c.secret))
|
mac := hmac.New(sha1.New, []byte(c.secret))
|
||||||
@ -176,6 +180,10 @@ func (c *httpClient) onBotPushEvent(m coolq.MSG) {
|
|||||||
}()).SetTimeout(time.Second * 5).Do()
|
}()).SetTimeout(time.Second * 5).Do()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warnf("上报Event数据到 %v 失败: %v", c.addr, err)
|
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 +286,8 @@ func (s *httpServer) SetGroupKick(c *gin.Context) {
|
|||||||
func (s *httpServer) SetGroupBan(c *gin.Context) {
|
func (s *httpServer) SetGroupBan(c *gin.Context) {
|
||||||
gid, _ := strconv.ParseInt(getParam(c, "group_id"), 10, 64)
|
gid, _ := strconv.ParseInt(getParam(c, "group_id"), 10, 64)
|
||||||
uid, _ := strconv.ParseInt(getParam(c, "user_id"), 10, 64)
|
uid, _ := strconv.ParseInt(getParam(c, "user_id"), 10, 64)
|
||||||
time, _ := strconv.ParseInt(getParam(c, "duration"), 10, 64)
|
i, _ := strconv.ParseInt(getParam(c, "duration"), 10, 64)
|
||||||
c.JSON(200, s.bot.CQSetGroupBan(gid, uid, uint32(time)))
|
c.JSON(200, s.bot.CQSetGroupBan(gid, uid, uint32(i)))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *httpServer) SetWholeBan(c *gin.Context) {
|
func (s *httpServer) SetWholeBan(c *gin.Context) {
|
||||||
@ -292,6 +300,11 @@ func (s *httpServer) SetGroupName(c *gin.Context) {
|
|||||||
c.JSON(200, s.bot.CQSetGroupName(gid, getParam(c, "name")))
|
c.JSON(200, s.bot.CQSetGroupName(gid, getParam(c, "name")))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *httpServer) GetForwardMessage(c *gin.Context) {
|
||||||
|
resId := getParam(c, "message_id")
|
||||||
|
c.JSON(200, s.bot.CQGetForwardMessage(resId))
|
||||||
|
}
|
||||||
|
|
||||||
func (s *httpServer) DeleteMessage(c *gin.Context) {
|
func (s *httpServer) DeleteMessage(c *gin.Context) {
|
||||||
mid, _ := strconv.ParseInt(getParam(c, "message_id"), 10, 32)
|
mid, _ := strconv.ParseInt(getParam(c, "message_id"), 10, 32)
|
||||||
c.JSON(200, s.bot.CQDeleteMessage(int32(mid)))
|
c.JSON(200, s.bot.CQDeleteMessage(int32(mid)))
|
||||||
@ -313,6 +326,17 @@ func (s *httpServer) GetVersionInfo(c *gin.Context) {
|
|||||||
c.JSON(200, s.bot.CQGetVersionInfo())
|
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 {
|
func getParamOrDefault(c *gin.Context, k, def string) string {
|
||||||
r := getParam(c, k)
|
r := getParam(c, k)
|
||||||
if r != "" {
|
if r != "" {
|
||||||
|
@ -3,10 +3,13 @@ package server
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/Mrs4s/go-cqhttp/coolq"
|
"github.com/Mrs4s/go-cqhttp/coolq"
|
||||||
|
"github.com/Mrs4s/go-cqhttp/global"
|
||||||
"github.com/gorilla/websocket"
|
"github.com/gorilla/websocket"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"github.com/tidwall/gjson"
|
"github.com/tidwall/gjson"
|
||||||
|
wsc "golang.org/x/net/websocket"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
@ -21,6 +24,13 @@ type websocketServer struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type websocketClient struct {
|
type websocketClient struct {
|
||||||
|
conf *global.GoCQReverseWebsocketConfig
|
||||||
|
token string
|
||||||
|
bot *coolq.CQBot
|
||||||
|
|
||||||
|
pushLock *sync.Mutex
|
||||||
|
universalConn *wsc.Conn
|
||||||
|
eventConn *wsc.Conn
|
||||||
}
|
}
|
||||||
|
|
||||||
var WebsocketServer = &websocketServer{}
|
var WebsocketServer = &websocketServer{}
|
||||||
@ -46,6 +56,149 @@ func (s *websocketServer) Run(addr, authToken string, b *coolq.CQBot) {
|
|||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewWebsocketClient(conf *global.GoCQReverseWebsocketConfig, authToken string, b *coolq.CQBot) *websocketClient {
|
||||||
|
return &websocketClient{conf: conf, token: authToken, bot: b, pushLock: new(sync.Mutex)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *websocketClient) Run() {
|
||||||
|
if !c.conf.Enabled {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if c.conf.ReverseApiUrl != "" {
|
||||||
|
c.connectApi()
|
||||||
|
}
|
||||||
|
if c.conf.ReverseEventUrl != "" {
|
||||||
|
c.connectEvent()
|
||||||
|
}
|
||||||
|
if c.conf.ReverseUrl != "" {
|
||||||
|
c.connectUniversal()
|
||||||
|
}
|
||||||
|
c.bot.OnEventPush(c.onBotPushEvent)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *websocketClient) connectApi() {
|
||||||
|
log.Infof("开始尝试连接到反向Websocket API服务器: %v", c.conf.ReverseApiUrl)
|
||||||
|
wsConf, err := wsc.NewConfig(c.conf.ReverseApiUrl, c.conf.ReverseApiUrl)
|
||||||
|
if err != nil {
|
||||||
|
log.Warnf("连接到反向Websocket API服务器 %v 时出现致命错误: %v", c.conf.ReverseApiUrl, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
wsConf.Header["X-Client-Role"] = []string{"API"}
|
||||||
|
wsConf.Header["X-Self-ID"] = []string{strconv.FormatInt(c.bot.Client.Uin, 10)}
|
||||||
|
wsConf.Header["User-Agent"] = []string{"CQHttp/4.15.0"}
|
||||||
|
if c.token != "" {
|
||||||
|
wsConf.Header["Authorization"] = []string{"Token " + c.token}
|
||||||
|
}
|
||||||
|
conn, err := wsc.DialConfig(wsConf)
|
||||||
|
if err != nil {
|
||||||
|
log.Warnf("连接到反向Websocket API服务器 %v 时出现错误: %v", c.conf.ReverseApiUrl, err)
|
||||||
|
if c.conf.ReverseReconnectInterval != 0 {
|
||||||
|
time.Sleep(time.Millisecond * time.Duration(c.conf.ReverseReconnectInterval))
|
||||||
|
c.connectApi()
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
log.Infof("已连接到反向Websocket API服务器 %v", c.conf.ReverseApiUrl)
|
||||||
|
go c.listenApi(conn, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *websocketClient) connectEvent() {
|
||||||
|
log.Infof("开始尝试连接到反向Websocket Event服务器: %v", c.conf.ReverseEventUrl)
|
||||||
|
wsConf, err := wsc.NewConfig(c.conf.ReverseEventUrl, c.conf.ReverseEventUrl)
|
||||||
|
if err != nil {
|
||||||
|
log.Warnf("连接到反向Websocket Event服务器 %v 时出现致命错误: %v", c.conf.ReverseApiUrl, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
wsConf.Header["X-Client-Role"] = []string{"Event"}
|
||||||
|
wsConf.Header["X-Self-ID"] = []string{strconv.FormatInt(c.bot.Client.Uin, 10)}
|
||||||
|
wsConf.Header["User-Agent"] = []string{"CQHttp/4.15.0"}
|
||||||
|
if c.token != "" {
|
||||||
|
wsConf.Header["Authorization"] = []string{"Token " + c.token}
|
||||||
|
}
|
||||||
|
conn, err := wsc.DialConfig(wsConf)
|
||||||
|
if err != nil {
|
||||||
|
log.Warnf("连接到反向Websocket API服务器 %v 时出现错误: %v", c.conf.ReverseApiUrl, err)
|
||||||
|
if c.conf.ReverseReconnectInterval != 0 {
|
||||||
|
time.Sleep(time.Millisecond * time.Duration(c.conf.ReverseReconnectInterval))
|
||||||
|
c.connectApi()
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
log.Infof("已连接到反向Websocket Event服务器 %v", c.conf.ReverseEventUrl)
|
||||||
|
c.eventConn = conn
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *websocketClient) connectUniversal() {
|
||||||
|
log.Infof("开始尝试连接到反向Websocket Universal服务器: %v", c.conf.ReverseUrl)
|
||||||
|
wsConf, err := wsc.NewConfig(c.conf.ReverseUrl, c.conf.ReverseUrl)
|
||||||
|
if err != nil {
|
||||||
|
log.Warnf("连接到反向Websocket Universal服务器 %v 时出现致命错误: %v", c.conf.ReverseUrl, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
wsConf.Header["X-Client-Role"] = []string{"Universal"}
|
||||||
|
wsConf.Header["X-Self-ID"] = []string{strconv.FormatInt(c.bot.Client.Uin, 10)}
|
||||||
|
wsConf.Header["User-Agent"] = []string{"CQHttp/4.15.0"}
|
||||||
|
if c.token != "" {
|
||||||
|
wsConf.Header["Authorization"] = []string{"Token " + c.token}
|
||||||
|
}
|
||||||
|
conn, err := wsc.DialConfig(wsConf)
|
||||||
|
if err != nil {
|
||||||
|
log.Warnf("连接到反向Websocket Universal服务器 %v 时出现错误: %v", c.conf.ReverseUrl, err)
|
||||||
|
if c.conf.ReverseReconnectInterval != 0 {
|
||||||
|
time.Sleep(time.Millisecond * time.Duration(c.conf.ReverseReconnectInterval))
|
||||||
|
c.connectUniversal()
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
go c.listenApi(conn, true)
|
||||||
|
c.universalConn = conn
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *websocketClient) listenApi(conn *wsc.Conn, u bool) {
|
||||||
|
defer conn.Close()
|
||||||
|
for {
|
||||||
|
buf := make([]byte, 10240)
|
||||||
|
l, err := conn.Read(buf)
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
j := gjson.ParseBytes(buf[:l])
|
||||||
|
t := strings.ReplaceAll(j.Get("action").Str, "_async", "")
|
||||||
|
if f, ok := wsApi[t]; ok {
|
||||||
|
ret := f(c.bot, j.Get("params"))
|
||||||
|
if j.Get("echo").Exists() {
|
||||||
|
ret["echo"] = j.Get("echo").Value()
|
||||||
|
}
|
||||||
|
_, _ = conn.Write([]byte(ret.ToJson()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if c.conf.ReverseReconnectInterval != 0 {
|
||||||
|
time.Sleep(time.Millisecond * time.Duration(c.conf.ReverseReconnectInterval))
|
||||||
|
if u {
|
||||||
|
c.connectUniversal()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.connectApi()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *websocketClient) onBotPushEvent(m coolq.MSG) {
|
||||||
|
c.pushLock.Lock()
|
||||||
|
defer c.pushLock.Unlock()
|
||||||
|
if c.eventConn != nil {
|
||||||
|
if _, err := c.eventConn.Write([]byte(m.ToJson())); err != nil {
|
||||||
|
_ = c.eventConn.Close()
|
||||||
|
if c.conf.ReverseReconnectInterval != 0 {
|
||||||
|
time.Sleep(time.Millisecond * time.Duration(c.conf.ReverseReconnectInterval))
|
||||||
|
c.connectEvent()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if c.universalConn != nil {
|
||||||
|
_, _ = c.universalConn.Write([]byte(m.ToJson()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (s *websocketServer) event(w http.ResponseWriter, r *http.Request) {
|
func (s *websocketServer) event(w http.ResponseWriter, r *http.Request) {
|
||||||
if s.token != "" {
|
if s.token != "" {
|
||||||
if r.URL.Query().Get("access_token") != s.token && strings.SplitN(r.Header.Get("Authorization"), " ", 2)[1] != s.token {
|
if r.URL.Query().Get("access_token") != s.token && strings.SplitN(r.Header.Get("Authorization"), " ", 2)[1] != s.token {
|
||||||
@ -114,9 +267,13 @@ func (s *websocketServer) listenApi(c *websocket.Conn) {
|
|||||||
if t == websocket.TextMessage {
|
if t == websocket.TextMessage {
|
||||||
j := gjson.ParseBytes(payload)
|
j := gjson.ParseBytes(payload)
|
||||||
t := strings.ReplaceAll(j.Get("action").Str, "_async", "") //TODO: async support
|
t := strings.ReplaceAll(j.Get("action").Str, "_async", "") //TODO: async support
|
||||||
log.Infof("API调用: %v", j.Get("action").Str)
|
//log.Infof("API调用: %v", j.Get("action").Str)
|
||||||
if f, ok := wsApi[t]; ok {
|
if f, ok := wsApi[t]; ok {
|
||||||
_ = c.WriteMessage(websocket.TextMessage, []byte(f(s.bot, j.Get("params"))))
|
ret := f(s.bot, j.Get("params"))
|
||||||
|
if j.Get("echo").Exists() {
|
||||||
|
ret["echo"] = j.Get("echo").Value()
|
||||||
|
}
|
||||||
|
_ = c.WriteJSON(ret)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -139,54 +296,54 @@ func (s *websocketServer) onBotPushEvent(m coolq.MSG) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var wsApi = map[string]func(*coolq.CQBot, gjson.Result) string{
|
var wsApi = map[string]func(*coolq.CQBot, gjson.Result) coolq.MSG{
|
||||||
"get_login_info": func(bot *coolq.CQBot, p gjson.Result) string {
|
"get_login_info": func(bot *coolq.CQBot, p gjson.Result) coolq.MSG {
|
||||||
return bot.CQGetLoginInfo().ToJson()
|
return bot.CQGetLoginInfo()
|
||||||
},
|
},
|
||||||
"get_friend_list": func(bot *coolq.CQBot, p gjson.Result) string {
|
"get_friend_list": func(bot *coolq.CQBot, p gjson.Result) coolq.MSG {
|
||||||
return bot.CQGetFriendList().ToJson()
|
return bot.CQGetFriendList()
|
||||||
},
|
},
|
||||||
"get_group_list": func(bot *coolq.CQBot, p gjson.Result) string {
|
"get_group_list": func(bot *coolq.CQBot, p gjson.Result) coolq.MSG {
|
||||||
return bot.CQGetGroupList().ToJson()
|
return bot.CQGetGroupList()
|
||||||
},
|
},
|
||||||
"get_group_info": func(bot *coolq.CQBot, p gjson.Result) string {
|
"get_group_info": func(bot *coolq.CQBot, p gjson.Result) coolq.MSG {
|
||||||
return bot.CQGetGroupInfo(p.Get("group_id").Int()).ToJson()
|
return bot.CQGetGroupInfo(p.Get("group_id").Int())
|
||||||
},
|
},
|
||||||
"get_group_member_list": func(bot *coolq.CQBot, p gjson.Result) string {
|
"get_group_member_list": func(bot *coolq.CQBot, p gjson.Result) coolq.MSG {
|
||||||
return bot.CQGetGroupMemberList(p.Get("group_id").Int()).ToJson()
|
return bot.CQGetGroupMemberList(p.Get("group_id").Int())
|
||||||
},
|
},
|
||||||
"get_group_member_info": func(bot *coolq.CQBot, p gjson.Result) string {
|
"get_group_member_info": func(bot *coolq.CQBot, p gjson.Result) coolq.MSG {
|
||||||
return bot.CQGetGroupMemberInfo(
|
return bot.CQGetGroupMemberInfo(
|
||||||
p.Get("group_id").Int(), p.Get("user_id").Int(),
|
p.Get("group_id").Int(), p.Get("user_id").Int(),
|
||||||
p.Get("no_cache").Bool(),
|
p.Get("no_cache").Bool(),
|
||||||
).ToJson()
|
)
|
||||||
},
|
},
|
||||||
"send_msg": func(bot *coolq.CQBot, p gjson.Result) string {
|
"send_msg": func(bot *coolq.CQBot, p gjson.Result) coolq.MSG {
|
||||||
if p.Get("group_id").Int() != 0 {
|
if p.Get("group_id").Int() != 0 {
|
||||||
return bot.CQSendGroupMessage(p.Get("group_id").Int(), p.Get("message").Str).ToJson()
|
return bot.CQSendGroupMessage(p.Get("group_id").Int(), p.Get("message").Str)
|
||||||
}
|
}
|
||||||
if p.Get("user_id").Int() != 0 {
|
if p.Get("user_id").Int() != 0 {
|
||||||
return bot.CQSendPrivateMessage(p.Get("user_id").Int(), p.Get("message").Str).ToJson()
|
return bot.CQSendPrivateMessage(p.Get("user_id").Int(), p.Get("message").Str)
|
||||||
}
|
}
|
||||||
return ""
|
return coolq.MSG{}
|
||||||
},
|
},
|
||||||
"send_group_msg": func(bot *coolq.CQBot, p gjson.Result) string {
|
"send_group_msg": func(bot *coolq.CQBot, p gjson.Result) coolq.MSG {
|
||||||
return bot.CQSendGroupMessage(p.Get("group_id").Int(), p.Get("message").Str).ToJson()
|
return bot.CQSendGroupMessage(p.Get("group_id").Int(), p.Get("message").Str)
|
||||||
},
|
},
|
||||||
"send_private_msg": func(bot *coolq.CQBot, p gjson.Result) string {
|
"send_private_msg": func(bot *coolq.CQBot, p gjson.Result) coolq.MSG {
|
||||||
return bot.CQSendPrivateMessage(p.Get("user_id").Int(), p.Get("message").Str).ToJson()
|
return bot.CQSendPrivateMessage(p.Get("user_id").Int(), p.Get("message").Str)
|
||||||
},
|
},
|
||||||
"delete_msg": func(bot *coolq.CQBot, p gjson.Result) string {
|
"delete_msg": func(bot *coolq.CQBot, p gjson.Result) coolq.MSG {
|
||||||
return bot.CQDeleteMessage(int32(p.Get("message_id").Int())).ToJson()
|
return bot.CQDeleteMessage(int32(p.Get("message_id").Int()))
|
||||||
},
|
},
|
||||||
"set_friend_add_request": func(bot *coolq.CQBot, p gjson.Result) string {
|
"set_friend_add_request": func(bot *coolq.CQBot, p gjson.Result) coolq.MSG {
|
||||||
apr := true
|
apr := true
|
||||||
if p.Get("approve").Exists() {
|
if p.Get("approve").Exists() {
|
||||||
apr = p.Get("approve").Bool()
|
apr = p.Get("approve").Bool()
|
||||||
}
|
}
|
||||||
return bot.CQProcessFriendRequest(p.Get("flag").Str, apr).ToJson()
|
return bot.CQProcessFriendRequest(p.Get("flag").Str, apr)
|
||||||
},
|
},
|
||||||
"set_group_add_request": func(bot *coolq.CQBot, p gjson.Result) string {
|
"set_group_add_request": func(bot *coolq.CQBot, p gjson.Result) coolq.MSG {
|
||||||
subType := p.Get("sub_type").Str
|
subType := p.Get("sub_type").Str
|
||||||
apr := true
|
apr := true
|
||||||
if subType == "" {
|
if subType == "" {
|
||||||
@ -195,47 +352,53 @@ var wsApi = map[string]func(*coolq.CQBot, gjson.Result) string{
|
|||||||
if p.Get("approve").Exists() {
|
if p.Get("approve").Exists() {
|
||||||
apr = p.Get("approve").Bool()
|
apr = p.Get("approve").Bool()
|
||||||
}
|
}
|
||||||
return bot.CQProcessGroupRequest(p.Get("flag").Str, subType, apr).ToJson()
|
return bot.CQProcessGroupRequest(p.Get("flag").Str, subType, apr)
|
||||||
},
|
},
|
||||||
"set_group_card": func(bot *coolq.CQBot, p gjson.Result) string {
|
"set_group_card": func(bot *coolq.CQBot, p gjson.Result) coolq.MSG {
|
||||||
return bot.CQSetGroupCard(p.Get("group_id").Int(), p.Get("user_id").Int(), p.Get("card").Str).ToJson()
|
return bot.CQSetGroupCard(p.Get("group_id").Int(), p.Get("user_id").Int(), p.Get("card").Str)
|
||||||
},
|
},
|
||||||
"set_group_special_title": func(bot *coolq.CQBot, p gjson.Result) string {
|
"set_group_special_title": func(bot *coolq.CQBot, p gjson.Result) coolq.MSG {
|
||||||
return bot.CQSetGroupSpecialTitle(p.Get("group_id").Int(), p.Get("user_id").Int(), p.Get("special_title").Str).ToJson()
|
return bot.CQSetGroupSpecialTitle(p.Get("group_id").Int(), p.Get("user_id").Int(), p.Get("special_title").Str)
|
||||||
},
|
},
|
||||||
"set_group_kick": func(bot *coolq.CQBot, p gjson.Result) string {
|
"set_group_kick": func(bot *coolq.CQBot, p gjson.Result) coolq.MSG {
|
||||||
return bot.CQSetGroupKick(p.Get("group_id").Int(), p.Get("user_id").Int(), p.Get("message").Str).ToJson()
|
return bot.CQSetGroupKick(p.Get("group_id").Int(), p.Get("user_id").Int(), p.Get("message").Str)
|
||||||
},
|
},
|
||||||
"set_group_ban": func(bot *coolq.CQBot, p gjson.Result) string {
|
"set_group_ban": func(bot *coolq.CQBot, p gjson.Result) coolq.MSG {
|
||||||
return bot.CQSetGroupBan(p.Get("group_id").Int(), p.Get("user_id").Int(), uint32(p.Get("duration").Int())).ToJson()
|
return bot.CQSetGroupBan(p.Get("group_id").Int(), p.Get("user_id").Int(), uint32(p.Get("duration").Int()))
|
||||||
},
|
},
|
||||||
"set_group_whole_ban": func(bot *coolq.CQBot, p gjson.Result) string {
|
"set_group_whole_ban": func(bot *coolq.CQBot, p gjson.Result) coolq.MSG {
|
||||||
return bot.CQSetGroupWholeBan(p.Get("group_id").Int(), func() bool {
|
return bot.CQSetGroupWholeBan(p.Get("group_id").Int(), func() bool {
|
||||||
if p.Get("enable").Exists() {
|
if p.Get("enable").Exists() {
|
||||||
return p.Get("enable").Bool()
|
return p.Get("enable").Bool()
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}()).ToJson()
|
}())
|
||||||
},
|
},
|
||||||
"set_group_name": func(bot *coolq.CQBot, p gjson.Result) string {
|
"set_group_name": func(bot *coolq.CQBot, p gjson.Result) coolq.MSG {
|
||||||
return bot.CQSetGroupName(p.Get("group_id").Int(), p.Get("name").Str).ToJson()
|
return bot.CQSetGroupName(p.Get("group_id").Int(), p.Get("name").Str)
|
||||||
},
|
},
|
||||||
"get_image": func(bot *coolq.CQBot, p gjson.Result) string {
|
"get_image": func(bot *coolq.CQBot, p gjson.Result) coolq.MSG {
|
||||||
return bot.CQGetImage(p.Get("file").Str).ToJson()
|
return bot.CQGetImage(p.Get("file").Str)
|
||||||
},
|
},
|
||||||
"get_group_msg": func(bot *coolq.CQBot, p gjson.Result) string {
|
"get_forward_msg": func(bot *coolq.CQBot, p gjson.Result) coolq.MSG {
|
||||||
return bot.CQGetGroupMessage(int32(p.Get("message_id").Int())).ToJson()
|
return bot.CQGetForwardMessage(p.Get("message_id").Str)
|
||||||
},
|
},
|
||||||
"can_send_image": func(bot *coolq.CQBot, p gjson.Result) string {
|
"get_group_msg": func(bot *coolq.CQBot, p gjson.Result) coolq.MSG {
|
||||||
return bot.CQCanSendImage().ToJson()
|
return bot.CQGetGroupMessage(int32(p.Get("message_id").Int()))
|
||||||
},
|
},
|
||||||
"can_send_record": func(bot *coolq.CQBot, p gjson.Result) string {
|
"can_send_image": func(bot *coolq.CQBot, p gjson.Result) coolq.MSG {
|
||||||
return bot.CQCanSendRecord().ToJson()
|
return bot.CQCanSendImage()
|
||||||
},
|
},
|
||||||
"get_status": func(bot *coolq.CQBot, p gjson.Result) string {
|
"can_send_record": func(bot *coolq.CQBot, p gjson.Result) coolq.MSG {
|
||||||
return bot.CQGetStatus().ToJson()
|
return bot.CQCanSendRecord()
|
||||||
},
|
},
|
||||||
"get_version_info": func(bot *coolq.CQBot, p gjson.Result) string {
|
"get_status": func(bot *coolq.CQBot, p gjson.Result) coolq.MSG {
|
||||||
return bot.CQGetVersionInfo().ToJson()
|
return bot.CQGetStatus()
|
||||||
|
},
|
||||||
|
"get_version_info": func(bot *coolq.CQBot, p gjson.Result) coolq.MSG {
|
||||||
|
return bot.CQGetVersionInfo()
|
||||||
|
},
|
||||||
|
".handle_quick_operation": func(bot *coolq.CQBot, p gjson.Result) coolq.MSG {
|
||||||
|
return bot.CQHandleQuickOperation(p.Get("context"), p.Get("operation"))
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user