mirror of
https://github.com/openimsdk/open-im-server.git
synced 2026-04-28 14:29:19 +08:00
feat: Change after webhook filter && feat SendSimpleMsg (#3151)
* feat: msg filter and search system account * feat: search system account * chore: msg * chore: msg * chore: msg * chore: webhook filter && sendSimpleMessage
This commit is contained in:
@@ -15,12 +15,16 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/go-playground/validator/v10"
|
||||
"github.com/mitchellh/mapstructure"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/apistruct"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/authverify"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/webhook"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/rpcli"
|
||||
"github.com/openimsdk/protocol/constant"
|
||||
"github.com/openimsdk/protocol/msg"
|
||||
@@ -368,6 +372,83 @@ func (m *MessageApi) BatchSendMsg(c *gin.Context) {
|
||||
apiresp.GinSuccess(c, resp)
|
||||
}
|
||||
|
||||
func (m *MessageApi) SendSimpleMessage(c *gin.Context) {
|
||||
encodedKey, ok := c.GetQuery(webhook.Key)
|
||||
if !ok {
|
||||
apiresp.GinError(c, errs.ErrArgs.WithDetail("missing key in query").Wrap())
|
||||
return
|
||||
}
|
||||
|
||||
decodedData, err := base64.StdEncoding.DecodeString(encodedKey)
|
||||
if err != nil {
|
||||
apiresp.GinError(c, errs.ErrArgs.WithDetail(err.Error()).Wrap())
|
||||
return
|
||||
}
|
||||
var (
|
||||
req apistruct.SendSingleMsgReq
|
||||
keyMsgData apistruct.KeyMsgData
|
||||
|
||||
sendID string
|
||||
sessionType int32
|
||||
recvID string
|
||||
)
|
||||
err = json.Unmarshal(decodedData, &keyMsgData)
|
||||
if err != nil {
|
||||
apiresp.GinError(c, errs.ErrArgs.WithDetail(err.Error()).Wrap())
|
||||
return
|
||||
}
|
||||
if keyMsgData.GroupID != "" {
|
||||
sessionType = constant.ReadGroupChatType
|
||||
sendID = req.SendID
|
||||
} else {
|
||||
sessionType = constant.SingleChatType
|
||||
sendID = keyMsgData.RecvID
|
||||
recvID = keyMsgData.SendID
|
||||
}
|
||||
// check param
|
||||
if keyMsgData.SendID == "" {
|
||||
apiresp.GinError(c, errs.ErrArgs.WithDetail("missing recvID or GroupID").Wrap())
|
||||
return
|
||||
}
|
||||
if sendID == "" {
|
||||
apiresp.GinError(c, errs.ErrArgs.WithDetail("missing sendID").Wrap())
|
||||
return
|
||||
}
|
||||
|
||||
msgData := &sdkws.MsgData{
|
||||
SendID: sendID,
|
||||
RecvID: recvID,
|
||||
GroupID: keyMsgData.GroupID,
|
||||
ClientMsgID: idutil.GetMsgIDByMD5(sendID),
|
||||
SenderPlatformID: constant.AdminPlatformID,
|
||||
SessionType: sessionType,
|
||||
MsgFrom: constant.UserMsgType,
|
||||
ContentType: constant.Text,
|
||||
Content: []byte(req.Content),
|
||||
OfflinePushInfo: req.OfflinePushInfo,
|
||||
Ex: req.Ex,
|
||||
}
|
||||
|
||||
respPb, err := m.Client.SendMsg(c, &msg.SendMsgReq{MsgData: msgData})
|
||||
if err != nil {
|
||||
apiresp.GinError(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
var status = constant.MsgSendSuccessed
|
||||
|
||||
_, err = m.Client.SetSendMsgStatus(c, &msg.SetSendMsgStatusReq{
|
||||
Status: int32(status),
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
apiresp.GinError(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
apiresp.GinSuccess(c, respPb)
|
||||
}
|
||||
|
||||
func (m *MessageApi) CheckMsgIsSendSuccess(c *gin.Context) {
|
||||
a2r.Call(c, msg.MsgClient.GetSendMsgStatus, m.Client)
|
||||
}
|
||||
|
||||
@@ -16,7 +16,11 @@ package msg
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/apistruct"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/webhook"
|
||||
"github.com/openimsdk/tools/utils/stringutil"
|
||||
|
||||
cbapi "github.com/openimsdk/open-im-server/v3/pkg/callbackstruct"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||
@@ -94,7 +98,7 @@ func (m *msgServer) webhookAfterSendSingleMsg(ctx context.Context, after *config
|
||||
CommonCallbackReq: toCommonCallback(ctx, msg, cbapi.CallbackAfterSendSingleMsgCommand),
|
||||
RecvID: msg.MsgData.RecvID,
|
||||
}
|
||||
m.webhookClient.AsyncPost(ctx, cbReq.GetCallbackCommand(), cbReq, &cbapi.CallbackAfterSendSingleMsgResp{}, after)
|
||||
m.webhookClient.AsyncPostWithQuery(ctx, cbReq.GetCallbackCommand(), cbReq, &cbapi.CallbackAfterSendSingleMsgResp{}, after, buildKeyMsgDataQuery(msg.MsgData))
|
||||
}
|
||||
|
||||
func (m *msgServer) webhookBeforeSendGroupMsg(ctx context.Context, before *config.BeforeConfig, msg *pbchat.SendMsgReq) error {
|
||||
@@ -128,7 +132,8 @@ func (m *msgServer) webhookAfterSendGroupMsg(ctx context.Context, after *config.
|
||||
CommonCallbackReq: toCommonCallback(ctx, msg, cbapi.CallbackAfterSendGroupMsgCommand),
|
||||
GroupID: msg.MsgData.GroupID,
|
||||
}
|
||||
m.webhookClient.AsyncPost(ctx, cbReq.GetCallbackCommand(), cbReq, &cbapi.CallbackAfterSendGroupMsgResp{}, after)
|
||||
|
||||
m.webhookClient.AsyncPostWithQuery(ctx, cbReq.GetCallbackCommand(), cbReq, &cbapi.CallbackAfterSendGroupMsgResp{}, after, buildKeyMsgDataQuery(msg.MsgData))
|
||||
}
|
||||
|
||||
func (m *msgServer) webhookBeforeMsgModify(ctx context.Context, before *config.BeforeConfig, msg *pbchat.SendMsgReq) error {
|
||||
@@ -192,3 +197,15 @@ func (m *msgServer) webhookAfterRevokeMsg(ctx context.Context, after *config.Aft
|
||||
}
|
||||
m.webhookClient.AsyncPost(ctx, callbackReq.GetCallbackCommand(), callbackReq, &cbapi.CallbackAfterRevokeMsgResp{}, after)
|
||||
}
|
||||
|
||||
func buildKeyMsgDataQuery(msg *sdkws.MsgData) map[string]string {
|
||||
keyMsgData := apistruct.KeyMsgData{
|
||||
SendID: msg.SendID,
|
||||
RecvID: msg.RecvID,
|
||||
GroupID: msg.GroupID,
|
||||
}
|
||||
|
||||
return map[string]string{
|
||||
webhook.Key: base64.StdEncoding.EncodeToString(stringutil.StructToJsonBytes(keyMsgData)),
|
||||
}
|
||||
}
|
||||
|
||||
+36
-12
@@ -1,11 +1,13 @@
|
||||
package msg
|
||||
|
||||
import (
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||
pbchat "github.com/openimsdk/protocol/msg"
|
||||
"github.com/openimsdk/tools/utils/datautil"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||
"github.com/openimsdk/protocol/constant"
|
||||
pbchat "github.com/openimsdk/protocol/msg"
|
||||
"github.com/openimsdk/tools/utils/datautil"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -13,28 +15,50 @@ const (
|
||||
)
|
||||
|
||||
func filterAfterMsg(msg *pbchat.SendMsgReq, after *config.AfterConfig) bool {
|
||||
return filterMsg(msg, after.AttentionIds, after.AllowedTypes, after.DeniedTypes)
|
||||
return filterMsg(msg, after.AttentionIds, after.DeniedTypes)
|
||||
}
|
||||
|
||||
func filterBeforeMsg(msg *pbchat.SendMsgReq, before *config.BeforeConfig) bool {
|
||||
return filterMsg(msg, nil, before.AllowedTypes, before.DeniedTypes)
|
||||
return filterMsg(msg, nil, before.DeniedTypes)
|
||||
}
|
||||
|
||||
func filterMsg(msg *pbchat.SendMsgReq, attentionIds, allowedTypes, deniedTypes []string) bool {
|
||||
func filterMsg(msg *pbchat.SendMsgReq, attentionIds []string, deniedTypes []int32) bool {
|
||||
// According to the attentionIds configuration, only some users are sent
|
||||
if len(attentionIds) != 0 && !datautil.Contains([]string{msg.MsgData.SendID, msg.MsgData.RecvID}, attentionIds...) {
|
||||
if len(attentionIds) != 0 && !datautil.Contain(msg.MsgData.RecvID, attentionIds...) {
|
||||
return false
|
||||
}
|
||||
if len(allowedTypes) != 0 && !isInInterval(msg.MsgData.ContentType, allowedTypes) {
|
||||
|
||||
if defaultDeniedTypes(msg.MsgData.ContentType) {
|
||||
return false
|
||||
}
|
||||
if len(deniedTypes) != 0 && isInInterval(msg.MsgData.ContentType, deniedTypes) {
|
||||
|
||||
if len(deniedTypes) != 0 && datautil.Contain(msg.MsgData.ContentType, deniedTypes...) {
|
||||
return false
|
||||
}
|
||||
//if len(allowedTypes) != 0 && !isInInterval(msg.MsgData.ContentType, allowedTypes) {
|
||||
// return false
|
||||
//}
|
||||
//if len(deniedTypes) != 0 && isInInterval(msg.MsgData.ContentType, deniedTypes) {
|
||||
// return false
|
||||
//}
|
||||
return true
|
||||
}
|
||||
|
||||
func isInInterval(contentType int32, interval []string) bool {
|
||||
func defaultDeniedTypes(contentType int32) bool {
|
||||
if contentType >= constant.NotificationBegin && contentType <= constant.NotificationEnd {
|
||||
return true
|
||||
}
|
||||
if contentType == constant.Typing {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// isInInterval if data is in interval
|
||||
// Supports two formats: a single type or a range. The range is defined by the lower and upper bounds connected with a hyphen ("-")
|
||||
// e.g. [1, 100, 200-500, 600-700] means that only data within the range
|
||||
// {1, 100} ∪ [200, 500] ∪ [600, 700] will return true.
|
||||
func isInInterval(data int32, interval []string) bool {
|
||||
for _, v := range interval {
|
||||
if strings.Contains(v, separator) {
|
||||
// is interval
|
||||
@@ -50,7 +74,7 @@ func isInInterval(contentType int32, interval []string) bool {
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if datautil.BetweenEq(int(contentType), bottom, top) {
|
||||
if datautil.BetweenEq(int(data), bottom, top) {
|
||||
return true
|
||||
}
|
||||
} else {
|
||||
@@ -58,7 +82,7 @@ func isInInterval(contentType int32, interval []string) bool {
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if int(contentType) == iv {
|
||||
if int(data) == iv {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -566,7 +566,7 @@ func (s *userServer) SearchNotificationAccount(ctx context.Context, req *pbuser.
|
||||
}
|
||||
|
||||
// Convert users to response format
|
||||
resp := s.userModelToResp(users, req.Pagination)
|
||||
resp := s.userModelToResp(users, req.Pagination, req.AppManagerLevel)
|
||||
if resp.Total != 0 {
|
||||
return resp, nil
|
||||
}
|
||||
@@ -576,17 +576,24 @@ func (s *userServer) SearchNotificationAccount(ctx context.Context, req *pbuser.
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp = s.userModelToResp(users, req.Pagination)
|
||||
resp = s.userModelToResp(users, req.Pagination, req.AppManagerLevel)
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// If no keyword, find users with notification settings
|
||||
users, err = s.db.FindNotification(ctx, constant.AppNotificationAdmin)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
if req.AppManagerLevel != nil {
|
||||
users, err = s.db.FindNotification(ctx, int64(*req.AppManagerLevel))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
users, err = s.db.FindSystemAccount(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
resp := s.userModelToResp(users, req.Pagination)
|
||||
resp := s.userModelToResp(users, req.Pagination, req.AppManagerLevel)
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
@@ -625,11 +632,16 @@ func (s *userServer) genUserID() string {
|
||||
return string(data)
|
||||
}
|
||||
|
||||
func (s *userServer) userModelToResp(users []*tablerelation.User, pagination pagination.Pagination) *pbuser.SearchNotificationAccountResp {
|
||||
func (s *userServer) userModelToResp(users []*tablerelation.User, pagination pagination.Pagination, appManagerLevel *int32) *pbuser.SearchNotificationAccountResp {
|
||||
accounts := make([]*pbuser.NotificationAccountInfo, 0)
|
||||
var total int64
|
||||
for _, v := range users {
|
||||
if v.AppMangerLevel >= constant.AppNotificationAdmin && !datautil.Contain(v.UserID, s.config.Share.IMAdminUserID...) {
|
||||
if appManagerLevel != nil {
|
||||
if v.AppMangerLevel != *appManagerLevel {
|
||||
continue
|
||||
}
|
||||
}
|
||||
temp := &pbuser.NotificationAccountInfo{
|
||||
UserID: v.UserID,
|
||||
FaceURL: v.FaceURL,
|
||||
|
||||
Reference in New Issue
Block a user