mirror of
https://github.com/openimsdk/open-im-server.git
synced 2025-10-08 18:20:04 +08:00
errcode
This commit is contained in:
parent
b6d19dba00
commit
5be441f4fd
@ -1,7 +1,6 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
_ "Open_IM/cmd/open_im_api/docs"
|
||||
apiAuth "Open_IM/internal/api/auth"
|
||||
"Open_IM/internal/api/conversation"
|
||||
"Open_IM/internal/api/friend"
|
||||
@ -14,7 +13,6 @@ import (
|
||||
"Open_IM/pkg/common/log"
|
||||
"Open_IM/pkg/common/middleware"
|
||||
"Open_IM/pkg/common/tokenverify"
|
||||
"Open_IM/pkg/utils"
|
||||
"flag"
|
||||
"fmt"
|
||||
|
||||
@ -25,10 +23,9 @@ import (
|
||||
swaggerFiles "github.com/swaggo/files"
|
||||
ginSwagger "github.com/swaggo/gin-swagger"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
//"syscall"
|
||||
"Open_IM/pkg/common/constant"
|
||||
prome "Open_IM/pkg/common/prometheus"
|
||||
"Open_IM/pkg/common/prome"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// @title open-IM-Server API
|
||||
|
@ -1,7 +1,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"Open_IM/internal/push/logic"
|
||||
"Open_IM/internal/push"
|
||||
"Open_IM/pkg/common/config"
|
||||
"Open_IM/pkg/common/constant"
|
||||
"Open_IM/pkg/common/log"
|
||||
@ -19,7 +19,7 @@ func main() {
|
||||
wg.Add(1)
|
||||
log.NewPrivateLog(constant.LogFileName)
|
||||
fmt.Println("start push rpc server, port: ", *rpcPort, ", OpenIM version: ", constant.CurrentVersion, "\n")
|
||||
logic.Init(*rpcPort)
|
||||
logic.Run(*prometheusPort)
|
||||
push.Init(*rpcPort)
|
||||
push.Run(*prometheusPort)
|
||||
wg.Wait()
|
||||
}
|
||||
|
@ -213,12 +213,6 @@ push:
|
||||
fcm: #firebase cloud message 消息推送
|
||||
serviceAccount: "openim-5c6c0-firebase-adminsdk-ppwol-8765884a78.json" #帐号文件,此处需要改修配置,并且这个文件放在 config目录下
|
||||
enable: false
|
||||
mob: #袤博推送
|
||||
appKey: #帐号文件,此处需要改修配置,并且这个文件放在 config目录下
|
||||
pushUrl:
|
||||
scheme:
|
||||
appSecret:
|
||||
enable: false
|
||||
|
||||
manager:
|
||||
#app管理员userID和对应的secret 建议修改。 用于管理后台登录,也可以用户管理后台对应的api
|
||||
|
@ -34,7 +34,6 @@ services:
|
||||
- MONGO_INITDB_DATABASE=openIM
|
||||
- MONGO_USERNAME=${USER}
|
||||
- MONGO_PASSWORD=${PASSWORD}
|
||||
#
|
||||
restart: always
|
||||
|
||||
redis:
|
||||
@ -84,20 +83,6 @@ services:
|
||||
depends_on:
|
||||
- zookeeper
|
||||
|
||||
etcd:
|
||||
image: quay.io/coreos/etcd
|
||||
ports:
|
||||
- 2379:2379
|
||||
- 2380:2380
|
||||
container_name: etcd
|
||||
volumes:
|
||||
- /etc/timezone:/etc/timezone
|
||||
- /etc/localtime:/etc/localtime
|
||||
environment:
|
||||
ETCDCTL_API: 3
|
||||
restart: always
|
||||
command: /usr/local/bin/etcd --name etcd0 --data-dir /etcd-data --listen-client-urls http://0.0.0.0:2379 --advertise-client-urls http://0.0.0.0:2379 --listen-peer-urls http://0.0.0.0:2380 --initial-advertise-peer-urls http://0.0.0.0:2380 --initial-cluster etcd0=http://0.0.0.0:2380 --initial-cluster-token tkn --initial-cluster-state new
|
||||
|
||||
minio:
|
||||
image: minio/minio
|
||||
ports:
|
||||
@ -129,7 +114,6 @@ services:
|
||||
- mysql
|
||||
- mongodb
|
||||
- redis
|
||||
- etcd
|
||||
- minio
|
||||
network_mode: "host"
|
||||
logging:
|
||||
@ -149,7 +133,6 @@ services:
|
||||
- mysql
|
||||
- mongodb
|
||||
- redis
|
||||
- etcd
|
||||
- minio
|
||||
- open_im_server
|
||||
network_mode: "host"
|
||||
|
4
go.mod
4
go.mod
@ -1,6 +1,6 @@
|
||||
module Open_IM
|
||||
|
||||
go 1.18
|
||||
go 1.16
|
||||
|
||||
require (
|
||||
firebase.google.com/go v3.13.0+incompatible
|
||||
@ -49,14 +49,12 @@ require (
|
||||
google.golang.org/api v0.103.0
|
||||
google.golang.org/grpc v1.52.3
|
||||
google.golang.org/protobuf v1.28.1
|
||||
gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
gorm.io/driver/mysql v1.3.5
|
||||
gorm.io/gorm v1.23.8
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0
|
||||
github.com/go-openapi/spec v0.20.6 // indirect
|
||||
github.com/go-openapi/swag v0.21.1 // indirect
|
||||
github.com/go-playground/locales v0.14.1 // indirect
|
||||
|
1
go.sum
1
go.sum
@ -510,7 +510,6 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.m
|
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
|
||||
github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
|
||||
github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0 h1:EQciDnbrYxy13PgWoY8AqoxGiPrpgBZ1R8UNe3ddc+A=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo=
|
||||
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
|
||||
|
@ -11,7 +11,6 @@ import (
|
||||
"math"
|
||||
)
|
||||
|
||||
|
||||
type ClearMsgTool struct {
|
||||
msgInterface controller.MsgInterface
|
||||
userInterface controller.UserInterface
|
||||
@ -46,15 +45,16 @@ func (c *ClearMsgTool) ClearAll() {
|
||||
|
||||
func (c *ClearMsgTool) ClearUsersMsg(ctx context.Context, userIDList []string) {
|
||||
for _, userID := range userIDList {
|
||||
if err := c.msgInterface.DeleteUserMsgsAndSetMinSeq(ctx, userID, int64(config.Config.Mongo.DBRetainChatRecords * 24 *60 *60)); err != nil {
|
||||
if err := c.msgInterface.DeleteUserMsgsAndSetMinSeq(ctx, userID, int64(config.Config.Mongo.DBRetainChatRecords*24*60*60)); err != nil {
|
||||
log.NewError(tracelog.GetOperationID(ctx), utils.GetSelfFuncName(), err.Error(), userID)
|
||||
}
|
||||
minSeqMongo, maxSeqMongo, minSeqCache, maxSeqCache, err := c.msgInterface.GetUserMinMaxSeqInMongoAndCache(ctx, userID)
|
||||
_, maxSeqMongo, minSeqCache, maxSeqCache, err := c.msgInterface.GetUserMinMaxSeqInMongoAndCache(ctx, userID)
|
||||
if err != nil {
|
||||
log.NewError(tracelog.GetOperationID(ctx), utils.GetSelfFuncName(), err.Error(), "GetUserMinMaxSeqInMongoAndCache failed", userID)
|
||||
continue
|
||||
}
|
||||
if
|
||||
c.FixUserSeq(ctx, userID, minSeqCache, maxSeqCache)
|
||||
c.CheckMaxSeqWithMongo(ctx, userID, maxSeqCache, maxSeqMongo, constant.WriteDiffusion)
|
||||
}
|
||||
}
|
||||
|
||||
@ -65,39 +65,41 @@ func (c *ClearMsgTool) ClearSuperGroupMsg(ctx context.Context, workingGroupIDLis
|
||||
log.NewError(tracelog.GetOperationID(ctx), utils.GetSelfFuncName(), "FindGroupMemberUserID", err.Error(), groupID)
|
||||
continue
|
||||
}
|
||||
if err := c.msgInterface.DeleteUserSuperGroupMsgsAndSetMinSeq(ctx, groupID, userIDs, int64(config.Config.Mongo.DBRetainChatRecords * 24 *60 *60)); err != nil {
|
||||
//log.NewError(operationID, utils.GetSelfFuncName(), err.Error(), groupID, userIDList)
|
||||
if err := c.msgInterface.DeleteUserSuperGroupMsgsAndSetMinSeq(ctx, groupID, userIDs, int64(config.Config.Mongo.DBRetainChatRecords*24*60*60)); err != nil {
|
||||
log.NewError(tracelog.GetOperationID(ctx), utils.GetSelfFuncName(), err.Error(), "DeleteUserSuperGroupMsgsAndSetMinSeq failed", groupID, userIDs, config.Config.Mongo.DBRetainChatRecords)
|
||||
}
|
||||
minSeqMongo, maxSeqMongo, minSeqCache, maxSeqCache, err := c.msgInterface.GetSuperGroupMinMaxSeqInMongoAndCache(ctx, groupID)
|
||||
|
||||
_, maxSeqMongo, maxSeqCache, err := c.msgInterface.GetSuperGroupMinMaxSeqInMongoAndCache(ctx, groupID)
|
||||
if err != nil {
|
||||
log.NewError(tracelog.GetOperationID(ctx), utils.GetSelfFuncName(), err.Error(), "GetUserMinMaxSeqInMongoAndCache failed", groupID)
|
||||
continue
|
||||
}
|
||||
c.FixGroupUserSeq(ctx, userIDs, groupID)
|
||||
c.CheckMaxSeqWithMongo(ctx, groupID, maxSeqCache, maxSeqMongo, constant.WriteDiffusion)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *ClearMsgTool) checkMaxSeqWithMongo(ctx context.Context, sourceID string, diffusionType int) error {
|
||||
var seqRedis uint64
|
||||
var err error
|
||||
if diffusionType == constant.WriteDiffusion {
|
||||
seqRedis, err = db.DB.GetUserMaxSeq(sourceID)
|
||||
} else {
|
||||
seqRedis, err = db.DB.GetGroupMaxSeq(sourceID)
|
||||
}
|
||||
if err != nil {
|
||||
if err == goRedis.Nil {
|
||||
return nil
|
||||
func (c *ClearMsgTool) FixUserSeq(ctx context.Context, userID string, minSeqCache, maxSeqCache int64) {
|
||||
if minSeqCache > maxSeqCache {
|
||||
if err := c.msgInterface.SetUserMinSeq(ctx, userID, maxSeqCache); err != nil {
|
||||
log.NewError(tracelog.GetOperationID(ctx), "SetUserMinSeq failed", userID, minSeqCache, maxSeqCache)
|
||||
} else {
|
||||
log.NewWarn(tracelog.GetOperationID(ctx), "SetUserMinSeq success", userID, minSeqCache, maxSeqCache)
|
||||
}
|
||||
return utils.Wrap(err, "GetUserMaxSeq failed")
|
||||
}
|
||||
msg, err := db.DB.GetNewestMsg(sourceID)
|
||||
if err != nil {
|
||||
return utils.Wrap(err, "GetNewestMsg failed")
|
||||
}
|
||||
if msg == nil {
|
||||
return nil
|
||||
}
|
||||
if math.Abs(float64(msg.Seq-uint32(seqRedis))) > 10 {
|
||||
log.NewWarn(operationID, utils.GetSelfFuncName(), "seqMongo, seqRedis", msg.Seq, seqRedis, sourceID, "redis maxSeq is different with msg.Seq > 10", "status: ", msg.Status, msg.SendTime)
|
||||
} else {
|
||||
log.NewInfo(operationID, utils.GetSelfFuncName(), "seqMongo, seqRedis", msg.Seq, seqRedis, sourceID, "seq and msg OK", "status:", msg.Status, msg.SendTime)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *ClearMsgTool) FixGroupUserSeq(ctx context.Context, userID string, groupID string, minSeqCache, maxSeqCache int64) {
|
||||
if minSeqCache > maxSeqCache {
|
||||
if err := c.msgInterface.SetGroupUserMinSeq(ctx, groupID, userID, maxSeqCache); err != nil {
|
||||
log.NewError(tracelog.GetOperationID(ctx), "SetGroupUserMinSeq failed", userID, minSeqCache, maxSeqCache)
|
||||
} else {
|
||||
log.NewWarn(tracelog.GetOperationID(ctx), "SetGroupUserMinSeq success", userID, minSeqCache, maxSeqCache)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (c *ClearMsgTool) CheckMaxSeqWithMongo(ctx context.Context, sourceID string, maxSeqCache, maxSeqMongo int64, diffusionType int) {
|
||||
if math.Abs(float64(maxSeqMongo-maxSeqCache)) > 10 {
|
||||
log.NewWarn(tracelog.GetOperationID(ctx), "cache max seq and mongo max seq is diff > 10", sourceID, maxSeqCache, maxSeqMongo, diffusionType)
|
||||
}
|
||||
}
|
||||
|
@ -261,7 +261,7 @@ func (och *OnlineHistoryRedisConsumerHandler) sendMessageToModifyMQ(ctx context.
|
||||
}
|
||||
}
|
||||
|
||||
func (och *OnlineHistoryRedisConsumerHandler) SendMessageToMongoCH(ctx context.Context, aggregationID string, triggerID string, messages []*pbMsg.MsgDataToMQ, lastSeq uint64) {
|
||||
func (och *OnlineHistoryRedisConsumerHandler) SendMessageToMongoCH(ctx context.Context, aggregationID string, triggerID string, messages []*pbMsg.MsgDataToMQ, lastSeq int64) {
|
||||
if len(messages) > 0 {
|
||||
pid, offset, err := och.producerToMongo.SendMessage(&pbMsg.MsgDataToMongoByMQ{LastSeq: lastSeq, AggregationID: aggregationID, MessageList: messages, TriggerID: triggerID}, aggregationID, triggerID)
|
||||
if err != nil {
|
||||
|
@ -1,7 +1,7 @@
|
||||
package logic
|
||||
package push
|
||||
|
||||
import (
|
||||
cbapi "Open_IM/pkg/callbackstruct"
|
||||
"Open_IM/pkg/callbackstruct"
|
||||
"Open_IM/pkg/common/config"
|
||||
"Open_IM/pkg/common/constant"
|
||||
"Open_IM/pkg/common/http"
|
||||
@ -15,13 +15,13 @@ func url() string {
|
||||
return config.Config.Callback.CallbackUrl
|
||||
}
|
||||
|
||||
func CallbackOfflinePush(ctx context.Context, userIDList []string, msg *common.MsgData, offlinePushUserIDList *[]string) error {
|
||||
func callbackOfflinePush(ctx context.Context, userIDList []string, msg *common.MsgData, offlinePushUserIDList *[]string) error {
|
||||
if !config.Config.Callback.CallbackOfflinePush.Enable {
|
||||
return nil
|
||||
}
|
||||
req := &cbapi.CallbackBeforePushReq{
|
||||
UserStatusBatchCallbackReq: cbapi.UserStatusBatchCallbackReq{
|
||||
UserStatusBaseCallback: cbapi.UserStatusBaseCallback{
|
||||
req := &callbackstruct.CallbackBeforePushReq{
|
||||
UserStatusBatchCallbackReq: callbackstruct.UserStatusBatchCallbackReq{
|
||||
UserStatusBaseCallback: callbackstruct.UserStatusBaseCallback{
|
||||
CallbackCommand: constant.CallbackOfflinePushCommand,
|
||||
OperationID: tracelog.GetOperationID(ctx),
|
||||
PlatformID: int(msg.SenderPlatformID),
|
||||
@ -35,10 +35,10 @@ func CallbackOfflinePush(ctx context.Context, userIDList []string, msg *common.M
|
||||
GroupID: msg.GroupID,
|
||||
ContentType: msg.ContentType,
|
||||
SessionType: msg.SessionType,
|
||||
AtUserIDList: msg.AtUserIDList,
|
||||
AtUserIDs: msg.AtUserIDList,
|
||||
Content: utils.GetContent(msg),
|
||||
}
|
||||
resp := &cbapi.CallbackBeforePushResp{}
|
||||
resp := &callbackstruct.CallbackBeforePushResp{}
|
||||
err := http.CallBackPostReturn(url(), req, resp, config.Config.Callback.CallbackOfflinePush)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -52,13 +52,13 @@ func CallbackOfflinePush(ctx context.Context, userIDList []string, msg *common.M
|
||||
return nil
|
||||
}
|
||||
|
||||
func CallbackOnlinePush(operationID string, userIDList []string, msg *common.MsgData) error {
|
||||
func callbackOnlinePush(operationID string, userIDList []string, msg *common.MsgData) error {
|
||||
if !config.Config.Callback.CallbackOnlinePush.Enable || utils.Contain(msg.SendID, userIDList...) {
|
||||
return nil
|
||||
}
|
||||
req := cbapi.CallbackBeforePushReq{
|
||||
UserStatusBatchCallbackReq: cbapi.UserStatusBatchCallbackReq{
|
||||
UserStatusBaseCallback: cbapi.UserStatusBaseCallback{
|
||||
req := callbackstruct.CallbackBeforePushReq{
|
||||
UserStatusBatchCallbackReq: callbackstruct.UserStatusBatchCallbackReq{
|
||||
UserStatusBaseCallback: callbackstruct.UserStatusBaseCallback{
|
||||
CallbackCommand: constant.CallbackOnlinePushCommand,
|
||||
OperationID: operationID,
|
||||
PlatformID: int(msg.SenderPlatformID),
|
||||
@ -66,24 +66,24 @@ func CallbackOnlinePush(operationID string, userIDList []string, msg *common.Msg
|
||||
},
|
||||
UserIDList: userIDList,
|
||||
},
|
||||
ClientMsgID: msg.ClientMsgID,
|
||||
SendID: msg.SendID,
|
||||
GroupID: msg.GroupID,
|
||||
ContentType: msg.ContentType,
|
||||
SessionType: msg.SessionType,
|
||||
AtUserIDList: msg.AtUserIDList,
|
||||
Content: utils.GetContent(msg),
|
||||
ClientMsgID: msg.ClientMsgID,
|
||||
SendID: msg.SendID,
|
||||
GroupID: msg.GroupID,
|
||||
ContentType: msg.ContentType,
|
||||
SessionType: msg.SessionType,
|
||||
AtUserIDs: msg.AtUserIDList,
|
||||
Content: utils.GetContent(msg),
|
||||
}
|
||||
resp := &cbapi.CallbackBeforePushResp{}
|
||||
resp := &callbackstruct.CallbackBeforePushResp{}
|
||||
return http.CallBackPostReturn(url(), req, resp, config.Config.Callback.CallbackOnlinePush)
|
||||
}
|
||||
|
||||
func CallbackBeforeSuperGroupOnlinePush(ctx context.Context, groupID string, msg *common.MsgData, pushToUserList *[]string) error {
|
||||
func callbackBeforeSuperGroupOnlinePush(ctx context.Context, groupID string, msg *common.MsgData, pushToUserList *[]string) error {
|
||||
if !config.Config.Callback.CallbackBeforeSuperGroupOnlinePush.Enable {
|
||||
return nil
|
||||
}
|
||||
req := cbapi.CallbackBeforeSuperGroupOnlinePushReq{
|
||||
UserStatusBaseCallback: cbapi.UserStatusBaseCallback{
|
||||
req := callbackstruct.CallbackBeforeSuperGroupOnlinePushReq{
|
||||
UserStatusBaseCallback: callbackstruct.UserStatusBaseCallback{
|
||||
CallbackCommand: constant.CallbackSuperGroupOnlinePushCommand,
|
||||
OperationID: tracelog.GetOperationID(ctx),
|
||||
PlatformID: int(msg.SenderPlatformID),
|
||||
@ -98,7 +98,7 @@ func CallbackBeforeSuperGroupOnlinePush(ctx context.Context, groupID string, msg
|
||||
Content: utils.GetContent(msg),
|
||||
Seq: msg.Seq,
|
||||
}
|
||||
resp := &cbapi.CallbackBeforeSuperGroupOnlinePushResp{}
|
||||
resp := &callbackstruct.CallbackBeforeSuperGroupOnlinePushResp{}
|
||||
if err := http.CallBackPostReturn(config.Config.Callback.CallbackUrl, req, resp, config.Config.Callback.CallbackBeforeSuperGroupOnlinePush); err != nil {
|
||||
return err
|
||||
}
|
@ -3,57 +3,52 @@ package fcm
|
||||
import (
|
||||
"Open_IM/internal/push"
|
||||
"Open_IM/pkg/common/config"
|
||||
"Open_IM/pkg/common/db"
|
||||
"Open_IM/pkg/common/log"
|
||||
"Open_IM/pkg/common/constant"
|
||||
"Open_IM/pkg/common/db/cache"
|
||||
"context"
|
||||
go_redis "github.com/go-redis/redis/v8"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
|
||||
firebase "firebase.google.com/go"
|
||||
"firebase.google.com/go/messaging"
|
||||
"github.com/go-redis/redis/v8"
|
||||
"google.golang.org/api/option"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
const SinglePushCountLimit = 400
|
||||
|
||||
var Terminal = []int{constant.IOSPlatformID, constant.AndroidPlatformID, constant.WebPlatformID}
|
||||
|
||||
type Fcm struct {
|
||||
FcmMsgCli *messaging.Client
|
||||
fcmMsgCli *messaging.Client
|
||||
cache cache.Cache
|
||||
}
|
||||
|
||||
func NewFcm() *Fcm {
|
||||
return newFcmClient()
|
||||
}
|
||||
func newFcmClient() *Fcm {
|
||||
func newFcmClient(cache cache.Cache) *Fcm {
|
||||
opt := option.WithCredentialsFile(filepath.Join(config.Root, "config", config.Config.Push.Fcm.ServiceAccount))
|
||||
fcmApp, err := firebase.NewApp(context.Background(), nil, opt)
|
||||
if err != nil {
|
||||
log.Debug("", "error initializing app: ", err.Error())
|
||||
return nil
|
||||
}
|
||||
//授权
|
||||
// auth
|
||||
// fcmClient, err := fcmApp.Auth(context.Background())
|
||||
// if err != nil {
|
||||
// log.Println("error getting Auth client: %v\n", err)
|
||||
// return
|
||||
// }
|
||||
// log.Printf("%#v\r\n", fcmClient)
|
||||
ctx := context.Background()
|
||||
fcmMsgClient, err := fcmApp.Messaging(ctx)
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
return nil
|
||||
}
|
||||
return &Fcm{FcmMsgCli: fcmMsgClient}
|
||||
return &Fcm{fcmMsgCli: fcmMsgClient}
|
||||
}
|
||||
|
||||
func (f *Fcm) Push(accounts []string, title, detailContent, operationID string, opts push.PushOpts) (string, error) {
|
||||
func (f *Fcm) Push(ctx context.Context, userIDs []string, title, content string, opts push.Opts) error {
|
||||
// accounts->registrationToken
|
||||
allTokens := make(map[string][]string, 0)
|
||||
for _, account := range accounts {
|
||||
for _, account := range userIDs {
|
||||
var personTokens []string
|
||||
for _, v := range push.PushTerminal {
|
||||
Token, err := db.DB.GetFcmToken(account, v)
|
||||
for _, v := range Terminal {
|
||||
Token, err := f.cache.GetFcmToken(ctx, account, v)
|
||||
if err == nil {
|
||||
personTokens = append(personTokens, Token)
|
||||
}
|
||||
@ -63,18 +58,16 @@ func (f *Fcm) Push(accounts []string, title, detailContent, operationID string,
|
||||
Success := 0
|
||||
Fail := 0
|
||||
notification := &messaging.Notification{}
|
||||
notification.Body = detailContent
|
||||
notification.Body = content
|
||||
notification.Title = title
|
||||
var messages []*messaging.Message
|
||||
ctx := context.Background()
|
||||
for uid, personTokens := range allTokens {
|
||||
for userID, personTokens := range allTokens {
|
||||
apns := &messaging.APNSConfig{Payload: &messaging.APNSPayload{Aps: &messaging.Aps{Sound: opts.IOSPushSound}}}
|
||||
messageCount := len(messages)
|
||||
if messageCount >= SinglePushCountLimit {
|
||||
response, err := f.FcmMsgCli.SendAll(ctx, messages)
|
||||
response, err := f.fcmMsgCli.SendAll(ctx, messages)
|
||||
if err != nil {
|
||||
Fail = Fail + messageCount
|
||||
log.Info(operationID, "some token push err", err.Error(), messageCount)
|
||||
} else {
|
||||
Success = Success + response.SuccessCount
|
||||
Fail = Fail + response.FailureCount
|
||||
@ -82,30 +75,30 @@ func (f *Fcm) Push(accounts []string, title, detailContent, operationID string,
|
||||
messages = messages[0:0]
|
||||
}
|
||||
if opts.IOSBadgeCount {
|
||||
unreadCountSum, err := db.DB.IncrUserBadgeUnreadCountSum(uid)
|
||||
unreadCountSum, err := f.cache.IncrUserBadgeUnreadCountSum(ctx, userID)
|
||||
if err == nil {
|
||||
apns.Payload.Aps.Badge = &unreadCountSum
|
||||
} else {
|
||||
log.Error(operationID, "IncrUserBadgeUnreadCountSum redis err", err.Error(), uid)
|
||||
//log.Error(operationID, "IncrUserBadgeUnreadCountSum redis err", err.Error(), uid)
|
||||
Fail++
|
||||
continue
|
||||
}
|
||||
} else {
|
||||
unreadCountSum, err := db.DB.GetUserBadgeUnreadCountSum(uid)
|
||||
unreadCountSum, err := f.cache.GetUserBadgeUnreadCountSum(ctx, userID)
|
||||
if err == nil && unreadCountSum != 0 {
|
||||
apns.Payload.Aps.Badge = &unreadCountSum
|
||||
} else if err == go_redis.Nil || unreadCountSum == 0 {
|
||||
} else if err == redis.Nil || unreadCountSum == 0 {
|
||||
zero := 1
|
||||
apns.Payload.Aps.Badge = &zero
|
||||
} else {
|
||||
log.Error(operationID, "GetUserBadgeUnreadCountSum redis err", err.Error(), uid)
|
||||
//log.Error(operationID, "GetUserBadgeUnreadCountSum redis err", err.Error(), uid)
|
||||
Fail++
|
||||
continue
|
||||
}
|
||||
}
|
||||
for _, token := range personTokens {
|
||||
temp := &messaging.Message{
|
||||
Data: map[string]string{"ex": opts.Data},
|
||||
Data: map[string]string{"ex": opts.Ex},
|
||||
Token: token,
|
||||
Notification: notification,
|
||||
APNS: apns,
|
||||
@ -116,14 +109,14 @@ func (f *Fcm) Push(accounts []string, title, detailContent, operationID string,
|
||||
}
|
||||
messageCount := len(messages)
|
||||
if messageCount > 0 {
|
||||
response, err := f.FcmMsgCli.SendAll(ctx, messages)
|
||||
response, err := f.fcmMsgCli.SendAll(ctx, messages)
|
||||
if err != nil {
|
||||
Fail = Fail + messageCount
|
||||
log.Info(operationID, "some token push err", err.Error(), messageCount)
|
||||
//log.Info(operationID, "some token push err", err.Error(), messageCount)
|
||||
} else {
|
||||
Success = Success + response.SuccessCount
|
||||
Fail = Fail + response.FailureCount
|
||||
}
|
||||
}
|
||||
return strconv.Itoa(Success) + " Success," + strconv.Itoa(Fail) + " Fail", nil
|
||||
return nil
|
||||
}
|
||||
|
142
internal/push/getui/body.go
Normal file
142
internal/push/getui/body.go
Normal file
@ -0,0 +1,142 @@
|
||||
package getui
|
||||
|
||||
import "Open_IM/pkg/common/config"
|
||||
|
||||
type CommonResp struct {
|
||||
Code int `json:"code"`
|
||||
Msg string `json:"msg"`
|
||||
Data interface{} `json:"data"`
|
||||
}
|
||||
|
||||
type AuthReq struct {
|
||||
Sign string `json:"sign"`
|
||||
Timestamp string `json:"timestamp"`
|
||||
AppKey string `json:"appkey"`
|
||||
}
|
||||
|
||||
type AuthResp struct {
|
||||
ExpireTime string `json:"expire_time"`
|
||||
Token string `json:"token"`
|
||||
}
|
||||
|
||||
type TaskResp struct {
|
||||
TaskID string `json:"taskID"`
|
||||
}
|
||||
|
||||
type Settings struct {
|
||||
TTL *int64 `json:"ttl"`
|
||||
}
|
||||
|
||||
type Audience struct {
|
||||
Alias []string `json:"alias"`
|
||||
}
|
||||
|
||||
type PushMessage struct {
|
||||
Notification *Notification `json:"notification,omitempty"`
|
||||
Transmission *string `json:"transmission,omitempty"`
|
||||
}
|
||||
|
||||
type PushChannel struct {
|
||||
Ios *Ios `json:"ios"`
|
||||
Android *Android `json:"android"`
|
||||
}
|
||||
|
||||
type PushReq struct {
|
||||
RequestID *string `json:"request_id"`
|
||||
Settings *Settings `json:"settings"`
|
||||
Audience *Audience `json:"audience"`
|
||||
PushMessage *PushMessage `json:"push_message"`
|
||||
PushChannel *PushChannel `json:"push_channel"`
|
||||
IsAsync *bool `json:"is_async"`
|
||||
TaskID *string `json:"taskid"`
|
||||
}
|
||||
|
||||
type Ios struct {
|
||||
NotificationType *string `json:"type"`
|
||||
AutoBadge *string `json:"auto_badge"`
|
||||
Aps struct {
|
||||
Sound string `json:"sound"`
|
||||
Alert Alert `json:"alert"`
|
||||
} `json:"aps"`
|
||||
}
|
||||
|
||||
type Alert struct {
|
||||
Title string `json:"title"`
|
||||
Body string `json:"body"`
|
||||
}
|
||||
|
||||
type Android struct {
|
||||
Ups struct {
|
||||
Notification Notification `json:"notification"`
|
||||
Options Options `json:"options"`
|
||||
} `json:"ups"`
|
||||
}
|
||||
|
||||
type Notification struct {
|
||||
Title string `json:"title"`
|
||||
Body string `json:"body"`
|
||||
ChannelID string `json:"channelID"`
|
||||
ChannelName string `json:"ChannelName"`
|
||||
ClickType string `json:"click_type"`
|
||||
}
|
||||
|
||||
type Options struct {
|
||||
HW struct {
|
||||
DefaultSound bool `json:"/message/android/notification/default_sound"`
|
||||
ChannelID string `json:"/message/android/notification/channel_id"`
|
||||
Sound string `json:"/message/android/notification/sound"`
|
||||
Importance string `json:"/message/android/notification/importance"`
|
||||
} `json:"HW"`
|
||||
XM struct {
|
||||
ChannelID string `json:"/extra.channel_id"`
|
||||
} `json:"XM"`
|
||||
VV struct {
|
||||
Classification int `json:"/classification"`
|
||||
} `json:"VV"`
|
||||
}
|
||||
|
||||
func newPushReq(title, content string) PushReq {
|
||||
pushReq := PushReq{PushMessage: &PushMessage{Notification: &Notification{
|
||||
Title: title,
|
||||
Body: content,
|
||||
ClickType: "startapp",
|
||||
ChannelID: config.Config.Push.Getui.ChannelID,
|
||||
ChannelName: config.Config.Push.Getui.ChannelName,
|
||||
}}}
|
||||
return pushReq
|
||||
}
|
||||
|
||||
func (pushReq *PushReq) setPushChannel(title string, body string) {
|
||||
pushReq.PushChannel = &PushChannel{}
|
||||
// autoBadge := "+1"
|
||||
pushReq.PushChannel.Ios = &Ios{}
|
||||
notify := "notify"
|
||||
pushReq.PushChannel.Ios.NotificationType = ¬ify
|
||||
pushReq.PushChannel.Ios.Aps.Sound = "default"
|
||||
pushReq.PushChannel.Ios.Aps.Alert = Alert{
|
||||
Title: title,
|
||||
Body: body,
|
||||
}
|
||||
pushReq.PushChannel.Android = &Android{}
|
||||
pushReq.PushChannel.Android.Ups.Notification = Notification{
|
||||
Title: title,
|
||||
Body: body,
|
||||
ClickType: "startapp",
|
||||
}
|
||||
pushReq.PushChannel.Android.Ups.Options = Options{
|
||||
HW: struct {
|
||||
DefaultSound bool `json:"/message/android/notification/default_sound"`
|
||||
ChannelID string `json:"/message/android/notification/channel_id"`
|
||||
Sound string `json:"/message/android/notification/sound"`
|
||||
Importance string `json:"/message/android/notification/importance"`
|
||||
}{ChannelID: "RingRing4", Sound: "/raw/ring001", Importance: "NORMAL"},
|
||||
XM: struct {
|
||||
ChannelID string `json:"/extra.channel_id"`
|
||||
}{ChannelID: "high_system"},
|
||||
VV: struct {
|
||||
Classification int "json:\"/classification\""
|
||||
}{
|
||||
Classification: 1,
|
||||
},
|
||||
}
|
||||
}
|
@ -3,16 +3,16 @@ package getui
|
||||
import (
|
||||
"Open_IM/internal/push"
|
||||
"Open_IM/pkg/common/config"
|
||||
"Open_IM/pkg/common/db"
|
||||
"Open_IM/pkg/common/db/cache"
|
||||
//http2 "Open_IM/pkg/common/http"
|
||||
"Open_IM/pkg/common/log"
|
||||
"Open_IM/pkg/utils"
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/sha256"
|
||||
"errors"
|
||||
|
||||
//"crypto/sha512"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strconv"
|
||||
@ -20,166 +20,61 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
GetuiClient *Getui
|
||||
|
||||
TokenExpireError = errors.New("token expire")
|
||||
)
|
||||
|
||||
const (
|
||||
PushURL = "/push/single/alias"
|
||||
AuthURL = "/auth"
|
||||
TaskURL = "/push/list/message"
|
||||
BatchPushURL = "/push/list/alias"
|
||||
pushURL = "/push/single/alias"
|
||||
authURL = "/auth"
|
||||
taskURL = "/push/list/message"
|
||||
batchPushURL = "/push/list/alias"
|
||||
|
||||
tokenExpire = 10001
|
||||
ttl = 0
|
||||
)
|
||||
|
||||
func init() {
|
||||
GetuiClient = newGetuiClient()
|
||||
type Client struct {
|
||||
cache cache.Cache
|
||||
}
|
||||
|
||||
type Getui struct{}
|
||||
|
||||
type GetuiCommonResp struct {
|
||||
Code int `json:"code"`
|
||||
Msg string `json:"msg"`
|
||||
Data interface{} `json:"data"`
|
||||
func newClient(cache cache.Cache) *Client {
|
||||
return &Client{cache: cache}
|
||||
}
|
||||
|
||||
type AuthReq struct {
|
||||
Sign string `json:"sign"`
|
||||
Timestamp string `json:"timestamp"`
|
||||
Appkey string `json:"appkey"`
|
||||
}
|
||||
|
||||
type AuthResp struct {
|
||||
ExpireTime string `json:"expire_time"`
|
||||
Token string `json:"token"`
|
||||
}
|
||||
|
||||
type TaskResp struct {
|
||||
TaskID string `json:"taskID"`
|
||||
}
|
||||
|
||||
type Settings struct {
|
||||
TTL *int64 `json:"ttl"`
|
||||
}
|
||||
|
||||
type Audience struct {
|
||||
Alias []string `json:"alias"`
|
||||
}
|
||||
|
||||
type PushMessage struct {
|
||||
Notification *Notification `json:"notification,omitempty"`
|
||||
Transmission *string `json:"transmission,omitempty"`
|
||||
}
|
||||
|
||||
type PushChannel struct {
|
||||
Ios *Ios `json:"ios"`
|
||||
Android *Android `json:"android"`
|
||||
}
|
||||
|
||||
type PushReq struct {
|
||||
RequestID *string `json:"request_id"`
|
||||
Settings *Settings `json:"settings"`
|
||||
Audience *Audience `json:"audience"`
|
||||
PushMessage *PushMessage `json:"push_message"`
|
||||
PushChannel *PushChannel `json:"push_channel"`
|
||||
IsAsync *bool `json:"is_async"`
|
||||
Taskid *string `json:"taskid"`
|
||||
}
|
||||
|
||||
type Ios struct {
|
||||
NotiType *string `json:"type"`
|
||||
AutoBadge *string `json:"auto_badge"`
|
||||
Aps struct {
|
||||
Sound string `json:"sound"`
|
||||
Alert Alert `json:"alert"`
|
||||
} `json:"aps"`
|
||||
}
|
||||
|
||||
type Alert struct {
|
||||
Title string `json:"title"`
|
||||
Body string `json:"body"`
|
||||
}
|
||||
|
||||
type Android struct {
|
||||
Ups struct {
|
||||
Notification Notification `json:"notification"`
|
||||
Options Options `json:"options"`
|
||||
} `json:"ups"`
|
||||
}
|
||||
|
||||
type Notification struct {
|
||||
Title string `json:"title"`
|
||||
Body string `json:"body"`
|
||||
ChannelID string `json:"channelID"`
|
||||
ChannelName string `json:"ChannelName"`
|
||||
ClickType string `json:"click_type"`
|
||||
}
|
||||
|
||||
type Options struct {
|
||||
HW struct {
|
||||
DefaultSound bool `json:"/message/android/notification/default_sound"`
|
||||
ChannelID string `json:"/message/android/notification/channel_id"`
|
||||
Sound string `json:"/message/android/notification/sound"`
|
||||
Importance string `json:"/message/android/notification/importance"`
|
||||
} `json:"HW"`
|
||||
XM struct {
|
||||
ChannelID string `json:"/extra.channel_id"`
|
||||
} `json:"XM"`
|
||||
VV struct {
|
||||
Classification int `json:"/classification"`
|
||||
} `json:"VV"`
|
||||
}
|
||||
|
||||
type PushResp struct {
|
||||
}
|
||||
|
||||
func newGetuiClient() *Getui {
|
||||
return &Getui{}
|
||||
}
|
||||
|
||||
func (g *Getui) Push(userIDList []string, title, detailContent, operationID string, opts push.PushOpts) (resp string, err error) {
|
||||
token, err := db.DB.GetGetuiToken()
|
||||
log.NewDebug(operationID, utils.GetSelfFuncName(), "token:", token, userIDList)
|
||||
func (g *Client) Push(ctx context.Context, userIDs []string, title, content, operationID string, opts *push.Opts) error {
|
||||
token, err := g.cache.GetGetuiToken(ctx)
|
||||
if err != nil {
|
||||
log.NewError(operationID, utils.GetSelfFuncName(), "GetGetuiToken failed", err.Error())
|
||||
}
|
||||
if token == "" || err != nil {
|
||||
token, err = g.getTokenAndSave2Redis(operationID)
|
||||
token, err = g.getTokenAndSave2Redis(ctx)
|
||||
if err != nil {
|
||||
log.NewError(operationID, utils.GetSelfFuncName(), "getTokenAndSave2Redis failed", err.Error())
|
||||
return "", utils.Wrap(err, "")
|
||||
return utils.Wrap(err, "")
|
||||
}
|
||||
}
|
||||
|
||||
pushReq := PushReq{PushMessage: &PushMessage{Notification: &Notification{
|
||||
Title: title,
|
||||
Body: detailContent,
|
||||
ClickType: "startapp",
|
||||
ChannelID: config.Config.Push.Getui.ChannelID,
|
||||
ChannelName: config.Config.Push.Getui.ChannelName,
|
||||
}}}
|
||||
pushReq.setPushChannel(title, detailContent)
|
||||
pushResp := PushResp{}
|
||||
if len(userIDList) > 1 {
|
||||
taskID, err := g.GetTaskID(operationID, token, pushReq)
|
||||
pushReq := newPushReq(title, content)
|
||||
pushReq.setPushChannel(title, content)
|
||||
pushResp := struct{}{}
|
||||
if len(userIDs) > 1 {
|
||||
taskID, err := g.GetTaskID(ctx, token, pushReq)
|
||||
if err != nil {
|
||||
return "", utils.Wrap(err, "GetTaskIDAndSave2Redis failed")
|
||||
return utils.Wrap(err, "GetTaskIDAndSave2Redis failed")
|
||||
}
|
||||
pushReq = PushReq{Audience: &Audience{Alias: userIDList}}
|
||||
pushReq = PushReq{Audience: &Audience{Alias: userIDs}}
|
||||
var IsAsync = true
|
||||
pushReq.IsAsync = &IsAsync
|
||||
pushReq.Taskid = &taskID
|
||||
err = g.request(BatchPushURL, pushReq, token, &pushResp, operationID)
|
||||
pushReq.TaskID = &taskID
|
||||
err = g.request(ctx, batchPushURL, pushReq, token, &pushResp)
|
||||
} else {
|
||||
reqID := utils.OperationIDGenerator()
|
||||
pushReq.RequestID = &reqID
|
||||
pushReq.Audience = &Audience{Alias: []string{userIDList[0]}}
|
||||
err = g.request(PushURL, pushReq, token, &pushResp, operationID)
|
||||
pushReq.Audience = &Audience{Alias: []string{userIDs[0]}}
|
||||
err = g.request(ctx, pushURL, pushReq, token, &pushResp)
|
||||
}
|
||||
switch err {
|
||||
case TokenExpireError:
|
||||
token, err = g.getTokenAndSave2Redis(operationID)
|
||||
token, err = g.getTokenAndSave2Redis(ctx)
|
||||
if err != nil {
|
||||
log.NewError(operationID, utils.GetSelfFuncName(), "getTokenAndSave2Redis failed, ", err.Error())
|
||||
} else {
|
||||
@ -187,52 +82,47 @@ func (g *Getui) Push(userIDList []string, title, detailContent, operationID stri
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
return "", utils.Wrap(err, "push failed")
|
||||
return utils.Wrap(err, "push failed")
|
||||
}
|
||||
respBytes, err := json.Marshal(pushResp)
|
||||
return string(respBytes), utils.Wrap(err, "")
|
||||
return utils.Wrap(err, "")
|
||||
}
|
||||
|
||||
func (g *Getui) Auth(operationID string, timeStamp int64) (token string, expireTime int64, err error) {
|
||||
log.NewInfo(operationID, utils.GetSelfFuncName(), config.Config.Push.Getui.AppKey, timeStamp, config.Config.Push.Getui.MasterSecret)
|
||||
func (g *Client) Auth(ctx context.Context, timeStamp int64) (token string, expireTime int64, err error) {
|
||||
h := sha256.New()
|
||||
h.Write([]byte(config.Config.Push.Getui.AppKey + strconv.Itoa(int(timeStamp)) + config.Config.Push.Getui.MasterSecret))
|
||||
sum := h.Sum(nil)
|
||||
sign := hex.EncodeToString(sum)
|
||||
log.NewInfo(operationID, utils.GetSelfFuncName(), "sha256 result", sign)
|
||||
sign := hex.EncodeToString(h.Sum(nil))
|
||||
reqAuth := AuthReq{
|
||||
Sign: sign,
|
||||
Timestamp: strconv.Itoa(int(timeStamp)),
|
||||
Appkey: config.Config.Push.Getui.AppKey,
|
||||
AppKey: config.Config.Push.Getui.AppKey,
|
||||
}
|
||||
respAuth := AuthResp{}
|
||||
err = g.request(AuthURL, reqAuth, "", &respAuth, operationID)
|
||||
err = g.request(ctx, authURL, reqAuth, "", &respAuth)
|
||||
if err != nil {
|
||||
return "", 0, err
|
||||
}
|
||||
log.NewInfo(operationID, utils.GetSelfFuncName(), "result: ", respAuth)
|
||||
//log.NewInfo(operationID, utils.GetSelfFuncName(), "result: ", respAuth)
|
||||
expire, err := strconv.Atoi(respAuth.ExpireTime)
|
||||
return respAuth.Token, int64(expire), err
|
||||
}
|
||||
|
||||
func (g *Getui) GetTaskID(operationID, token string, pushReq PushReq) (string, error) {
|
||||
func (g *Client) GetTaskID(ctx context.Context, token string, pushReq PushReq) (string, error) {
|
||||
respTask := TaskResp{}
|
||||
ttl := int64(1000 * 60 * 5)
|
||||
pushReq.Settings = &Settings{TTL: &ttl}
|
||||
err := g.request(TaskURL, pushReq, token, &respTask, operationID)
|
||||
err := g.request(ctx, taskURL, pushReq, token, &respTask)
|
||||
if err != nil {
|
||||
return "", utils.Wrap(err, "")
|
||||
}
|
||||
return respTask.TaskID, nil
|
||||
}
|
||||
|
||||
func (g *Getui) request(url string, content interface{}, token string, returnStruct interface{}, operationID string) error {
|
||||
func (g *Client) request(ctx context.Context, url string, content interface{}, token string, output interface{}) error {
|
||||
con, err := json.Marshal(content)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
client := &http.Client{}
|
||||
log.Debug(operationID, utils.GetSelfFuncName(), "json:", string(con), "token:", token)
|
||||
req, err := http.NewRequest("POST", config.Config.Push.Getui.PushUrl+url, bytes.NewBuffer(con))
|
||||
if err != nil {
|
||||
return err
|
||||
@ -250,74 +140,38 @@ func (g *Getui) request(url string, content interface{}, token string, returnStr
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.NewDebug(operationID, "getui", utils.GetSelfFuncName(), "resp, ", string(result))
|
||||
commonResp := GetuiCommonResp{}
|
||||
commonResp.Data = returnStruct
|
||||
//log.NewDebug(operationID, "getui", utils.GetSelfFuncName(), "resp, ", string(result))
|
||||
commonResp := CommonResp{}
|
||||
commonResp.Data = output
|
||||
if err := json.Unmarshal(result, &commonResp); err != nil {
|
||||
return err
|
||||
}
|
||||
if commonResp.Code == 10001 {
|
||||
if commonResp.Code == tokenExpire {
|
||||
return TokenExpireError
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (pushReq *PushReq) setPushChannel(title string, body string) {
|
||||
pushReq.PushChannel = &PushChannel{}
|
||||
// autoBadge := "+1"
|
||||
pushReq.PushChannel.Ios = &Ios{}
|
||||
notify := "notify"
|
||||
pushReq.PushChannel.Ios.NotiType = ¬ify
|
||||
pushReq.PushChannel.Ios.Aps.Sound = "default"
|
||||
pushReq.PushChannel.Ios.Aps.Alert = Alert{
|
||||
Title: title,
|
||||
Body: body,
|
||||
}
|
||||
pushReq.PushChannel.Android = &Android{}
|
||||
pushReq.PushChannel.Android.Ups.Notification = Notification{
|
||||
Title: title,
|
||||
Body: body,
|
||||
ClickType: "startapp",
|
||||
}
|
||||
pushReq.PushChannel.Android.Ups.Options = Options{
|
||||
HW: struct {
|
||||
DefaultSound bool `json:"/message/android/notification/default_sound"`
|
||||
ChannelID string `json:"/message/android/notification/channel_id"`
|
||||
Sound string `json:"/message/android/notification/sound"`
|
||||
Importance string `json:"/message/android/notification/importance"`
|
||||
}{ChannelID: "RingRing4", Sound: "/raw/ring001", Importance: "NORMAL"},
|
||||
XM: struct {
|
||||
ChannelID string `json:"/extra.channel_id"`
|
||||
}{ChannelID: "high_system"},
|
||||
VV: struct {
|
||||
Classification int "json:\"/classification\""
|
||||
}{
|
||||
Classification: 1,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (g *Getui) getTokenAndSave2Redis(operationID string) (token string, err error) {
|
||||
token, expireTime, err := g.Auth(operationID, time.Now().UnixNano()/1e6)
|
||||
func (g *Client) getTokenAndSave2Redis(ctx context.Context) (token string, err error) {
|
||||
token, _, err = g.Auth(ctx, time.Now().UnixNano()/1e6)
|
||||
if err != nil {
|
||||
return "", utils.Wrap(err, "Auth failed")
|
||||
}
|
||||
log.NewDebug(operationID, "getui", utils.GetSelfFuncName(), token, expireTime, err)
|
||||
err = db.DB.SetGetuiToken(token, 60*60*23)
|
||||
err = g.cache.SetGetuiTaskID(ctx, token, 60*60*23)
|
||||
if err != nil {
|
||||
return "", utils.Wrap(err, "Auth failed")
|
||||
}
|
||||
return token, nil
|
||||
}
|
||||
|
||||
func (g *Getui) GetTaskIDAndSave2Redis(operationID, token string, pushReq PushReq) (taskID string, err error) {
|
||||
func (g *Client) GetTaskIDAndSave2Redis(ctx context.Context, token string, pushReq PushReq) (taskID string, err error) {
|
||||
ttl := int64(1000 * 60 * 60 * 24)
|
||||
pushReq.Settings = &Settings{TTL: &ttl}
|
||||
taskID, err = g.GetTaskID(operationID, token, pushReq)
|
||||
taskID, err = g.GetTaskID(ctx, token, pushReq)
|
||||
if err != nil {
|
||||
return "", utils.Wrap(err, "GetTaskIDAndSave2Redis failed")
|
||||
}
|
||||
err = db.DB.SetGetuiTaskID(taskID, 60*60*23)
|
||||
err = g.cache.SetGetuiTaskID(ctx, taskID, 60*60*23)
|
||||
if err != nil {
|
||||
return "", utils.Wrap(err, "Auth failed")
|
||||
}
|
||||
|
@ -4,27 +4,23 @@
|
||||
** author("fg,Gordon@open-im.io").
|
||||
** time(2021/3/22 15:33).
|
||||
*/
|
||||
package logic
|
||||
package push
|
||||
|
||||
import (
|
||||
pusher "Open_IM/internal/push"
|
||||
fcm "Open_IM/internal/push/fcm"
|
||||
"Open_IM/internal/push/getui"
|
||||
jpush "Open_IM/internal/push/jpush"
|
||||
"Open_IM/internal/push/mobpush"
|
||||
"Open_IM/pkg/common/config"
|
||||
"Open_IM/pkg/common/constant"
|
||||
"Open_IM/pkg/common/kafka"
|
||||
prome "Open_IM/pkg/common/prometheus"
|
||||
"Open_IM/pkg/common/prome"
|
||||
"Open_IM/pkg/statistics"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
var (
|
||||
rpcServer RPCServer
|
||||
pushCh PushConsumerHandler
|
||||
producer *kafka.Producer
|
||||
offlinePusher pusher.OfflinePusher
|
||||
pushCh ConsumerHandler
|
||||
offlinePusher OfflinePusher
|
||||
successCount uint64
|
||||
)
|
||||
|
||||
@ -34,7 +30,6 @@ func Init(rpcPort int) {
|
||||
|
||||
}
|
||||
func init() {
|
||||
producer = kafka.NewKafkaProducer(config.Config.Kafka.Ws2mschat.Addr, config.Config.Kafka.Ws2mschat.Topic)
|
||||
statistics.NewStatistics(&successCount, config.Config.ModuleName.PushName, fmt.Sprintf("%d second push to msg_gateway count", constant.StatisticsTimeInterval), constant.StatisticsTimeInterval)
|
||||
if *config.Config.Push.Getui.Enable {
|
||||
offlinePusher = getui.GetuiClient
|
||||
@ -46,10 +41,6 @@ func init() {
|
||||
if config.Config.Push.Fcm.Enable {
|
||||
offlinePusher = fcm.NewFcm()
|
||||
}
|
||||
|
||||
if config.Config.Push.Mob.Enable {
|
||||
offlinePusher = mobpush.MobPushClient
|
||||
}
|
||||
}
|
||||
|
||||
func initPrometheus() {
|
||||
@ -59,7 +50,7 @@ func initPrometheus() {
|
||||
|
||||
func Run(promethuesPort int) {
|
||||
go rpcServer.run()
|
||||
go pushCh.pushConsumerGroup.RegisterHandleAndConsumer(&pushCh)
|
||||
go pushCh.ConsumerGroup.RegisterHandleAndConsumer(&pushCh)
|
||||
go func() {
|
||||
err := prome.StartPromeSrv(promethuesPort)
|
||||
if err != nil {
|
@ -1,4 +1,4 @@
|
||||
package requestbody
|
||||
package body
|
||||
|
||||
const (
|
||||
TAG = "tag"
|
||||
@ -20,7 +20,6 @@ func (a *Audience) set(key string, v []string) {
|
||||
a.audience = make(map[string][]string)
|
||||
a.Object = a.audience
|
||||
}
|
||||
|
||||
//v, ok = this.audience[key]
|
||||
//if ok {
|
||||
// return
|
@ -1,4 +1,4 @@
|
||||
package requestbody
|
||||
package body
|
||||
|
||||
type Message struct {
|
||||
MsgContent string `json:"msg_content"`
|
@ -1,4 +1,4 @@
|
||||
package requestbody
|
||||
package body
|
||||
|
||||
import (
|
||||
"Open_IM/pkg/common/config"
|
@ -1,4 +1,4 @@
|
||||
package requestbody
|
||||
package body
|
||||
|
||||
type Options struct {
|
||||
ApnsProduction bool `json:"apns_production"`
|
@ -1,4 +1,4 @@
|
||||
package requestbody
|
||||
package body
|
||||
|
||||
import (
|
||||
"Open_IM/pkg/common/constant"
|
@ -1,4 +1,4 @@
|
||||
package requestbody
|
||||
package body
|
||||
|
||||
type PushObj struct {
|
||||
Platform interface{} `json:"platform"`
|
@ -1,13 +0,0 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func GetAuthorization(Appkey string, MasterSecret string) string {
|
||||
str := fmt.Sprintf("%s:%s", Appkey, MasterSecret)
|
||||
buf := []byte(str)
|
||||
Authorization := fmt.Sprintf("Basic %s", base64.StdEncoding.EncodeToString(buf))
|
||||
return Authorization
|
||||
}
|
@ -2,11 +2,13 @@ package push
|
||||
|
||||
import (
|
||||
"Open_IM/internal/push"
|
||||
"Open_IM/internal/push/jpush/body"
|
||||
"Open_IM/internal/push/jpush/common"
|
||||
"Open_IM/internal/push/jpush/requestBody"
|
||||
"Open_IM/pkg/common/config"
|
||||
"bytes"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
)
|
||||
@ -33,26 +35,31 @@ func (j *JPush) SetAlias(cid, alias string) (resp string, err error) {
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func (j *JPush) getAuthorization(Appkey string, MasterSecret string) string {
|
||||
str := fmt.Sprintf("%s:%s", Appkey, MasterSecret)
|
||||
buf := []byte(str)
|
||||
Authorization := fmt.Sprintf("Basic %s", base64.StdEncoding.EncodeToString(buf))
|
||||
return Authorization
|
||||
}
|
||||
|
||||
func (j *JPush) Push(accounts []string, title, detailContent, operationID string, opts push.PushOpts) (string, error) {
|
||||
|
||||
var pf requestbody.Platform
|
||||
var pf body.Platform
|
||||
pf.SetAll()
|
||||
var au requestbody.Audience
|
||||
var au body.Audience
|
||||
au.SetAlias(accounts)
|
||||
var no requestbody.Notification
|
||||
|
||||
var extras requestbody.Extras
|
||||
var no body.Notification
|
||||
var extras body.Extras
|
||||
if opts.Signal.ClientMsgID != "" {
|
||||
extras.ClientMsgID = opts.Signal.ClientMsgID
|
||||
}
|
||||
no.IOSEnableMutableContent()
|
||||
no.SetExtras(extras)
|
||||
no.SetAlert(title)
|
||||
var me requestbody.Message
|
||||
var me body.Message
|
||||
me.SetMsgContent(detailContent)
|
||||
var o requestbody.Options
|
||||
var o body.Options
|
||||
o.SetApnsProduction(config.Config.IOSPush.Production)
|
||||
var po requestbody.PushObj
|
||||
var po body.PushObj
|
||||
po.SetPlatform(&pf)
|
||||
po.SetAudience(&au)
|
||||
po.SetNotification(&no)
|
||||
@ -68,8 +75,7 @@ func (j *JPush) Push(accounts []string, title, detailContent, operationID string
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
req.Header.Set("Authorization", common.GetAuthorization(config.Config.Push.Jpns.AppKey, config.Config.Push.Jpns.MasterSecret))
|
||||
|
||||
req.Header.Set("Authorization", j.getAuthorization(config.Config.Push.Jpns.AppKey, config.Config.Push.Jpns.MasterSecret))
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
@ -1,18 +0,0 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"Open_IM/pkg/common/config"
|
||||
"crypto/md5"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
func GetSign(paramsStr string) string {
|
||||
h := md5.New()
|
||||
io.WriteString(h, paramsStr)
|
||||
io.WriteString(h, config.Config.Push.Mob.AppSecret)
|
||||
fmt.Printf("%x", h.Sum(nil))
|
||||
|
||||
return hex.EncodeToString(h.Sum(nil))
|
||||
}
|
@ -1,73 +0,0 @@
|
||||
package mobpush
|
||||
|
||||
import (
|
||||
"Open_IM/internal/push"
|
||||
"Open_IM/internal/push/mobpush/common"
|
||||
"Open_IM/internal/push/mobpush/requestParams"
|
||||
"Open_IM/pkg/common/config"
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
MobPushClient *MobPush
|
||||
)
|
||||
|
||||
func init() {
|
||||
MobPushClient = newGetuiClient()
|
||||
}
|
||||
|
||||
type MobPush struct{}
|
||||
|
||||
func newGetuiClient() *MobPush {
|
||||
return &MobPush{}
|
||||
}
|
||||
|
||||
func (j *MobPush) Push(accounts []string, alert, detailContent, operationID string, opts push.PushOpts) (string, error) {
|
||||
var target requestparams.PushTarget
|
||||
target.SetAlias(accounts)
|
||||
target.SetTarget(2)
|
||||
|
||||
var no requestparams.PushNotify
|
||||
no.SetType(1)
|
||||
no.SetIosProduction(1)
|
||||
no.SetPlats([]int{1, 2})
|
||||
no.SetContent(alert)
|
||||
|
||||
var forward requestparams.PushForward
|
||||
forward.SetNextType(2)
|
||||
forward.SetScheme(config.Config.Push.Mob.Scheme)
|
||||
|
||||
var po requestparams.PushObj
|
||||
po.SetSource("webapi")
|
||||
po.SetAppkey(config.Config.Push.Mob.AppKey)
|
||||
po.SetPushTarget(&target)
|
||||
po.SetPushNotify(&no)
|
||||
po.SetPushForward(&forward)
|
||||
|
||||
con, err := json.Marshal(po)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
client := &http.Client{}
|
||||
req, err := http.NewRequest("POST", config.Config.Push.Mob.PushUrl, strings.NewReader(string(con)))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
req.Header.Set("key", config.Config.Push.Mob.AppKey)
|
||||
req.Header.Set("sign", common.GetSign(string(con)))
|
||||
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
result, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(result), nil
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
package requestparams
|
||||
|
||||
type PushForward struct {
|
||||
NextType int `json:"nextType"`
|
||||
Scheme string `json:"scheme,omitempty"`
|
||||
}
|
||||
|
||||
func (m *PushForward) SetNextType(c int) {
|
||||
m.NextType = c
|
||||
}
|
||||
|
||||
func (m *PushForward) SetScheme(t string) {
|
||||
m.Scheme = t
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
package requestparams
|
||||
|
||||
type PushNotify struct {
|
||||
Plats []int `json:"plats,omitempty"`
|
||||
IosProduction int `json:"iosProduction,omitempty"`
|
||||
Content string `json:"content,omitempty"`
|
||||
Type int `json:"type,omitempty"`
|
||||
}
|
||||
|
||||
func (n *PushNotify) SetPlats(plats []int) {
|
||||
n.Plats = plats
|
||||
|
||||
}
|
||||
|
||||
func (n *PushNotify) SetIosProduction(iosProduction int) {
|
||||
n.IosProduction = iosProduction
|
||||
|
||||
}
|
||||
|
||||
func (n *PushNotify) SetContent(content string) {
|
||||
n.Content = content
|
||||
}
|
||||
|
||||
func (n *PushNotify) SetType(Type int) {
|
||||
n.Type = Type
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
package requestparams
|
||||
|
||||
type PushObj struct {
|
||||
Source interface{} `json:"source"`
|
||||
Appkey interface{} `json:"appkey"`
|
||||
PushTarget interface{} `json:"pushTarget,omitempty"`
|
||||
PushNotify interface{} `json:"pushNotify,omitempty"`
|
||||
PushForward interface{} `json:"pushForward,omitempty"`
|
||||
}
|
||||
|
||||
func (p *PushObj) SetSource(source string) {
|
||||
p.Source = source
|
||||
}
|
||||
|
||||
func (p *PushObj) SetAppkey(appkey string) {
|
||||
p.Appkey = appkey
|
||||
}
|
||||
|
||||
func (p *PushObj) SetPushTarget(no *PushTarget) {
|
||||
p.PushTarget = no
|
||||
}
|
||||
|
||||
func (p *PushObj) SetPushNotify(m *PushNotify) {
|
||||
p.PushNotify = m
|
||||
}
|
||||
func (p *PushObj) SetPushForward(o *PushForward) {
|
||||
p.PushForward = o
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
package requestparams
|
||||
|
||||
type PushTarget struct {
|
||||
Target interface{} `json:"target,omitempty"`
|
||||
Alias []string `json:"alias,omitempty"`
|
||||
}
|
||||
|
||||
func (p *PushTarget) SetTarget(target int) {
|
||||
p.Target = target
|
||||
}
|
||||
func (p *PushTarget) SetAlias(alias []string) {
|
||||
p.Alias = alias
|
||||
}
|
@ -4,7 +4,7 @@
|
||||
** author("fg,Gordon@tuoyun.net").
|
||||
** time(2021/5/13 10:33).
|
||||
*/
|
||||
package logic
|
||||
package push
|
||||
|
||||
import (
|
||||
"Open_IM/pkg/common/config"
|
||||
@ -18,21 +18,16 @@ import (
|
||||
"github.com/golang/protobuf/proto"
|
||||
)
|
||||
|
||||
type fcb func(msg []byte)
|
||||
|
||||
type PushConsumerHandler struct {
|
||||
msgHandle map[string]fcb
|
||||
type ConsumerHandler struct {
|
||||
pushConsumerGroup *kfk.MConsumerGroup
|
||||
}
|
||||
|
||||
func (ms *PushConsumerHandler) Init() {
|
||||
ms.msgHandle = make(map[string]fcb)
|
||||
ms.msgHandle[config.Config.Kafka.Ms2pschat.Topic] = ms.handleMs2PsChat
|
||||
ms.pushConsumerGroup = kfk.NewMConsumerGroup(&kfk.MConsumerGroupConfig{KafkaVersion: sarama.V2_0_0_0,
|
||||
func (c *ConsumerHandler) Init() {
|
||||
c.pushConsumerGroup = kfk.NewMConsumerGroup(&kfk.MConsumerGroupConfig{KafkaVersion: sarama.V2_0_0_0,
|
||||
OffsetsInitial: sarama.OffsetNewest, IsReturnErr: false}, []string{config.Config.Kafka.Ms2pschat.Topic}, config.Config.Kafka.Ms2pschat.Addr,
|
||||
config.Config.Kafka.ConsumerGroupID.MsgToPush)
|
||||
}
|
||||
func (ms *PushConsumerHandler) handleMs2PsChat(msg []byte) {
|
||||
func (c *ConsumerHandler) handleMs2PsChat(msg []byte) {
|
||||
log.NewDebug("", "msg come from kafka And push!!!", "msg", string(msg))
|
||||
msgFromMQ := pbChat.PushMsgDataToMQ{}
|
||||
if err := proto.Unmarshal(msg, &msgFromMQ); err != nil {
|
||||
@ -55,16 +50,14 @@ func (ms *PushConsumerHandler) handleMs2PsChat(msg []byte) {
|
||||
default:
|
||||
MsgToUser(pbData)
|
||||
}
|
||||
//Call push module to send message to the user
|
||||
//MsgToUser((*pbPush.PushMsgReq)(&msgFromMQ))
|
||||
}
|
||||
func (PushConsumerHandler) Setup(_ sarama.ConsumerGroupSession) error { return nil }
|
||||
func (PushConsumerHandler) Cleanup(_ sarama.ConsumerGroupSession) error { return nil }
|
||||
func (ms *PushConsumerHandler) ConsumeClaim(sess sarama.ConsumerGroupSession,
|
||||
func (ConsumerHandler) Setup(_ sarama.ConsumerGroupSession) error { return nil }
|
||||
func (ConsumerHandler) Cleanup(_ sarama.ConsumerGroupSession) error { return nil }
|
||||
func (c *ConsumerHandler) ConsumeClaim(sess sarama.ConsumerGroupSession,
|
||||
claim sarama.ConsumerGroupClaim) error {
|
||||
for msg := range claim.Messages() {
|
||||
log.NewDebug("", "kafka get info to mysql", "msgTopic", msg.Topic, "msgPartition", msg.Partition, "msg", string(msg.Value))
|
||||
ms.msgHandle[msg.Topic](msg.Value)
|
||||
c.handleMs2PsChat(msg.Value)
|
||||
sess.MarkMessage(msg, "")
|
||||
}
|
||||
return nil
|
@ -1,18 +1,16 @@
|
||||
package push
|
||||
|
||||
import "Open_IM/pkg/common/constant"
|
||||
|
||||
var PushTerminal = []int{constant.IOSPlatformID, constant.AndroidPlatformID, constant.WebPlatformID}
|
||||
import "context"
|
||||
|
||||
type OfflinePusher interface {
|
||||
Push(userIDList []string, title, detailContent, operationID string, opts PushOpts) (resp string, err error)
|
||||
Push(ctx context.Context, userIDs []string, title, content, opts *Opts) error
|
||||
}
|
||||
|
||||
type PushOpts struct {
|
||||
Signal Signal
|
||||
type Opts struct {
|
||||
Signal *Signal
|
||||
IOSPushSound string
|
||||
IOSBadgeCount bool
|
||||
Data string
|
||||
Ex string
|
||||
}
|
||||
|
||||
type Signal struct {
|
||||
|
@ -1,4 +1,4 @@
|
||||
package logic
|
||||
package push
|
||||
|
||||
import (
|
||||
"Open_IM/pkg/common/config"
|
||||
@ -6,7 +6,6 @@ import (
|
||||
"Open_IM/pkg/common/db"
|
||||
"Open_IM/pkg/common/log"
|
||||
prome "Open_IM/pkg/common/prometheus"
|
||||
"Open_IM/pkg/getcdv3"
|
||||
pbPush "Open_IM/pkg/proto/push"
|
||||
"Open_IM/pkg/utils"
|
||||
"context"
|
@ -4,45 +4,33 @@
|
||||
** author("fg,Gordon@open-im.io").
|
||||
** time(2021/3/5 14:31).
|
||||
*/
|
||||
package logic
|
||||
package push
|
||||
|
||||
import (
|
||||
"Open_IM/internal/push"
|
||||
"Open_IM/pkg/common/config"
|
||||
"Open_IM/pkg/common/constant"
|
||||
"Open_IM/pkg/common/db"
|
||||
"Open_IM/pkg/common/log"
|
||||
"Open_IM/pkg/getcdv3"
|
||||
"Open_IM/pkg/common/prome"
|
||||
pbPush "Open_IM/pkg/proto/push"
|
||||
pbRelay "Open_IM/pkg/proto/relay"
|
||||
pbRtc "Open_IM/pkg/proto/rtc"
|
||||
"Open_IM/pkg/utils"
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
prome "Open_IM/pkg/common/prometheus"
|
||||
|
||||
"github.com/golang/protobuf/proto"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type OpenIMContent struct {
|
||||
SessionType int `json:"sessionType"`
|
||||
From string `json:"from"`
|
||||
To string `json:"to"`
|
||||
Seq uint32 `json:"seq"`
|
||||
}
|
||||
type AtContent struct {
|
||||
Text string `json:"text"`
|
||||
AtUserList []string `json:"atUserList"`
|
||||
IsAtSelf bool `json:"isAtSelf"`
|
||||
}
|
||||
|
||||
//var grpcCons []*grpc.ClientConn
|
||||
|
||||
func MsgToUser(pushMsg *pbPush.PushMsgReq) {
|
||||
var wsResult []*pbRelay.SingelMsgToUserResultList
|
||||
isOfflinePush := utils.GetSwitchFromOptions(pushMsg.MsgData.Options, constant.IsOfflinePush)
|
||||
log.Debug(pushMsg.OperationID, "Get msg from msg_transfer And push msg", pushMsg.String())
|
||||
|
||||
grpcCons := rpc.GetDefaultGatewayConn4Unique(config.Config.Etcd.EtcdSchema, strings.Join(config.Config.Etcd.EtcdAddr, ","), pushMsg.OperationID)
|
||||
|
||||
var UIDList = []string{pushMsg.PushToUserID}
|
||||
@ -277,13 +265,13 @@ func MsgToSuperGroupUser(pushMsg *pbPush.PushMsgReq) {
|
||||
}
|
||||
}
|
||||
|
||||
func GetOfflinePushOpts(pushMsg *pbPush.PushMsgReq) (opts push.PushOpts, err error) {
|
||||
if pushMsg.MsgData.ContentType < constant.SignalingNotificationEnd && pushMsg.MsgData.ContentType > constant.SignalingNotificationBegin {
|
||||
func GetOfflinePushOpts(pushMsg *pbPush.PushMsgReq) (opts *Opts, err error) {
|
||||
if pushMsg.MsgData.ContentType > constant.SignalingNotificationBegin && pushMsg.MsgData.ContentType < constant.SignalingNotificationEnd {
|
||||
req := &pbRtc.SignalReq{}
|
||||
if err := proto.Unmarshal(pushMsg.MsgData.Content, req); err != nil {
|
||||
return opts, utils.Wrap(err, "")
|
||||
return nil, utils.Wrap(err, "")
|
||||
}
|
||||
log.NewDebug(pushMsg.OperationID, utils.GetSelfFuncName(), "SignalReq: ", req.String())
|
||||
opts = &Opts{}
|
||||
switch req.Payload.(type) {
|
||||
case *pbRtc.SignalReq_Invite, *pbRtc.SignalReq_InviteInGroup:
|
||||
opts.Signal.ClientMsgID = pushMsg.MsgData.ClientMsgID
|
||||
@ -291,10 +279,10 @@ func GetOfflinePushOpts(pushMsg *pbPush.PushMsgReq) (opts push.PushOpts, err err
|
||||
}
|
||||
}
|
||||
if pushMsg.MsgData.OfflinePushInfo != nil {
|
||||
opts = &Opts{}
|
||||
opts.IOSBadgeCount = pushMsg.MsgData.OfflinePushInfo.IOSBadgeCount
|
||||
opts.IOSPushSound = pushMsg.MsgData.OfflinePushInfo.IOSPushSound
|
||||
opts.Data = pushMsg.MsgData.OfflinePushInfo.Ex
|
||||
opts.Ex = pushMsg.MsgData.OfflinePushInfo.Ex
|
||||
}
|
||||
|
||||
return opts, nil
|
||||
}
|
@ -1,62 +0,0 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"crypto/hmac"
|
||||
"crypto/sha256"
|
||||
"encoding/base64"
|
||||
b64 "encoding/base64"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Auther struct {
|
||||
AccessID string
|
||||
SecretKey string
|
||||
}
|
||||
|
||||
var UseSignAuthored = true
|
||||
|
||||
func (a *Auther) Auth(req *http.Request, useSignAuthored bool, auth Auther, reqBody string) {
|
||||
|
||||
if useSignAuthored {
|
||||
now := time.Now()
|
||||
timeStamp := now.Unix()
|
||||
req.Header.Add("AccessId", auth.AccessID)
|
||||
req.Header.Add("TimeStamp", strconv.Itoa(int(timeStamp)))
|
||||
sign := GenSign(uint64(timeStamp), auth.AccessID, auth.SecretKey, reqBody)
|
||||
req.Header.Add("Sign", sign)
|
||||
} else {
|
||||
author := makeAuthHeader(a.AccessID, a.SecretKey)
|
||||
//log.Printf("author string:%v", author)
|
||||
req.Header.Add("Authorization", author)
|
||||
}
|
||||
//req.Header.Add("Content-Type", "application/json")
|
||||
}
|
||||
|
||||
func makeAuthHeader(appID, secretKey string) string {
|
||||
base64Str := base64.StdEncoding.EncodeToString(
|
||||
[]byte(
|
||||
fmt.Sprintf("%s:%s", appID, secretKey),
|
||||
),
|
||||
)
|
||||
return fmt.Sprintf("Basic %s", base64Str)
|
||||
}
|
||||
|
||||
func GenSign(timeStamp uint64, accessId string, secretKey, requestBody string) string {
|
||||
signBody := strconv.Itoa(int(timeStamp)) + accessId + requestBody
|
||||
// Create a new HMAC by defining the hash type and the key (as byte array)
|
||||
h := hmac.New(sha256.New, []byte(secretKey))
|
||||
// Write Map to it
|
||||
h.Write([]byte(signBody))
|
||||
|
||||
// Get result and encode as hexadecimal string
|
||||
sha := hex.EncodeToString(h.Sum(nil))
|
||||
//fmt.Println()
|
||||
//fmt.Println("timeStamp: " + strconv.Itoa(int(timeStamp)) + " accessID:" + accessId + " body:" + requestBody)
|
||||
sEnc := b64.StdEncoding.EncodeToString([]byte(sha))
|
||||
//fmt.Println("final Result " + sEnc)
|
||||
return sEnc
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package logic
|
||||
package push
|
||||
|
||||
import (
|
||||
tpns "Open_IM/internal/push/sdk/tpns-server-sdk-go/go"
|
@ -8,10 +8,8 @@ import (
|
||||
"Open_IM/pkg/common/db/controller"
|
||||
"Open_IM/pkg/common/db/relation"
|
||||
tableRelation "Open_IM/pkg/common/db/table/relation"
|
||||
"Open_IM/pkg/common/db/unrelation"
|
||||
"Open_IM/pkg/common/log"
|
||||
promePkg "Open_IM/pkg/common/prometheus"
|
||||
"Open_IM/pkg/getcdv3"
|
||||
"Open_IM/pkg/common/prome"
|
||||
pbConversation "Open_IM/pkg/proto/conversation"
|
||||
pbUser "Open_IM/pkg/proto/user"
|
||||
"Open_IM/pkg/utils"
|
||||
|
@ -5,13 +5,13 @@ import common "Open_IM/pkg/proto/sdkws"
|
||||
type CallbackBeforePushReq struct {
|
||||
UserStatusBatchCallbackReq
|
||||
*common.OfflinePushInfo
|
||||
ClientMsgID string `json:"clientMsgID"`
|
||||
SendID string `json:"sendID"`
|
||||
GroupID string `json:"groupID"`
|
||||
ContentType int32 `json:"contentType"`
|
||||
SessionType int32 `json:"sessionType"`
|
||||
AtUserIDList []string `json:"atUserIDList"`
|
||||
Content string `json:"content"`
|
||||
ClientMsgID string `json:"clientMsgID"`
|
||||
SendID string `json:"sendID"`
|
||||
GroupID string `json:"groupID"`
|
||||
ContentType int32 `json:"contentType"`
|
||||
SessionType int32 `json:"sessionType"`
|
||||
AtUserIDs []string `json:"atUserIDList"`
|
||||
Content string `json:"content"`
|
||||
}
|
||||
|
||||
type CallbackBeforePushResp struct {
|
||||
@ -21,7 +21,6 @@ type CallbackBeforePushResp struct {
|
||||
}
|
||||
|
||||
type CallbackBeforeSuperGroupOnlinePushReq struct {
|
||||
//*common.OfflinePushInfo
|
||||
UserStatusBaseCallback
|
||||
ClientMsgID string `json:"clientMsgID"`
|
||||
SendID string `json:"sendID"`
|
||||
@ -30,7 +29,7 @@ type CallbackBeforeSuperGroupOnlinePushReq struct {
|
||||
SessionType int32 `json:"sessionType"`
|
||||
AtUserIDList []string `json:"atUserIDList"`
|
||||
Content string `json:"content"`
|
||||
Seq uint32 `json:"seq"`
|
||||
Seq int64 `json:"seq"`
|
||||
}
|
||||
|
||||
type CallbackBeforeSuperGroupOnlinePushResp struct {
|
||||
|
@ -7,7 +7,7 @@
|
||||
package http
|
||||
|
||||
import (
|
||||
cbapi "Open_IM/pkg/callbackstruct"
|
||||
"Open_IM/pkg/callbackstruct"
|
||||
"Open_IM/pkg/common/config"
|
||||
"Open_IM/pkg/common/constant"
|
||||
"bytes"
|
||||
@ -33,19 +33,17 @@ func Get(url string) (response []byte, err error) {
|
||||
}
|
||||
|
||||
// application/json; charset=utf-8
|
||||
func Post(url string, data interface{}, timeOutSecond int) (content []byte, err error) {
|
||||
func Post(url string, header map[string]string, data interface{}, timeOutSecond int) (content []byte, err error) {
|
||||
jsonStr, err := json.Marshal(data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonStr))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.Close = true
|
||||
req.Header.Add("content-type", "application/json; charset=utf-8")
|
||||
|
||||
client := &http.Client{Timeout: time.Duration(timeOutSecond) * time.Second}
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
@ -59,11 +57,20 @@ func Post(url string, data interface{}, timeOutSecond int) (content []byte, err
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func callBackPostReturn(url, callbackCommand string, input interface{}, output cbapi.CallbackResp, callbackConfig config.CallBackConfig) error {
|
||||
func PostReturn(url string, header map[string]string, input, output interface{}, timeOutSecond int) error {
|
||||
b, err := Post(url, header, input, timeOutSecond)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = json.Unmarshal(b, output)
|
||||
return err
|
||||
}
|
||||
|
||||
func callBackPostReturn(url, command string, input interface{}, output callbackstruct.CallbackResp, callbackConfig config.CallBackConfig) error {
|
||||
v := urlLib.Values{}
|
||||
v.Set("callbackCommand", callbackCommand)
|
||||
v.Set("callbackCommand", command)
|
||||
url = url + "?" + v.Encode()
|
||||
b, err := Post(url, input, callbackConfig.CallbackTimeOut)
|
||||
b, err := Post(url, nil, input, callbackConfig.CallbackTimeOut)
|
||||
if err != nil {
|
||||
if callbackConfig.CallbackFailedContinue != nil && *callbackConfig.CallbackFailedContinue {
|
||||
return constant.ErrCallbackContinue
|
||||
@ -79,6 +86,6 @@ func callBackPostReturn(url, callbackCommand string, input interface{}, output c
|
||||
return output.Parse()
|
||||
}
|
||||
|
||||
func CallBackPostReturn(url string, req cbapi.CallbackReq, resp cbapi.CallbackResp, callbackConfig config.CallBackConfig) error {
|
||||
func CallBackPostReturn(url string, req callbackstruct.CallbackReq, resp callbackstruct.CallbackResp, callbackConfig config.CallBackConfig) error {
|
||||
return callBackPostReturn(url, req.GetCallbackCommand(), req, resp, callbackConfig)
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ type SvcDiscoveryRegistry interface {
|
||||
UnRegister() error
|
||||
GetConns(serviceName string, opts ...grpc.DialOption) ([]*grpc.ClientConn, error)
|
||||
GetConn(serviceName string, opts ...grpc.DialOption) (*grpc.ClientConn, error)
|
||||
|
||||
//RegisterConf(conf []byte) error
|
||||
//LoadConf() ([]byte, error)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user