mirror of
https://github.com/Mrs4s/go-cqhttp.git
synced 2025-05-05 03:23:49 +08:00
forward message sending supported.
This commit is contained in:
parent
b73aeb6666
commit
57153d2d4a
@ -18,7 +18,7 @@
|
|||||||
- [x] 修改群名
|
- [x] 修改群名
|
||||||
- [x] 消息撤回事件
|
- [x] 消息撤回事件
|
||||||
- [x] 解析/发送 回复消息
|
- [x] 解析/发送 回复消息
|
||||||
- [x] 解析合并转发
|
- [x] 解析/发送 合并转发
|
||||||
- [ ] 使用代理请求网络图片
|
- [ ] 使用代理请求网络图片
|
||||||
|
|
||||||
#### 实现
|
#### 实现
|
||||||
|
71
coolq/api.go
71
coolq/api.go
@ -12,6 +12,7 @@ import (
|
|||||||
"path"
|
"path"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// https://cqhttp.cc/docs/4.15/#/API?id=get_login_info-%E8%8E%B7%E5%8F%96%E7%99%BB%E5%BD%95%E5%8F%B7%E4%BF%A1%E6%81%AF
|
// https://cqhttp.cc/docs/4.15/#/API?id=get_login_info-%E8%8E%B7%E5%8F%96%E7%99%BB%E5%BD%95%E5%8F%B7%E4%BF%A1%E6%81%AF
|
||||||
@ -119,6 +120,76 @@ func (bot *CQBot) CQSendGroupMessage(groupId int64, m gjson.Result) MSG {
|
|||||||
return Failed(100)
|
return Failed(100)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (bot *CQBot) CQSendGroupForwardMessage(groupId int64, m gjson.Result) MSG {
|
||||||
|
if m.Type != gjson.JSON {
|
||||||
|
return Failed(100)
|
||||||
|
}
|
||||||
|
var nodes []*message.ForwardNode
|
||||||
|
ts := time.Now().Add(-time.Minute * 5)
|
||||||
|
hasCustom := func() bool {
|
||||||
|
for _, item := range m.Array() {
|
||||||
|
if item.Get("data.uin").Exists() {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}()
|
||||||
|
convert := func(e gjson.Result) {
|
||||||
|
if e.Get("type").Str != "node" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ts.Add(time.Second)
|
||||||
|
if e.Get("data.id").Exists() {
|
||||||
|
i, _ := strconv.Atoi(e.Get("data.id").Str)
|
||||||
|
m := bot.GetGroupMessage(int32(i))
|
||||||
|
if m != nil {
|
||||||
|
sender := m["sender"].(message.Sender)
|
||||||
|
nodes = append(nodes, &message.ForwardNode{
|
||||||
|
SenderId: sender.Uin,
|
||||||
|
SenderName: (&sender).DisplayName(),
|
||||||
|
Time: func() int32 {
|
||||||
|
if hasCustom {
|
||||||
|
return int32(ts.Unix())
|
||||||
|
}
|
||||||
|
return m["time"].(int32)
|
||||||
|
}(),
|
||||||
|
Message: bot.ConvertStringMessage(m["message"].(string), true),
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
log.Warnf("警告: 引用消息 %v 错误或数据库未开启.", e.Get("data.id").Str)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
uin, _ := strconv.ParseInt(e.Get("data.uin").Str, 10, 64)
|
||||||
|
name := e.Get("data.name").Str
|
||||||
|
content := bot.ConvertObjectMessage(e.Get("data.content"), true)
|
||||||
|
if uin != 0 && name != "" && len(content) > 0 {
|
||||||
|
nodes = append(nodes, &message.ForwardNode{
|
||||||
|
SenderId: uin,
|
||||||
|
SenderName: name,
|
||||||
|
Time: int32(ts.Unix()),
|
||||||
|
Message: content,
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
log.Warnf("警告: 非法 Forward node 将跳过")
|
||||||
|
}
|
||||||
|
if m.IsArray() {
|
||||||
|
for _, item := range m.Array() {
|
||||||
|
convert(item)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
convert(m)
|
||||||
|
}
|
||||||
|
if len(nodes) > 0 {
|
||||||
|
gm := bot.Client.SendGroupForwardMessage(groupId, &message.ForwardMessage{Nodes: nodes})
|
||||||
|
return OK(MSG{
|
||||||
|
"message_id": ToGlobalId(groupId, gm.Id),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return Failed(100)
|
||||||
|
}
|
||||||
|
|
||||||
// https://cqhttp.cc/docs/4.15/#/API?id=send_private_msg-%E5%8F%91%E9%80%81%E7%A7%81%E8%81%8A%E6%B6%88%E6%81%AF
|
// https://cqhttp.cc/docs/4.15/#/API?id=send_private_msg-%E5%8F%91%E9%80%81%E7%A7%81%E8%81%8A%E6%B6%88%E6%81%AF
|
||||||
func (bot *CQBot) CQSendPrivateMessage(userId int64, m gjson.Result) MSG {
|
func (bot *CQBot) CQSendPrivateMessage(userId int64, m gjson.Result) MSG {
|
||||||
if m.Type == gjson.String {
|
if m.Type == gjson.String {
|
||||||
|
@ -142,6 +142,9 @@ func (bot *CQBot) ConvertObjectMessage(m gjson.Result, group bool) (r []message.
|
|||||||
}
|
}
|
||||||
r = append(r, elem)
|
r = append(r, elem)
|
||||||
}
|
}
|
||||||
|
if m.Type == gjson.String {
|
||||||
|
return bot.ConvertStringMessage(m.Str, group)
|
||||||
|
}
|
||||||
if m.IsArray() {
|
if m.IsArray() {
|
||||||
for _, e := range m.Array() {
|
for _, e := range m.Array() {
|
||||||
convertElem(e)
|
convertElem(e)
|
||||||
|
120
docs/cqhttp.md
120
docs/cqhttp.md
@ -4,10 +4,122 @@
|
|||||||
|
|
||||||
## CQCode
|
## CQCode
|
||||||
|
|
||||||
| Code | 示例 | 说明 |
|
### 回复
|
||||||
| ------- | -------------------- | ------------------------------------------------------------ |
|
|
||||||
| reply | [CQ:reply,id=123456] | 回复ID为 `123456`的信息. 发送时一条 `message` 仅能使用一次 |
|
Type : `reply`
|
||||||
| forward | [CQ:forward,id=abcd] | ID为abcd的转发消息, 暂时仅能接收. 可通过 `/get_forward_msg` API获取具体信息 |
|
|
||||||
|
范围: **发送/接收**
|
||||||
|
|
||||||
|
参数:
|
||||||
|
|
||||||
|
| 参数名 | 类型 | 说明 |
|
||||||
|
| ------ | ---- | ------------------------------------- |
|
||||||
|
| id | int | 回复时所引用的消息id, 必须为本群消息. |
|
||||||
|
|
||||||
|
示例: `[CQ:reply,id=123456]`
|
||||||
|
|
||||||
|
### 合并转发
|
||||||
|
|
||||||
|
Type: `forward`
|
||||||
|
|
||||||
|
范围: **接收**
|
||||||
|
|
||||||
|
参数:
|
||||||
|
|
||||||
|
| 参数名 | 类型 | 说明 |
|
||||||
|
| ------ | ------ | ------------------------------------------------------------ |
|
||||||
|
| id | string | 合并转发ID, 需要通过 `/get_forward_msg` API获取转发的具体内容 |
|
||||||
|
|
||||||
|
示例: `[CQ:forward,id=xxxx]`
|
||||||
|
|
||||||
|
### 合并转发消息节点
|
||||||
|
|
||||||
|
Type: `node`
|
||||||
|
|
||||||
|
范围: **发送**
|
||||||
|
|
||||||
|
参数:
|
||||||
|
|
||||||
|
| 参数名 | 类型 | 说明 | 特殊说明 |
|
||||||
|
| ------- | ------- | -------------- | ------------------------------------------------------------ |
|
||||||
|
| id | int32 | 转发消息id | 直接引用他人的消息合并转发, 实际查看顺序为原消息发送顺序 **与下面的自定义消息二选一** |
|
||||||
|
| name | string | 发送者显示名字 | 用于自定义消息 (自定义消息并合并转发,实际查看顺序为自定义消息段顺序) |
|
||||||
|
| uin | int64 | 发送者QQ号 | 用于自定义消息 |
|
||||||
|
| content | message | 具体消息 | 用于自定义消息 **不支持转发套娃,不支持引用回复** |
|
||||||
|
|
||||||
|
特殊说明: **需要使用单独的API `/send_group_forward_msg` 发送,并且由于消息段较为复杂,仅支持Array形式入参。 如果引用消息和自定义消息同时出现,实际查看顺序将取消息段顺序. 另外按 [CQHTTP](https://cqhttp.cc/docs/4.15/#/Message?id=格式) 文档说明, `data` 应全为字符串, 但由于需要接收`message` 类型的消息, 所以 *仅限此Type的content字段* 支持Array套娃**
|
||||||
|
|
||||||
|
示例:
|
||||||
|
|
||||||
|
直接引用消息合并转发:
|
||||||
|
|
||||||
|
````json
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"type": "node",
|
||||||
|
"data": {
|
||||||
|
"id": "123"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "node",
|
||||||
|
"data": {
|
||||||
|
"id": "456"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
````
|
||||||
|
|
||||||
|
自定义消息合并转发:
|
||||||
|
|
||||||
|
````json
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"type": "node",
|
||||||
|
"data": {
|
||||||
|
"name": "消息发送者A",
|
||||||
|
"uin": "10086",
|
||||||
|
"content": [
|
||||||
|
{
|
||||||
|
"type": "text",
|
||||||
|
"data": {"text": "测试消息1"}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "node",
|
||||||
|
"data": {
|
||||||
|
"name": "消息发送者B",
|
||||||
|
"uin": "10087",
|
||||||
|
"content": "[CQ:image,file=xxxxx]测试消息2"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
````
|
||||||
|
|
||||||
|
引用自定义混合合并转发:
|
||||||
|
|
||||||
|
````json
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"type": "node",
|
||||||
|
"data": {
|
||||||
|
"name": "自定义发送者",
|
||||||
|
"uin": "10086",
|
||||||
|
"content": "我是自定义消息"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "node",
|
||||||
|
"data": {
|
||||||
|
"id": "123"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
````
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## API
|
## API
|
||||||
|
|
||||||
|
@ -97,6 +97,9 @@ func (s *httpServer) Run(addr, authToken string, bot *coolq.CQBot) {
|
|||||||
s.engine.Any("/send_group_msg", s.SendGroupMessage)
|
s.engine.Any("/send_group_msg", s.SendGroupMessage)
|
||||||
s.engine.Any("/send_group_msg_async", s.SendGroupMessage)
|
s.engine.Any("/send_group_msg_async", s.SendGroupMessage)
|
||||||
|
|
||||||
|
s.engine.Any("/send_group_forward_msg", s.SendGroupForwardMessage)
|
||||||
|
s.engine.Any("/send_group_forward_msg_async", s.SendGroupForwardMessage)
|
||||||
|
|
||||||
s.engine.Any("/delete_msg", s.DeleteMessage)
|
s.engine.Any("/delete_msg", s.DeleteMessage)
|
||||||
s.engine.Any("/delete_msg_async", s.DeleteMessage)
|
s.engine.Any("/delete_msg_async", s.DeleteMessage)
|
||||||
|
|
||||||
@ -246,6 +249,12 @@ func (s *httpServer) SendGroupMessage(c *gin.Context) {
|
|||||||
c.JSON(200, s.bot.CQSendGroupMessage(gid, gjson.Result{Type: gjson.String, Str: msg}))
|
c.JSON(200, s.bot.CQSendGroupMessage(gid, gjson.Result{Type: gjson.String, Str: msg}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *httpServer) SendGroupForwardMessage(c *gin.Context) {
|
||||||
|
gid, _ := strconv.ParseInt(getParam(c, "group_id"), 10, 64)
|
||||||
|
msg := getParam(c, "messages")
|
||||||
|
c.JSON(200, s.bot.CQSendGroupForwardMessage(gid, gjson.Parse(msg)))
|
||||||
|
}
|
||||||
|
|
||||||
func (s *httpServer) GetImage(c *gin.Context) {
|
func (s *httpServer) GetImage(c *gin.Context) {
|
||||||
file := getParam(c, "file")
|
file := getParam(c, "file")
|
||||||
c.JSON(200, s.bot.CQGetImage(file))
|
c.JSON(200, s.bot.CQGetImage(file))
|
||||||
|
@ -331,6 +331,9 @@ var wsApi = map[string]func(*coolq.CQBot, gjson.Result) coolq.MSG{
|
|||||||
"send_group_msg": func(bot *coolq.CQBot, p gjson.Result) coolq.MSG {
|
"send_group_msg": func(bot *coolq.CQBot, p gjson.Result) coolq.MSG {
|
||||||
return bot.CQSendGroupMessage(p.Get("group_id").Int(), p.Get("message"))
|
return bot.CQSendGroupMessage(p.Get("group_id").Int(), p.Get("message"))
|
||||||
},
|
},
|
||||||
|
"send_group_forward_msg": func(bot *coolq.CQBot, p gjson.Result) coolq.MSG {
|
||||||
|
return bot.CQSendGroupForwardMessage(p.Get("group_id").Int(), p.Get("messages"))
|
||||||
|
},
|
||||||
"send_private_msg": func(bot *coolq.CQBot, p gjson.Result) coolq.MSG {
|
"send_private_msg": func(bot *coolq.CQBot, p gjson.Result) coolq.MSG {
|
||||||
return bot.CQSendPrivateMessage(p.Get("user_id").Int(), p.Get("message"))
|
return bot.CQSendPrivateMessage(p.Get("user_id").Int(), p.Get("message"))
|
||||||
},
|
},
|
||||||
|
Loading…
x
Reference in New Issue
Block a user