1
0
mirror of https://github.com/Mrs4s/go-cqhttp.git synced 2025-06-30 11:53:25 +00:00

Compare commits

..

13 Commits

Author SHA1 Message Date
ff75b0a2a9 update doc. 2021-02-06 21:55:32 +08:00
4a13f35003 update MiraiGo. 2021-02-06 21:46:28 +08:00
8d0a0b7f4d fix typo. 2021-02-06 19:11:24 +08:00
4c570bdfe6 feature check_url_safely. 2021-02-06 06:40:39 +08:00
d4e8a3df4f update MiraiGo. 2021-02-06 06:34:29 +08:00
307a09dd11 feature upload_group_file. 2021-02-05 22:24:49 +08:00
4445af6ff2 update MiraiGo. 2021-02-05 21:46:25 +08:00
dbd0f85025 Merge pull request #611 from wdvxdr1123/patch/essence
feat group essence msg operate
2021-02-03 01:26:44 +08:00
0bacbde4d7 Merge branch 'dev' into patch/essence 2021-02-03 01:26:27 +08:00
c92dd39191 Merge pull request #610 from wdvxdr1123/group_info
get group info by search
2021-02-03 01:23:27 +08:00
7da1918c0c update docs 2021-02-02 23:59:00 +08:00
89d466d3e1 feat group essence msg operate 2021-02-02 23:36:05 +08:00
5b57aeb1d1 get group info by search 2021-02-02 22:12:47 +08:00
9 changed files with 298 additions and 9 deletions

View File

@ -62,7 +62,22 @@ func (bot *CQBot) CQGetGroupList(noCache bool) MSG {
func (bot *CQBot) CQGetGroupInfo(groupId int64, noCache bool) MSG {
group := bot.Client.FindGroup(groupId)
if group == nil {
return Failed(100, "GROUP_NOT_FOUND", "群聊不存在")
gid := strconv.FormatInt(groupId, 10)
info, err := bot.Client.SearchGroupByKeyword(gid)
if err != nil {
return Failed(100, "GROUP_SEARCH_ERROR", "群聊搜索失败")
}
for _, g := range info {
if g.Code == groupId {
return OK(MSG{
"group_id": g.Code,
"group_name": g.Name,
"max_member_count": 0,
"member_count": 0,
})
}
}
return Failed(100, "GROUP_NOT_FOUND", "群聊不存在失败")
}
if noCache {
var err error
@ -166,6 +181,26 @@ func (bot *CQBot) CQGetGroupFileUrl(groupId int64, fileId string, busId int32) M
})
}
func (bot *CQBot) CQUploadGroupFile(groupId int64, file, name, folder string) MSG {
if !global.PathExists(file) {
log.Errorf("上传群文件 %v 失败: 文件不存在", file)
return Failed(100, "FILE_NOT_FOUND", "文件不存在")
}
fs, err := bot.Client.GetGroupFileSystem(groupId)
if err != nil {
log.Errorf("获取群 %v 文件系统信息失败: %v", groupId, err)
return Failed(100, "FILE_SYSTEM_API_ERROR", err.Error())
}
if folder == "" {
folder = "/"
}
if err = fs.UploadFile(file, name, folder); err != nil {
log.Errorf("上传群 %v 文件 %v 失败: %v", groupId, file, err)
return Failed(100, "FILE_SYSTEM_UPLOAD_API_ERROR", err.Error())
}
return OK(nil)
}
func (bot *CQBot) CQGetWordSlices(content string) MSG {
slices, err := bot.Client.GetWordSegmentation(content)
if err != nil {
@ -973,6 +1008,74 @@ func (bot *CQBot) CQGetStatus() MSG {
})
}
// CQSetEssenceMessage 设置精华消息
func (bot *CQBot) CQSetEssenceMessage(messageID int32) MSG {
msg := bot.GetMessage(messageID)
if msg == nil {
return Failed(100, "MESSAGE_NOT_FOUND", "消息不存在")
}
if _, ok := msg["group"]; ok {
if err := bot.Client.SetEssenceMessage(msg["group"].(int64), msg["message-id"].(int32), msg["internal-id"].(int32)); err != nil {
log.Warnf("设置精华消息 %v 失败: %v", messageID, err)
return Failed(100, "SET_ESSENCE_MSG_ERROR", err.Error())
}
} else {
log.Warnf("设置精华消息 %v 失败: 非群聊", messageID)
return Failed(100, "SET_ESSENCE_MSG_ERROR", "非群聊")
}
return OK(nil)
}
// CQDeleteEssenceMessage 移出精华消息
func (bot *CQBot) CQDeleteEssenceMessage(messageID int32) MSG {
msg := bot.GetMessage(messageID)
if msg == nil {
return Failed(100, "MESSAGE_NOT_FOUND", "消息不存在")
}
if _, ok := msg["group"]; ok {
if err := bot.Client.DeleteEssenceMessage(msg["group"].(int64), msg["message-id"].(int32), msg["internal-id"].(int32)); err != nil {
log.Warnf("移出精华消息 %v 失败: %v", messageID, err)
return Failed(100, "DEL_ESSENCE_MSG_ERROR", err.Error())
}
} else {
log.Warnf("移出精华消息 %v 失败: 非群聊", messageID)
return Failed(100, "DEL_ESSENCE_MSG_ERROR", "非群聊")
}
return OK(nil)
}
// CQGetEssenceMessageList 获取精华消息列表
func (bot *CQBot) CQGetEssenceMessageList(groupCode int64) MSG {
g := bot.Client.FindGroup(groupCode)
if g == nil {
return Failed(100, "GROUP_NOT_FOUND", "群聊不存在")
}
msgList, err := bot.Client.GetGroupEssenceMsgList(groupCode)
if err != nil {
return Failed(100, "GET_ESSENCE_LIST_FOUND", err.Error())
}
list := make([]MSG, 0)
for _, m := range msgList {
var msg = MSG{
"sender_nick": m.SenderNick,
"sender_time": m.SenderTime,
"operator_time": m.AddDigestTime,
"operator_nick": m.AddDigestNick,
}
msg["sender_id"], _ = strconv.ParseUint(m.SenderUin, 10, 64)
msg["operator_id"], _ = strconv.ParseUint(m.AddDigestUin, 10, 64)
msg["message_id"] = ToGlobalId(groupCode, int32(m.MessageID))
list = append(list, msg)
}
return OK(list)
}
func (bot *CQBot) CQCheckUrlSafely(url string) MSG {
return OK(MSG{
"level": bot.Client.CheckUrlSafely(url),
})
}
func (bot *CQBot) CQGetVersionInfo() MSG {
wd, _ := os.Getwd()
return OK(MSG{

View File

@ -78,6 +78,7 @@ func NewQQBot(cli *client.QQClient, conf *global.JSONConfig) *CQBot {
bot.Client.OnGroupInvited(bot.groupInvitedEvent)
bot.Client.OnUserWantJoinGroup(bot.groupJoinReqEvent)
bot.Client.OnOtherClientStatusChanged(bot.otherClientStatusChangedEvent)
bot.Client.OnGroupDigest(bot.groupEssenceMsg)
go func() {
i := conf.HeartbeatInterval
if i < 0 {

View File

@ -431,7 +431,47 @@ func (bot *CQBot) otherClientStatusChangedEvent(c *client.QQClient, e *client.Ot
"self_id": c.Uin,
"time": time.Now().Unix(),
})
}
func (bot *CQBot) groupEssenceMsg(c *client.QQClient, e *client.GroupDigestEvent) {
g := c.FindGroup(e.GroupCode)
gid := ToGlobalId(e.GroupCode, e.MessageID)
if e.OperationType == 1 {
log.Infof(
"群 %v 内 %v 将 %v 的消息(%v)设为了精华消息.",
formatGroupName(g),
formatMemberName(g.FindMember(e.OperatorUin)),
formatMemberName(g.FindMember(e.SenderUin)),
gid,
)
} else {
log.Infof(
"群 %v 内 %v 将 %v 的消息(%v)移出了精华消息.",
formatGroupName(g),
formatMemberName(g.FindMember(e.OperatorUin)),
formatMemberName(g.FindMember(e.SenderUin)),
gid,
)
}
if e.OperatorUin == bot.Client.Uin {
return
}
bot.dispatchEventMessage(MSG{
"post_type": "notice",
"group_id": e.GroupCode,
"notice_type": "essence",
"sub_type": func() string {
if e.OperationType == 1 {
return "add"
}
return "delete"
}(),
"self_id": c.Uin,
"sender_id": e.SenderUin,
"operator_id": e.OperatorUin,
"time": time.Now().Unix(),
"message_id": gid,
})
}
func (bot *CQBot) groupIncrease(groupCode, operatorUin, userUin int64) MSG {

View File

@ -39,6 +39,9 @@
- [获取群子目录文件列表](#设置群名)
- [获取用户VIP信息](#获取用户VIP信息)
- [发送群公告](#发送群公告)
- [设置精华消息](#设置精华消息)
- [移出精华消息](#移出精华消息)
- [获取精华消息列表](#获取精华消息列表)
- [重载事件过滤器](#重载事件过滤器)
##### 事件
@ -50,6 +53,7 @@
- [群成员荣誉变更提示](#群成员荣誉变更提示)
- [群成员名片更新](#群成员名片更新)
- [接收到离线文件](#接收到离线文件)
- [群精华消息](#精华消息)
</p>
</details>
@ -620,11 +624,63 @@ Type: `tts`
| -------- | -------- | ---- |
| `slices` | string[] | 词组 |
### 设置精华消息
终结点: `/set_essence_msg`
**参数**
| 字段 | 类型 | 说明 |
| --------- | ------ | ---- |
| `message_id` | int32 | 消息ID |
**响应数据**
### 移出精华消息
终结点: `/delete_essence_msg`
**参数**
| 字段 | 类型 | 说明 |
| --------- | ------ | ---- |
| `message_id` | int32 | 消息ID |
**响应数据**
### 获取精华消息列表
终结点: `/get_essence_msg_list`
**参数**
| 字段 | 类型 | 说明 |
| --------- | ------ | ---- |
| `group_id` | int64 | 群号 |
**响应数据**
响应内容为 JSON 数组,每个元素如下:
| 字段名 | 数据类型 | 说明 |
| ----- | ------- | --- |
| `sender_id` |int64 | 发送者QQ 号 |
| `sender_nick` | string | 发送者昵称 |
| `sender_time` | int64 | 消息发送时间 |
| `operator_id` |int64 | 发送者QQ 号 |
| `operator_nick` | string | 发送者昵称 |
| `operator_time` | int64 | 消息发送时间|
| `message_id` | int32 | 消息ID |
### 图片OCR
> 注意: 目前图片OCR接口仅支持接受的图片
终结点: `/.ocr_image`
终结点: `/ocr_image`
**参数**
@ -790,6 +846,22 @@ Type: `tts`
| `creator_name` | string | 创建者名字 |
| `total_file_count` | int32 | 子文件数量 |
### 上传群文件
终结点: `/upload_group_file`
**参数**
| 字段 | 类型 | 说明 |
| ---------- | ------ | ------------------------- |
| `group_id` | int64 | 群号 |
| `file` | string | 本地文件路径 |
| `name` | string | 储存名称 |
| `folder` | string | 父目录ID |
> 在不提供 `folder` 参数的情况下默认上传到根目录
> 只能上传本地文件, 需要上传 `http` 文件的话请先调用 `download_file` API下载
### 获取状态
终结点: `/get_status`
@ -922,6 +994,22 @@ JSON数组:
| `device_name` | string | 设备名称 |
| `device_kind` | string | 设备类型 |
### 检查链接安全性
终结点:`/check_url_safely`
**参数**
| 字段 | 类型 | 说明 |
| ---------- | ------ | ------------------------- |
| `url` | string | 需要检查的链接 |
**响应数据**
| 字段 | 类型 | 说明 |
| ---------- | ---------- | ------------ |
| `level` | int | 安全等级, 1: 安全 2: 未知 3: 危险 |
### 获取用户VIP信息
终结点:`/_get_vip_info`
@ -1096,3 +1184,16 @@ JSON数组:
| `notice_type` | string | `client_status` | 消息类型 |
| `client` | Device | | 客户端信息 |
| `online` | bool | | 当前是否在线 |
### 精华消息
**上报数据**
| 字段 | 类型 | 可能的值 | 说明 |
| ------------- | ------ | -------------- | -------- |
| `post_type` | string | `notice` | 上报类型 |
| `notice_type` | string | `essence` | 消息类型 |
| `sub_type` | string | `add`,`delete` | 添加为`add`,移出为`delete` |
| `sender_id` | int64 | | 消息发送者ID |
| `operator_id` | int64 | | 操作者ID |
| `message_id` | int32 | | 消息ID |

2
go.mod
View File

@ -3,7 +3,7 @@ module github.com/Mrs4s/go-cqhttp
go 1.15
require (
github.com/Mrs4s/MiraiGo v0.0.0-20210201234941-c69e578d0815
github.com/Mrs4s/MiraiGo v0.0.0-20210206134348-800bf525ed0e
github.com/dustin/go-humanize v1.0.0
github.com/gin-contrib/pprof v1.3.0
github.com/gin-gonic/gin v1.6.3

4
go.sum
View File

@ -1,7 +1,7 @@
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-20210201234941-c69e578d0815 h1:WW2YfA+0+LSa/0VlWVhnfrXXatcE09paHgPgfPxlIMk=
github.com/Mrs4s/MiraiGo v0.0.0-20210201234941-c69e578d0815/go.mod h1:yhqA0NyKxUf7I/0HR/1OMchveFggX8wde04gqdGrNfU=
github.com/Mrs4s/MiraiGo v0.0.0-20210206134348-800bf525ed0e h1:SnN+nyRdqN7sULnHUWCofP+Jxs3VJN/y8AlMpcz0nbk=
github.com/Mrs4s/MiraiGo v0.0.0-20210206134348-800bf525ed0e/go.mod h1:yhqA0NyKxUf7I/0HR/1OMchveFggX8wde04gqdGrNfU=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=

View File

@ -143,7 +143,7 @@ func main() {
if conf.Uin == 0 || (conf.Password == "" && conf.PasswordEncrypted == "") {
log.Warnf("请修改 config.hjson 以添加账号密码.")
if (!isFastStart) {
if !isFastStart {
time.Sleep(time.Second * 5)
}
return
@ -509,7 +509,7 @@ func getConfig() *global.JSONConfig {
return nil
}
log.Infof("默认配置文件已生成, 请编辑 config.hjson 后重启程序.")
if (!isFastStart) {
if !isFastStart {
time.Sleep(time.Second * 5)
}
return nil

View File

@ -215,6 +215,11 @@ func GetGroupFileUrl(s *httpServer, c *gin.Context) {
c.JSON(200, s.bot.CQGetGroupFileUrl(gid, fid, int32(busid)))
}
func UploadGroupFile(s *httpServer, c *gin.Context) {
gid, _ := strconv.ParseInt(getParam(c, "group_id"), 10, 64)
c.JSON(200, s.bot.CQUploadGroupFile(gid, getParam(c, "file"), getParam(c, "name"), getParam(c, "folder")))
}
func SendMessage(s *httpServer, c *gin.Context) {
if getParam(c, "message_type") == "private" {
SendPrivateMessage(s, c)
@ -486,6 +491,25 @@ func SetGroupPortrait(s *httpServer, c *gin.Context) {
c.JSON(200, s.bot.CQSetGroupPortrait(gid, file, cache))
}
func SetEssenceMsg(s *httpServer, c *gin.Context) {
mid, _ := strconv.ParseInt(getParam(c, "message_id"), 10, 64)
c.JSON(200, s.bot.CQSetEssenceMessage(int32(mid)))
}
func DeleteEssenceMsg(s *httpServer, c *gin.Context) {
mid, _ := strconv.ParseInt(getParam(c, "message_id"), 10, 64)
c.JSON(200, s.bot.CQDeleteEssenceMessage(int32(mid)))
}
func GetEssenceMsgList(s *httpServer, c *gin.Context) {
gid, _ := strconv.ParseInt(getParam(c, "group_id"), 10, 64)
c.JSON(200, s.bot.CQGetEssenceMessageList(gid))
}
func CheckUrlSafely(s *httpServer, c *gin.Context) {
c.JSON(200, s.bot.CQCheckUrlSafely(getParam(c, "url")))
}
func getParamOrDefault(c *gin.Context, k, def string) string {
r := getParam(c, k)
if r != "" {
@ -545,11 +569,14 @@ var httpApi = map[string]func(s *httpServer, c *gin.Context){
"get_group_root_files": GetGroupRootFiles,
"get_group_files_by_folder": GetGroupFilesByFolderId,
"get_group_file_url": GetGroupFileUrl,
"upload_group_file": UploadGroupFile,
"get_essence_msg_list": GetEssenceMsgList,
"send_msg": SendMessage,
"send_group_msg": SendGroupMessage,
"send_group_forward_msg": SendGroupForwardMessage,
"send_private_msg": SendPrivateMessage,
"delete_msg": DeleteMessage,
"delete_essence_msg": DeleteEssenceMsg,
"set_friend_add_request": ProcessFriendRequest,
"set_group_add_request": ProcessGroupRequest,
"set_group_card": SetGroupCard,
@ -559,6 +586,7 @@ var httpApi = map[string]func(s *httpServer, c *gin.Context){
"set_group_whole_ban": SetWholeBan,
"set_group_name": SetGroupName,
"set_group_admin": SetGroupAdmin,
"set_essence_msg": SetEssenceMsg,
"set_restart": SetRestart,
"_send_group_notice": SendGroupNotice,
"set_group_leave": SetGroupLeave,
@ -577,6 +605,7 @@ var httpApi = map[string]func(s *httpServer, c *gin.Context){
"set_group_portrait": SetGroupPortrait,
"set_group_anonymous_ban": SetGroupAnonymousBan,
"get_group_msg_history": GetGroupMessageHistory,
"check_url_safely": CheckUrlSafely,
"download_file": DownloadFile,
".handle_quick_operation": HandleQuickOperation,
".ocr_image": OcrImage,

View File

@ -562,6 +562,9 @@ var wsAPI = map[string]func(*coolq.CQBot, gjson.Result) coolq.MSG{
"get_group_file_url": func(bot *coolq.CQBot, p gjson.Result) coolq.MSG {
return bot.CQGetGroupFileUrl(p.Get("group_id").Int(), p.Get("file_id").Str, int32(p.Get("busid").Int()))
},
"upload_group_file": func(bot *coolq.CQBot, p gjson.Result) coolq.MSG {
return bot.CQUploadGroupFile(p.Get("group_id").Int(), p.Get("file").Str, p.Get("name").Str, p.Get("folder").Str)
},
"get_group_msg_history": func(bot *coolq.CQBot, p gjson.Result) coolq.MSG {
return bot.CQGetGroupMessageHistory(p.Get("group_id").Int(), p.Get("message_seq").Int())
},
@ -589,6 +592,18 @@ var wsAPI = map[string]func(*coolq.CQBot, gjson.Result) coolq.MSG{
"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())
},
"set_essence_msg": func(bot *coolq.CQBot, p gjson.Result) coolq.MSG {
return bot.CQSetEssenceMessage(int32(p.Get("message_id").Int()))
},
"delete_essence_msg": func(bot *coolq.CQBot, p gjson.Result) coolq.MSG {
return bot.CQDeleteEssenceMessage(int32(p.Get("message_id").Int()))
},
"get_essence_msg_list": func(bot *coolq.CQBot, p gjson.Result) coolq.MSG {
return bot.CQGetEssenceMessageList(p.Get("group_id").Int())
},
"check_url_safely": func(bot *coolq.CQBot, p gjson.Result) coolq.MSG {
return bot.CQCheckUrlSafely(p.Get("url").String())
},
"set_group_anonymous_ban": func(bot *coolq.CQBot, p gjson.Result) coolq.MSG {
obj := p.Get("anonymous")
flag := p.Get("anonymous_flag")