mirror of
https://github.com/Mrs4s/go-cqhttp.git
synced 2025-06-30 03:43:25 +00:00
Compare commits
17 Commits
v0.9.21-fi
...
v0.9.22
Author | SHA1 | Date | |
---|---|---|---|
174ebfae9d | |||
02355db0f1 | |||
bda02d895a | |||
5fe15163f8 | |||
174bb0bbe1 | |||
e319f2645e | |||
52c911056e | |||
ac97c04cef | |||
801fa9a204 | |||
17f8232a1c | |||
cb9436601f | |||
03cc0dba95 | |||
248ba84a0c | |||
8874ed0392 | |||
9acf598209 | |||
15085d0a6b | |||
65acc888fd |
1
.gitignore
vendored
1
.gitignore
vendored
@ -1 +1,2 @@
|
|||||||
vendor/
|
vendor/
|
||||||
|
.idea
|
||||||
|
11
coolq/bot.go
11
coolq/bot.go
@ -10,6 +10,7 @@ import (
|
|||||||
"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"
|
||||||
"github.com/xujiajun/nutsdb"
|
"github.com/xujiajun/nutsdb"
|
||||||
"hash/crc32"
|
"hash/crc32"
|
||||||
"path"
|
"path"
|
||||||
@ -30,6 +31,8 @@ type CQBot struct {
|
|||||||
|
|
||||||
type MSG map[string]interface{}
|
type MSG map[string]interface{}
|
||||||
|
|
||||||
|
var ForceFragmented = false
|
||||||
|
|
||||||
func NewQQBot(cli *client.QQClient, conf *global.JsonConfig) *CQBot {
|
func NewQQBot(cli *client.QQClient, conf *global.JsonConfig) *CQBot {
|
||||||
bot := &CQBot{
|
bot := &CQBot{
|
||||||
Client: cli,
|
Client: cli,
|
||||||
@ -127,7 +130,7 @@ func (bot *CQBot) SendGroupMessage(groupId int64, m *message.SendingMessage) int
|
|||||||
newElem = append(newElem, elem)
|
newElem = append(newElem, elem)
|
||||||
}
|
}
|
||||||
m.Elements = newElem
|
m.Elements = newElem
|
||||||
ret := bot.Client.SendGroupMessage(groupId, m)
|
ret := bot.Client.SendGroupMessage(groupId, m, ForceFragmented)
|
||||||
if ret == nil || ret.Id == -1 {
|
if ret == nil || ret.Id == -1 {
|
||||||
log.Warnf("群消息发送失败: 账号可能被风控.")
|
log.Warnf("群消息发送失败: 账号可能被风控.")
|
||||||
return -1
|
return -1
|
||||||
@ -208,6 +211,12 @@ func (bot *CQBot) Release() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (bot *CQBot) dispatchEventMessage(m MSG) {
|
func (bot *CQBot) dispatchEventMessage(m MSG) {
|
||||||
|
payload := gjson.Parse(m.ToJson())
|
||||||
|
filter := global.GetFilter()
|
||||||
|
if filter != nil && (*filter).Eval(payload) == false {
|
||||||
|
log.Debug("Event filtered!")
|
||||||
|
return
|
||||||
|
}
|
||||||
for _, f := range bot.events {
|
for _, f := range bot.events {
|
||||||
fn := f
|
fn := f
|
||||||
go func() {
|
go func() {
|
||||||
|
@ -6,11 +6,6 @@ import (
|
|||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/Mrs4s/MiraiGo/binary"
|
|
||||||
"github.com/Mrs4s/MiraiGo/message"
|
|
||||||
"github.com/Mrs4s/go-cqhttp/global"
|
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
"github.com/tidwall/gjson"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/url"
|
"net/url"
|
||||||
"path"
|
"path"
|
||||||
@ -18,12 +13,20 @@ import (
|
|||||||
"runtime"
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/Mrs4s/MiraiGo/binary"
|
||||||
|
"github.com/Mrs4s/MiraiGo/message"
|
||||||
|
"github.com/Mrs4s/go-cqhttp/global"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
"github.com/tidwall/gjson"
|
||||||
)
|
)
|
||||||
|
|
||||||
var matchReg = regexp.MustCompile(`\[CQ:\w+?.*?]`)
|
var matchReg = regexp.MustCompile(`\[CQ:\w+?.*?]`)
|
||||||
var typeReg = regexp.MustCompile(`\[CQ:(\w+)`)
|
var typeReg = regexp.MustCompile(`\[CQ:(\w+)`)
|
||||||
var paramReg = regexp.MustCompile(`,([\w\-.]+?)=([^,\]]+)`)
|
var paramReg = regexp.MustCompile(`,([\w\-.]+?)=([^,\]]+)`)
|
||||||
|
|
||||||
|
var IgnoreInvalidCQCode = false
|
||||||
|
|
||||||
func ToArrayMessage(e []message.IMessageElement, code int64, raw ...bool) (r []MSG) {
|
func ToArrayMessage(e []message.IMessageElement, code int64, raw ...bool) (r []MSG) {
|
||||||
ur := false
|
ur := false
|
||||||
if len(raw) != 0 {
|
if len(raw) != 0 {
|
||||||
@ -198,8 +201,12 @@ func (bot *CQBot) ConvertStringMessage(m string, group bool) (r []message.IMessa
|
|||||||
}
|
}
|
||||||
elem, err := bot.ToElement(t, d, group)
|
elem, err := bot.ToElement(t, d, group)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warnf("转换CQ码到MiraiGo Element时出现错误: %v 将原样发送.", err)
|
if !IgnoreInvalidCQCode {
|
||||||
r = append(r, message.NewText(code))
|
log.Warnf("转换CQ码 %v 到MiraiGo Element时出现错误: %v 将原样发送.", code, err)
|
||||||
|
r = append(r, message.NewText(code))
|
||||||
|
} else {
|
||||||
|
log.Warnf("转换CQ码 %v 到MiraiGo Element时出现错误: %v 将忽略.", code, err)
|
||||||
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
r = append(r, elem)
|
r = append(r, elem)
|
||||||
@ -329,6 +336,7 @@ func (bot *CQBot) ToElement(t string, d map[string]string, group bool) (message.
|
|||||||
}
|
}
|
||||||
var size int32
|
var size int32
|
||||||
var hash []byte
|
var hash []byte
|
||||||
|
var url string
|
||||||
if path.Ext(rawPath) == ".cqimg" {
|
if path.Ext(rawPath) == ".cqimg" {
|
||||||
for _, line := range strings.Split(global.ReadAllText(rawPath), "\n") {
|
for _, line := range strings.Split(global.ReadAllText(rawPath), "\n") {
|
||||||
kv := strings.SplitN(line, "=", 2)
|
kv := strings.SplitN(line, "=", 2)
|
||||||
@ -344,8 +352,13 @@ func (bot *CQBot) ToElement(t string, d map[string]string, group bool) (message.
|
|||||||
r := binary.NewReader(b)
|
r := binary.NewReader(b)
|
||||||
hash = r.ReadBytes(16)
|
hash = r.ReadBytes(16)
|
||||||
size = r.ReadInt32()
|
size = r.ReadInt32()
|
||||||
|
r.ReadString()
|
||||||
|
url = r.ReadString()
|
||||||
}
|
}
|
||||||
if size == 0 {
|
if size == 0 {
|
||||||
|
if url != "" {
|
||||||
|
return bot.ToElement(t, map[string]string{"file": url}, group)
|
||||||
|
}
|
||||||
return nil, errors.New("img size is 0")
|
return nil, errors.New("img size is 0")
|
||||||
}
|
}
|
||||||
if len(hash) != 16 {
|
if len(hash) != 16 {
|
||||||
@ -447,6 +460,27 @@ func (bot *CQBot) ToElement(t string, d map[string]string, group bool) (message.
|
|||||||
SubType: "music",
|
SubType: "music",
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
if d["type"] == "163" {
|
||||||
|
info, err := global.NeteaseMusicSongInfo(d["id"])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if !info.Exists() {
|
||||||
|
return nil, errors.New("song not found")
|
||||||
|
}
|
||||||
|
name := info.Get("name").Str
|
||||||
|
artistName := ""
|
||||||
|
if info.Get("artists.0").Exists() {
|
||||||
|
artistName = info.Get("artists.0.name").Str
|
||||||
|
}
|
||||||
|
xml := fmt.Sprintf(`<?xml version='1.0' encoding='UTF-8' standalone='yes' ?><msg serviceID="2" templateID="1" action="web" brief="[分享] %s" sourceMsgId="0" url="http://music.163.com/m/song/%s" flag="0" adverSign="0" multiMsgFlag="0"><item layout="2"><audio cover="%s?param=90y90" src="https://music.163.com/song/media/outer/url?id=%s.mp3" /><title>%s</title><summary>%s</summary></item><source name="网易云音乐" icon="https://pic.rmb.bdstatic.com/911423bee2bef937975b29b265d737b3.png" url="http://web.p.qq.com/qqmpmobile/aio/app.html?id=1101079856" action="app" a_actionData="com.netease.cloudmusic" i_actionData="tencent100495085://" appid="100495085" /></msg>`,
|
||||||
|
name, d["id"], info.Get("album.picUrl").Str, d["id"], name, artistName)
|
||||||
|
return &message.ServiceElement{
|
||||||
|
Id: 60,
|
||||||
|
Content: xml,
|
||||||
|
SubType: "music",
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
if d["type"] == "custom" {
|
if d["type"] == "custom" {
|
||||||
xml := fmt.Sprintf(`<?xml version='1.0' encoding='UTF-8' standalone='yes' ?><msg serviceID="2" templateID="1" action="web" brief="[分享] %s" sourceMsgId="0" url="%s" flag="0" adverSign="0" multiMsgFlag="0"><item layout="2"><audio cover="%s" src="%s"/><title>%s</title><summary>%s</summary></item><source name="音乐" icon="https://i.gtimg.cn/open/app_icon/01/07/98/56/1101079856_100_m.png" url="http://web.p.qq.com/qqmpmobile/aio/app.html?id=1101079856" action="app" a_actionData="com.tencent.qqmusic" i_actionData="tencent1101079856://" appid="1101079856" /></msg>`,
|
xml := fmt.Sprintf(`<?xml version='1.0' encoding='UTF-8' standalone='yes' ?><msg serviceID="2" templateID="1" action="web" brief="[分享] %s" sourceMsgId="0" url="%s" flag="0" adverSign="0" multiMsgFlag="0"><item layout="2"><audio cover="%s" src="%s"/><title>%s</title><summary>%s</summary></item><source name="音乐" icon="https://i.gtimg.cn/open/app_icon/01/07/98/56/1101079856_100_m.png" url="http://web.p.qq.com/qqmpmobile/aio/app.html?id=1101079856" action="app" a_actionData="com.tencent.qqmusic" i_actionData="tencent1101079856://" appid="1101079856" /></msg>`,
|
||||||
d["title"], d["url"], d["image"], d["audio"], d["title"], d["content"])
|
d["title"], d["url"], d["image"], d["audio"], d["title"], d["content"])
|
||||||
@ -457,6 +491,13 @@ func (bot *CQBot) ToElement(t string, d map[string]string, group bool) (message.
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
return nil, errors.New("unsupported music type: " + d["type"])
|
return nil, errors.New("unsupported music type: " + d["type"])
|
||||||
|
case "xml":
|
||||||
|
resId := d["resid"]
|
||||||
|
template := CQCodeEscapeValue(d["data"])
|
||||||
|
//println(template)
|
||||||
|
i, _ := strconv.ParseInt(resId, 10, 64)
|
||||||
|
msg := global.NewXmlMsg(template, i)
|
||||||
|
return msg, nil
|
||||||
default:
|
default:
|
||||||
return nil, errors.New("unsupported cq code: " + t)
|
return nil, errors.New("unsupported cq code: " + t)
|
||||||
}
|
}
|
||||||
|
@ -25,12 +25,14 @@ go-cqhttp 支持导入CQHTTP的配置文件, 具体步骤为:
|
|||||||
"relogin": false,
|
"relogin": false,
|
||||||
"relogin_delay": 0,
|
"relogin_delay": 0,
|
||||||
"post_message_format": "string",
|
"post_message_format": "string",
|
||||||
|
"ignore_invalid_cqcode": false,
|
||||||
|
"force_fragmented": true,
|
||||||
"http_config": {
|
"http_config": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"host": "0.0.0.0",
|
"host": "0.0.0.0",
|
||||||
"port": 5700,
|
"port": 5700,
|
||||||
"timeout": 5,
|
"timeout": 5,
|
||||||
"post_urls": {"url:port": "secret"},
|
"post_urls": {"url:port": "secret"}
|
||||||
},
|
},
|
||||||
"ws_config": {
|
"ws_config": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
@ -51,18 +53,23 @@ go-cqhttp 支持导入CQHTTP的配置文件, 具体步骤为:
|
|||||||
|
|
||||||
| 字段 | 类型 | 说明 |
|
| 字段 | 类型 | 说明 |
|
||||||
| ------------------ | -------- | ------------------------------------------------------------------- |
|
| ------------------ | -------- | ------------------------------------------------------------------- |
|
||||||
| uin | int64 | 登录用QQ号 |
|
| uin | int64 | 登录用QQ号 |
|
||||||
| password | string | 登录用密码 |
|
| password | string | 登录用密码 |
|
||||||
| encrypt_password | bool | 是否对密码进行加密. |
|
| encrypt_password | bool | 是否对密码进行加密. |
|
||||||
| password_encrypted | string | 加密后的密码(请勿修改) |
|
| password_encrypted | string | 加密后的密码(请勿修改) |
|
||||||
| enable_db | bool | 是否开启内置数据库, 关闭后将无法使用 **回复/撤回** 等上下文相关接口 |
|
| enable_db | bool | 是否开启内置数据库, 关闭后将无法使用 **回复/撤回** 等上下文相关接口 |
|
||||||
| access_token | string | 同CQHTTP的 `access_token` 用于身份验证 |
|
| access_token | string | 同CQHTTP的 `access_token` 用于身份验证 |
|
||||||
| relogin | bool | 是否自动重新登录 |
|
| relogin | bool | 是否自动重新登录 |
|
||||||
| relogin_delay | int | 重登录延时(秒) |
|
| relogin_delay | int | 重登录延时(秒) |
|
||||||
| http_config | object | HTTP API配置 |
|
| post_message_format | string | 上报信息类型 |
|
||||||
| ws_config | object | Websocket API 配置 |
|
| ignore_invalid_cqcode| bool | 是否忽略错误的CQ码 |
|
||||||
| ws_reverse_servers | object[] | 反向 Websocket API 配置 |
|
| force_fragmented | bool | 是否强制分片发送群长消息 |
|
||||||
|
| http_config | object | HTTP API配置 |
|
||||||
|
| ws_config | object | Websocket API 配置 |
|
||||||
|
| ws_reverse_servers | object[] | 反向 Websocket API 配置 |
|
||||||
|
|
||||||
> 注: 开启密码加密后程序将在每次启动时要求输入解密密钥, 密钥错误会导致登录时提示密码错误.
|
> 注: 开启密码加密后程序将在每次启动时要求输入解密密钥, 密钥错误会导致登录时提示密码错误.
|
||||||
> 解密后密码将储存在内存中,用于自动重连等功能. 所以此加密并不能防止内存读取.
|
> 解密后密码将储存在内存中,用于自动重连等功能. 所以此加密并不能防止内存读取.
|
||||||
> 解密密钥在使用完成后并不会留存在内存中, 所以可用相对简单的字符串作为密钥
|
> 解密密钥在使用完成后并不会留存在内存中, 所以可用相对简单的字符串作为密钥
|
||||||
|
|
||||||
|
> 注2: 分片发送为原酷Q发送长消息的老方案, 发送速度更优/兼容性更好。关闭后将优先使用新方案, 能发送更长的消息, 但发送速度更慢,在部分老客户端将无法解析.
|
@ -119,6 +119,51 @@ Type: `node`
|
|||||||
]
|
]
|
||||||
````
|
````
|
||||||
|
|
||||||
|
### xml支持
|
||||||
|
|
||||||
|
Type: `xml`
|
||||||
|
|
||||||
|
范围: **发送**
|
||||||
|
|
||||||
|
参数:
|
||||||
|
|
||||||
|
| 参数名 | 类型 | 说明 |
|
||||||
|
| ------ | ------ | ------------------------------------------------------------ |
|
||||||
|
| data | string | xml内容,xml中的value部分,记得实体化处理|
|
||||||
|
| resid | int32 | 可以不填|
|
||||||
|
|
||||||
|
示例: `[CQ:xml,data=xxxx]`
|
||||||
|
|
||||||
|
####一些xml样例
|
||||||
|
####ps:重要:xml中的value部分,记得html实体化处理后,再打加入到cq码中
|
||||||
|
#### qq音乐
|
||||||
|
```xml
|
||||||
|
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?><msg serviceID="2" templateID="1" action="web" brief="[分享] 十年" sourceMsgId="0" url="https://i.y.qq.com/v8/playsong.html?_wv=1&songid=4830342&souce=qqshare&source=qqshare&ADTAG=qqshare" flag="0" adverSign="0" multiMsgFlag="0" ><item layout="2"><audio cover="http://imgcache.qq.com/music/photo/album_500/26/500_albumpic_89526_0.jpg" src="http://ws.stream.qqmusic.qq.com/C400003mAan70zUy5O.m4a?guid=1535153710&vkey=D5315B8C0603653592AD4879A8A3742177F59D582A7A86546E24DD7F282C3ACF81526C76E293E57EA1E42CF19881C561275D919233333ADE&uin=&fromtag=3" /><title>十年</title><summary>陈奕迅</summary></item><source name="QQ音乐" icon="https://i.gtimg.cn/open/app_icon/01/07/98/56/1101079856_100_m.png" url="http://web.p.qq.com/qqmpmobile/aio/app.html?id=1101079856" action="app" a_actionData="com.tencent.qqmusic" i_actionData="tencent1101079856://" appid="1101079856" /></msg>
|
||||||
|
```
|
||||||
|
#### 网易音乐
|
||||||
|
```xml
|
||||||
|
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?><msg serviceID="2" templateID="1" action="web" brief="[分享] 十年" sourceMsgId="0" url="http://music.163.com/m/song/409650368" flag="0" adverSign="0" multiMsgFlag="0" ><item layout="2"><audio cover="http://p2.music.126.net/g-Qgb9ibk9Wp_0HWra0xQQ==/16636710440565853.jpg?param=90y90" src="https://music.163.com/song/media/outer/url?id=409650368.mp3" /><title>十年</title><summary>黄梦之</summary></item><source name="网易云音乐" icon="https://pic.rmb.bdstatic.com/911423bee2bef937975b29b265d737b3.png" url="http://web.p.qq.com/qqmpmobile/aio/app.html?id=1101079856" action="app" a_actionData="com.netease.cloudmusic" i_actionData="tencent100495085://" appid="100495085" /></msg>
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 卡片消息1
|
||||||
|
```xml
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||||
|
<msg serviceID="1">
|
||||||
|
<item><title>生死8秒!女司机高速急刹,他一个操作救下一车性命</title></item>
|
||||||
|
<source name="官方认证消息" icon="https://qzs.qq.com/ac/qzone_v5/client/auth_icon.png" action="" appid="-1" />
|
||||||
|
</msg>
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 卡片消息2
|
||||||
|
```xml
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||||
|
<msg serviceID="1">
|
||||||
|
<item layout="4">
|
||||||
|
<title>test title</title>
|
||||||
|
<picture cover="http://url.cn/5CEwIUy"/>
|
||||||
|
</item>
|
||||||
|
</msg>
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
## API
|
## API
|
||||||
|
@ -6,19 +6,21 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type JsonConfig struct {
|
type JsonConfig struct {
|
||||||
Uin int64 `json:"uin"`
|
Uin int64 `json:"uin"`
|
||||||
Password string `json:"password"`
|
Password string `json:"password"`
|
||||||
EncryptPassword bool `json:"encrypt_password"`
|
EncryptPassword bool `json:"encrypt_password"`
|
||||||
PasswordEncrypted string `json:"password_encrypted"`
|
PasswordEncrypted string `json:"password_encrypted"`
|
||||||
EnableDB bool `json:"enable_db"`
|
EnableDB bool `json:"enable_db"`
|
||||||
AccessToken string `json:"access_token"`
|
AccessToken string `json:"access_token"`
|
||||||
ReLogin bool `json:"relogin"`
|
ReLogin bool `json:"relogin"`
|
||||||
ReLoginDelay int `json:"relogin_delay"`
|
ReLoginDelay int `json:"relogin_delay"`
|
||||||
HttpConfig *GoCQHttpConfig `json:"http_config"`
|
IgnoreInvalidCQCode bool `json:"ignore_invalid_cqcode"`
|
||||||
WSConfig *GoCQWebsocketConfig `json:"ws_config"`
|
ForceFragmented bool `json:"force_fragmented"`
|
||||||
ReverseServers []*GoCQReverseWebsocketConfig `json:"ws_reverse_servers"`
|
HttpConfig *GoCQHttpConfig `json:"http_config"`
|
||||||
PostMessageFormat string `json:"post_message_format"`
|
WSConfig *GoCQWebsocketConfig `json:"ws_config"`
|
||||||
Debug bool `json:"debug"`
|
ReverseServers []*GoCQReverseWebsocketConfig `json:"ws_reverse_servers"`
|
||||||
|
PostMessageFormat string `json:"post_message_format"`
|
||||||
|
Debug bool `json:"debug"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type CQHttpApiConfig struct {
|
type CQHttpApiConfig struct {
|
||||||
@ -68,6 +70,7 @@ func DefaultConfig() *JsonConfig {
|
|||||||
ReLogin: true,
|
ReLogin: true,
|
||||||
ReLoginDelay: 3,
|
ReLoginDelay: 3,
|
||||||
PostMessageFormat: "string",
|
PostMessageFormat: "string",
|
||||||
|
ForceFragmented: true,
|
||||||
HttpConfig: &GoCQHttpConfig{
|
HttpConfig: &GoCQHttpConfig{
|
||||||
Enabled: true,
|
Enabled: true,
|
||||||
Host: "0.0.0.0",
|
Host: "0.0.0.0",
|
||||||
|
@ -3,10 +3,14 @@ package global
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"compress/gzip"
|
"compress/gzip"
|
||||||
"github.com/tidwall/gjson"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/Mrs4s/MiraiGo/message"
|
||||||
|
"github.com/tidwall/gjson"
|
||||||
)
|
)
|
||||||
|
|
||||||
func GetBytes(url string) ([]byte, error) {
|
func GetBytes(url string) ([]byte, error) {
|
||||||
@ -41,3 +45,27 @@ func QQMusicSongInfo(id string) (gjson.Result, error) {
|
|||||||
}
|
}
|
||||||
return gjson.ParseBytes(d).Get("songinfo.data"), nil
|
return gjson.ParseBytes(d).Get("songinfo.data"), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NeteaseMusicSongInfo(id string) (gjson.Result, error) {
|
||||||
|
d, err := GetBytes(fmt.Sprintf("http://music.163.com/api/song/detail/?id=%s&ids=%%5B%s%%5D", id, id))
|
||||||
|
if err != nil {
|
||||||
|
return gjson.Result{}, err
|
||||||
|
}
|
||||||
|
return gjson.ParseBytes(d).Get("songs.0"), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewXmlMsg(template string, ResId int64) *message.ServiceElement {
|
||||||
|
var serviceid string
|
||||||
|
if ResId == 0 {
|
||||||
|
serviceid = "2" //默认值2
|
||||||
|
} else {
|
||||||
|
serviceid = strconv.FormatInt(ResId, 10)
|
||||||
|
}
|
||||||
|
//println(serviceid)
|
||||||
|
return &message.ServiceElement{
|
||||||
|
Id: int32(ResId),
|
||||||
|
Content: template,
|
||||||
|
ResId: serviceid,
|
||||||
|
SubType: "xml",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
2
go.mod
2
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-20200823075559-507fe33e842d
|
github.com/Mrs4s/MiraiGo v0.0.0-20200825052841-d3b0f5f9e839
|
||||||
github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239 // indirect
|
github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239 // indirect
|
||||||
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
|
||||||
|
4
go.sum
4
go.sum
@ -1,7 +1,7 @@
|
|||||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
github.com/Mrs4s/MiraiGo v0.0.0-20200823075559-507fe33e842d h1:F7ssNQDHqB7NZVwTeADRY+AxKT3eeSlBzfzeZYTUfxM=
|
github.com/Mrs4s/MiraiGo v0.0.0-20200825052841-d3b0f5f9e839 h1:TDhaPfWcubIMKDz1HU+N07SwIUjj7oVUQ7EXZBbDUxs=
|
||||||
github.com/Mrs4s/MiraiGo v0.0.0-20200823075559-507fe33e842d/go.mod h1:0je03wji/tSw4bUH4QCF2Z4/EjyNWjSJTyy5tliX6EM=
|
github.com/Mrs4s/MiraiGo v0.0.0-20200825052841-d3b0f5f9e839/go.mod h1:0je03wji/tSw4bUH4QCF2Z4/EjyNWjSJTyy5tliX6EM=
|
||||||
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=
|
||||||
|
12
main.go
12
main.go
@ -171,6 +171,16 @@ func main() {
|
|||||||
time.Sleep(time.Second * 5)
|
time.Sleep(time.Second * 5)
|
||||||
log.Info("开始尝试登录并同步消息...")
|
log.Info("开始尝试登录并同步消息...")
|
||||||
cli := client.NewClient(conf.Uin, conf.Password)
|
cli := client.NewClient(conf.Uin, conf.Password)
|
||||||
|
cli.OnLog(func(c *client.QQClient, e *client.LogEvent) {
|
||||||
|
switch e.Type {
|
||||||
|
case "INFO":
|
||||||
|
log.Info("Protocol -> " + e.Message)
|
||||||
|
case "ERROR":
|
||||||
|
log.Error("Protocol -> " + e.Message)
|
||||||
|
case "DEBUG":
|
||||||
|
log.Debug("Protocol -> " + e.Message)
|
||||||
|
}
|
||||||
|
})
|
||||||
rsp, err := cli.Login()
|
rsp, err := cli.Login()
|
||||||
for {
|
for {
|
||||||
global.Check(err)
|
global.Check(err)
|
||||||
@ -210,6 +220,8 @@ func main() {
|
|||||||
} else {
|
} else {
|
||||||
coolq.SetMessageFormat(conf.PostMessageFormat)
|
coolq.SetMessageFormat(conf.PostMessageFormat)
|
||||||
}
|
}
|
||||||
|
coolq.IgnoreInvalidCQCode = conf.IgnoreInvalidCQCode
|
||||||
|
coolq.ForceFragmented = conf.ForceFragmented
|
||||||
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 {
|
||||||
|
@ -400,6 +400,7 @@ func getParamOrDefault(c *gin.Context, k, def string) string {
|
|||||||
return def
|
return def
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func getParam(c *gin.Context, k string) string {
|
func getParam(c *gin.Context, k string) string {
|
||||||
p, _ := getParamWithType(c, k)
|
p, _ := getParamWithType(c, k)
|
||||||
return p
|
return p
|
||||||
|
@ -172,12 +172,6 @@ func (c *websocketClient) listenApi(conn *websocketConn, u bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *websocketClient) onBotPushEvent(m coolq.MSG) {
|
func (c *websocketClient) onBotPushEvent(m coolq.MSG) {
|
||||||
payload := gjson.Parse(m.ToJson())
|
|
||||||
filter := global.GetFilter()
|
|
||||||
if filter != nil && (*filter).Eval(payload) == false {
|
|
||||||
log.Debug("Event filtered!")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if c.eventConn != nil {
|
if c.eventConn != nil {
|
||||||
log.Debugf("向WS服务器 %v 推送Event: %v", c.eventConn.RemoteAddr().String(), m.ToJson())
|
log.Debugf("向WS服务器 %v 推送Event: %v", c.eventConn.RemoteAddr().String(), m.ToJson())
|
||||||
conn := c.eventConn
|
conn := c.eventConn
|
||||||
|
Reference in New Issue
Block a user