mirror of
https://github.com/Mrs4s/go-cqhttp.git
synced 2025-06-30 11:53:25 +00:00
Compare commits
24 Commits
v0.9.25-fi
...
v0.9.26
Author | SHA1 | Date | |
---|---|---|---|
9b41cd8ea2 | |||
e0ab2417c4 | |||
c7ab32fead | |||
8f5b8375a7 | |||
9049018d2f | |||
fffe64651a | |||
a9d53f038f | |||
cec81b7ad8 | |||
dddb3d2299 | |||
f6d37d460c | |||
aca6a3cf28 | |||
d390dd539b | |||
3269387163 | |||
cd09a68e0d | |||
d2d408a8e9 | |||
995737b0b8 | |||
72d62ad7c3 | |||
387d33a01b | |||
65811d4e22 | |||
01dd760b5c | |||
c31169b99b | |||
b5b6117487 | |||
9b77f09d2f | |||
ec45d04c81 |
31
coolq/api.go
31
coolq/api.go
@ -125,6 +125,7 @@ func (bot *CQBot) CQSendGroupMessage(groupId int64, i interface{}, autoEscape bo
|
||||
if mid == -1 {
|
||||
return Failed(100)
|
||||
}
|
||||
log.Infof("发送群 %v(%v) 的消息: %v (%v)", groupId, groupId, m.String(), mid)
|
||||
return OK(MSG{"message_id": mid})
|
||||
}
|
||||
str = func() string {
|
||||
@ -151,6 +152,7 @@ func (bot *CQBot) CQSendGroupMessage(groupId int64, i interface{}, autoEscape bo
|
||||
if mid == -1 {
|
||||
return Failed(100)
|
||||
}
|
||||
log.Infof("发送群 %v(%v) 的消息: %v (%v)", groupId, groupId, str, mid)
|
||||
return OK(MSG{"message_id": mid})
|
||||
}
|
||||
|
||||
@ -247,6 +249,7 @@ func (bot *CQBot) CQSendPrivateMessage(userId int64, i interface{}, autoEscape b
|
||||
if mid == -1 {
|
||||
return Failed(100)
|
||||
}
|
||||
log.Infof("发送好友 %v(%v) 的消息: %v (%v)", userId, userId, m.String(), mid)
|
||||
return OK(MSG{"message_id": mid})
|
||||
}
|
||||
str = func() string {
|
||||
@ -271,6 +274,7 @@ func (bot *CQBot) CQSendPrivateMessage(userId int64, i interface{}, autoEscape b
|
||||
if mid == -1 {
|
||||
return Failed(100)
|
||||
}
|
||||
log.Infof("发送好友 %v(%v) 的消息: %v (%v)", userId, userId, str, mid)
|
||||
return OK(MSG{"message_id": mid})
|
||||
}
|
||||
|
||||
@ -648,11 +652,38 @@ func (bot *CQBot) CQCanSendRecord() MSG {
|
||||
return OK(MSG{"yes": true})
|
||||
}
|
||||
|
||||
func (bot *CQBot) CQOcrImage(imageId string) MSG {
|
||||
img, err := bot.makeImageElem("image", map[string]string{"file": imageId}, true)
|
||||
if err != nil {
|
||||
log.Warnf("load image error: %v", err)
|
||||
return Failed(100)
|
||||
}
|
||||
rsp, err := bot.Client.ImageOcr(img)
|
||||
if err != nil {
|
||||
log.Warnf("ocr image error: %v", err)
|
||||
return Failed(100)
|
||||
}
|
||||
return OK(rsp)
|
||||
}
|
||||
|
||||
func (bot *CQBot) CQReloadEventFilter() MSG {
|
||||
global.BootFilter()
|
||||
return OK(nil)
|
||||
}
|
||||
|
||||
func (bot *CQBot) CQSetGroupPortrait(groupId int64, file, cache string) MSG {
|
||||
if g := bot.Client.FindGroup(groupId); g != nil {
|
||||
img, err := global.FindFile(file, cache, global.IMAGE_PATH)
|
||||
if err != nil {
|
||||
log.Warnf("set group portrait error: %v", err)
|
||||
return Failed(100)
|
||||
}
|
||||
g.UpdateGroupHeadPortrait(img)
|
||||
return OK(nil)
|
||||
}
|
||||
return Failed(100)
|
||||
}
|
||||
|
||||
func (bot *CQBot) CQGetStatus() MSG {
|
||||
return OK(MSG{
|
||||
"app_initialized": true,
|
||||
|
@ -58,8 +58,6 @@ func ToArrayMessage(e []message.IMessageElement, code int64, raw ...bool) (r []M
|
||||
"type": "text",
|
||||
"data": map[string]string{"text": o.Content},
|
||||
}
|
||||
case *message.ReplyElement:
|
||||
continue
|
||||
case *message.LightAppElement:
|
||||
//m = MSG{
|
||||
// "type": "text",
|
||||
@ -144,6 +142,8 @@ func ToArrayMessage(e []message.IMessageElement, code int64, raw ...bool) (r []M
|
||||
"data": map[string]string{"data": o.Content, "resid": fmt.Sprintf("%d", o.Id)},
|
||||
}
|
||||
}
|
||||
default:
|
||||
continue
|
||||
}
|
||||
r = append(r, m)
|
||||
}
|
||||
@ -338,41 +338,9 @@ func (bot *CQBot) ToElement(t string, d map[string]string, group bool) (message.
|
||||
return nil, errors.New("private voice unsupported now")
|
||||
}
|
||||
f := d["file"]
|
||||
var data []byte
|
||||
if strings.HasPrefix(f, "http") || strings.HasPrefix(f, "https") {
|
||||
b, err := global.GetBytes(f)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
data = b
|
||||
}
|
||||
if strings.HasPrefix(f, "base64") {
|
||||
b, err := base64.StdEncoding.DecodeString(strings.ReplaceAll(f, "base64://", ""))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
data = b
|
||||
}
|
||||
if strings.HasPrefix(f, "file") {
|
||||
fu, err := url.Parse(f)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if strings.HasPrefix(fu.Path, "/") && runtime.GOOS == `windows` {
|
||||
fu.Path = fu.Path[1:]
|
||||
}
|
||||
b, err := ioutil.ReadFile(fu.Path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
data = b
|
||||
}
|
||||
if global.PathExists(path.Join(global.VOICE_PATH, f)) {
|
||||
b, err := ioutil.ReadFile(path.Join(global.VOICE_PATH, f))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
data = b
|
||||
data, err := global.FindFile(f, d["cache"], global.VOICE_PATH)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !global.IsAMRorSILK(data) {
|
||||
return nil, errors.New("unsupported voice file format (please use AMR file for now)")
|
||||
|
@ -164,9 +164,9 @@ Type: `xml`
|
||||
|
||||
示例: `[CQ:xml,data=xxxx]`
|
||||
|
||||
####一些xml样例
|
||||
#### 一些xml样例
|
||||
|
||||
####ps:重要:xml中的value部分,记得html实体化处理后,再打加入到cq码中
|
||||
#### ps:重要:xml中的value部分,记得html实体化处理后,再打加入到cq码中
|
||||
|
||||
#### qq音乐
|
||||
|
||||
|
@ -7,7 +7,6 @@ go-cqhttp 默认生成的文件树如下所示:
|
||||
├── go-cqhttp
|
||||
├── config.json
|
||||
├── device.json
|
||||
├── servers.bin
|
||||
├── logs
|
||||
│ └── xx-xx-xx.log
|
||||
└── data
|
||||
@ -21,7 +20,6 @@ go-cqhttp 默认生成的文件树如下所示:
|
||||
| go-cqhttp | go-cqhttp可执行文件 |
|
||||
| config.json | 运行配置文件 |
|
||||
| device.json | 虚拟设备配置文件 |
|
||||
| servers.bin | 储存QQ服务器地址 |
|
||||
| logs | 日志存放目录 |
|
||||
| data | 数据目录 |
|
||||
| data/images | 图片缓存目录 |
|
||||
|
@ -1,3 +1,3 @@
|
||||
# 开始
|
||||
|
||||
欢迎来到 go-cqhttp 文档
|
||||
欢迎来到 go-cqhttp 文档 目前还在咕
|
52
global/fs.go
52
global/fs.go
@ -2,11 +2,17 @@ package global
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/md5"
|
||||
"encoding/base64"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"io/ioutil"
|
||||
"net/url"
|
||||
"os"
|
||||
"path"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"runtime"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -45,3 +51,45 @@ func Check(err error) {
|
||||
func IsAMRorSILK(b []byte) bool {
|
||||
return bytes.HasPrefix(b, HEADER_AMR) || bytes.HasPrefix(b, HEADER_SILK)
|
||||
}
|
||||
|
||||
func FindFile(f, cache, PATH string) (data []byte, err error) {
|
||||
data, err = nil, errors.New("can't find the file: "+f)
|
||||
if strings.HasPrefix(f, "http") || strings.HasPrefix(f, "https") {
|
||||
if cache == "" {
|
||||
cache = "1"
|
||||
}
|
||||
hash := md5.Sum([]byte(f))
|
||||
cacheFile := path.Join(CACHE_PATH, hex.EncodeToString(hash[:])+".cache")
|
||||
if PathExists(cacheFile) && cache == "1" {
|
||||
return ioutil.ReadFile(cacheFile)
|
||||
}
|
||||
data, err = GetBytes(f)
|
||||
_ = ioutil.WriteFile(cacheFile, data, 0644)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else if strings.HasPrefix(f, "base64") {
|
||||
data, err = base64.StdEncoding.DecodeString(strings.ReplaceAll(f, "base64://", ""))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else if strings.HasPrefix(f, "file") {
|
||||
fu, err := url.Parse(f)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if strings.HasPrefix(fu.Path, "/") && runtime.GOOS == `windows` {
|
||||
fu.Path = fu.Path[1:]
|
||||
}
|
||||
data, err = ioutil.ReadFile(fu.Path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else if PathExists(path.Join(PATH, f)) {
|
||||
data, err = ioutil.ReadFile(path.Join(PATH, f))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
4
go.mod
4
go.mod
@ -3,7 +3,7 @@ module github.com/Mrs4s/go-cqhttp
|
||||
go 1.14
|
||||
|
||||
require (
|
||||
github.com/Mrs4s/MiraiGo v0.0.0-20200919153352-249af274638d
|
||||
github.com/Mrs4s/MiraiGo v0.0.0-20200926101830-afb0ed6368ad
|
||||
github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239 // indirect
|
||||
github.com/gin-gonic/gin v1.6.3
|
||||
github.com/go-playground/validator/v10 v10.3.0 // indirect
|
||||
@ -25,7 +25,7 @@ require (
|
||||
github.com/xujiajun/nutsdb v0.5.0
|
||||
github.com/yinghau76/go-ascii-art v0.0.0-20190517192627-e7f465a30189
|
||||
golang.org/x/net v0.0.0-20200904194848-62affa334b73 // indirect
|
||||
golang.org/x/sys v0.0.0-20200909081042-eff7692f9009 // indirect
|
||||
golang.org/x/sys v0.0.0-20200916084744-dbad9cb7cb7a // indirect
|
||||
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e
|
||||
gopkg.in/yaml.v2 v2.3.0 // indirect
|
||||
)
|
||||
|
10
go.sum
10
go.sum
@ -1,9 +1,9 @@
|
||||
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/Mrs4s/MiraiGo v0.0.0-20200919083021-4013c077186d h1:LZ1pjJJ7sD/AOL8tvkTB9bPc0DiOErCNN+wWXUMyvX0=
|
||||
github.com/Mrs4s/MiraiGo v0.0.0-20200919083021-4013c077186d/go.mod h1:cwYPI2uq6nxNbx0nA6YuAKF1V5szSs6FPlGVLQvRUlo=
|
||||
github.com/Mrs4s/MiraiGo v0.0.0-20200919153352-249af274638d h1:nGJSE9xQBeDiugBKKX0vUOq51MqlUEm/y2FMfZFH/w4=
|
||||
github.com/Mrs4s/MiraiGo v0.0.0-20200919153352-249af274638d/go.mod h1:cwYPI2uq6nxNbx0nA6YuAKF1V5szSs6FPlGVLQvRUlo=
|
||||
github.com/Mrs4s/MiraiGo v0.0.0-20200921142226-9a449519db5c h1:TpGiSjI8Pe0YLEQPAVkOV37OFLeJnQ6jxvcDSb/LESY=
|
||||
github.com/Mrs4s/MiraiGo v0.0.0-20200921142226-9a449519db5c/go.mod h1:cwYPI2uq6nxNbx0nA6YuAKF1V5szSs6FPlGVLQvRUlo=
|
||||
github.com/Mrs4s/MiraiGo v0.0.0-20200926101830-afb0ed6368ad h1:m4KU2n3desxr1L3Idk7qRlf71+77rm0JEMWqd4gmrlQ=
|
||||
github.com/Mrs4s/MiraiGo v0.0.0-20200926101830-afb0ed6368ad/go.mod h1:cwYPI2uq6nxNbx0nA6YuAKF1V5szSs6FPlGVLQvRUlo=
|
||||
github.com/bwmarrin/snowflake v0.3.0 h1:xm67bEhkKh6ij1790JB83OujPR5CzNe8QuQqAgISZN0=
|
||||
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=
|
||||
@ -142,6 +142,8 @@ golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200909081042-eff7692f9009 h1:W0lCpv29Hv0UaM1LXb9QlBHLNP8UFfcKjblhVCWftOM=
|
||||
golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200916084744-dbad9cb7cb7a h1:chkwkn8HYWVtTE5DCQNKYlkyptadXYY0+PuyaVdyMo4=
|
||||
golang.org/x/sys v0.0.0-20200916084744-dbad9cb7cb7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e h1:EHBhcS0mlXEAVwNyO2dLfjToGsyY4j24pTs2ScHnX7s=
|
||||
|
24
main.go
24
main.go
@ -10,7 +10,6 @@ import (
|
||||
"image"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"os"
|
||||
"os/signal"
|
||||
"path"
|
||||
@ -237,29 +236,8 @@ func main() {
|
||||
}
|
||||
})
|
||||
cli.OnServerUpdated(func(bot *client.QQClient, e *client.ServerUpdatedEvent) {
|
||||
log.Infof("收到服务器地址更新通知, 将在下一次重连时应用. 地址信息已储存到 servers.bin 文件")
|
||||
_ = ioutil.WriteFile("servers.bin", binary.NewWriterF(func(w *binary.Writer) {
|
||||
w.WriteUInt16(uint16(len(e.Servers)))
|
||||
for _, s := range e.Servers {
|
||||
if !strings.Contains(s.Server, "com") {
|
||||
w.WriteString(s.Server)
|
||||
w.WriteUInt16(uint16(s.Port))
|
||||
}
|
||||
}
|
||||
}), 0644)
|
||||
log.Infof("收到服务器地址更新通知, 将在下一次重连时应用. ")
|
||||
})
|
||||
if global.PathExists("servers.bin") {
|
||||
if data, err := ioutil.ReadFile("servers.bin"); err == nil {
|
||||
r := binary.NewReader(data)
|
||||
var addr []*net.TCPAddr
|
||||
for i := 0; i < int(r.ReadUInt16()); i++ {
|
||||
addr = append(addr, &net.TCPAddr{
|
||||
IP: net.ParseIP(r.ReadString()),
|
||||
Port: int(r.ReadUInt16()),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
rsp, err := cli.Login()
|
||||
for {
|
||||
global.Check(err)
|
||||
|
@ -349,6 +349,18 @@ func (s *httpServer) HandleQuickOperation(c *gin.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
func (s *httpServer) OcrImage(c *gin.Context) {
|
||||
img := getParam(c, "image")
|
||||
c.JSON(200, s.bot.CQOcrImage(img))
|
||||
}
|
||||
|
||||
func (s *httpServer) SetGroupPortrait(c *gin.Context) {
|
||||
gid, _ := strconv.ParseInt(getParam(c, "group_id"), 10, 64)
|
||||
file := getParam(c, "file")
|
||||
cache := getParam(c, "cache")
|
||||
c.JSON(200, s.bot.CQSetGroupPortrait(gid, file, cache))
|
||||
}
|
||||
|
||||
func getParamOrDefault(c *gin.Context, k, def string) string {
|
||||
r := getParam(c, k)
|
||||
if r != "" {
|
||||
@ -497,7 +509,13 @@ var httpApi = map[string]func(s *httpServer, c *gin.Context){
|
||||
"reload_event_filter": func(s *httpServer, c *gin.Context) {
|
||||
s.ReloadEventFilter(c)
|
||||
},
|
||||
"set_group_portrait": func(s *httpServer, c *gin.Context) {
|
||||
s.SetGroupPortrait(c)
|
||||
},
|
||||
".handle_quick_operation": func(s *httpServer, c *gin.Context) {
|
||||
s.HandleQuickOperation(c)
|
||||
},
|
||||
".ocr_image": func(s *httpServer, c *gin.Context) {
|
||||
s.OcrImage(c)
|
||||
},
|
||||
}
|
||||
|
@ -501,6 +501,12 @@ var wsApi = map[string]func(*coolq.CQBot, gjson.Result) coolq.MSG{
|
||||
"reload_event_filter": func(bot *coolq.CQBot, p gjson.Result) coolq.MSG {
|
||||
return bot.CQReloadEventFilter()
|
||||
},
|
||||
".ocr_image": func(bot *coolq.CQBot, p gjson.Result) coolq.MSG {
|
||||
return bot.CQOcrImage(p.Get("image").Str)
|
||||
},
|
||||
"set_group_portrait": func(bot *coolq.CQBot, p gjson.Result) coolq.MSG {
|
||||
return bot.CQSetGroupPortrait(p.Get("group_id").Int(), p.Get("file").String(), p.Get("cache").String())
|
||||
},
|
||||
".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