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
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
_ "Open_IM/cmd/open_im_api/docs"
|
|
||||||
apiAuth "Open_IM/internal/api/auth"
|
apiAuth "Open_IM/internal/api/auth"
|
||||||
"Open_IM/internal/api/conversation"
|
"Open_IM/internal/api/conversation"
|
||||||
"Open_IM/internal/api/friend"
|
"Open_IM/internal/api/friend"
|
||||||
@ -14,7 +13,6 @@ import (
|
|||||||
"Open_IM/pkg/common/log"
|
"Open_IM/pkg/common/log"
|
||||||
"Open_IM/pkg/common/middleware"
|
"Open_IM/pkg/common/middleware"
|
||||||
"Open_IM/pkg/common/tokenverify"
|
"Open_IM/pkg/common/tokenverify"
|
||||||
"Open_IM/pkg/utils"
|
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
@ -25,10 +23,9 @@ import (
|
|||||||
swaggerFiles "github.com/swaggo/files"
|
swaggerFiles "github.com/swaggo/files"
|
||||||
ginSwagger "github.com/swaggo/gin-swagger"
|
ginSwagger "github.com/swaggo/gin-swagger"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
//"syscall"
|
|
||||||
"Open_IM/pkg/common/constant"
|
"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
|
// @title open-IM-Server API
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"Open_IM/internal/push/logic"
|
"Open_IM/internal/push"
|
||||||
"Open_IM/pkg/common/config"
|
"Open_IM/pkg/common/config"
|
||||||
"Open_IM/pkg/common/constant"
|
"Open_IM/pkg/common/constant"
|
||||||
"Open_IM/pkg/common/log"
|
"Open_IM/pkg/common/log"
|
||||||
@ -19,7 +19,7 @@ func main() {
|
|||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
log.NewPrivateLog(constant.LogFileName)
|
log.NewPrivateLog(constant.LogFileName)
|
||||||
fmt.Println("start push rpc server, port: ", *rpcPort, ", OpenIM version: ", constant.CurrentVersion, "\n")
|
fmt.Println("start push rpc server, port: ", *rpcPort, ", OpenIM version: ", constant.CurrentVersion, "\n")
|
||||||
logic.Init(*rpcPort)
|
push.Init(*rpcPort)
|
||||||
logic.Run(*prometheusPort)
|
push.Run(*prometheusPort)
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
}
|
}
|
||||||
|
@ -213,12 +213,6 @@ push:
|
|||||||
fcm: #firebase cloud message 消息推送
|
fcm: #firebase cloud message 消息推送
|
||||||
serviceAccount: "openim-5c6c0-firebase-adminsdk-ppwol-8765884a78.json" #帐号文件,此处需要改修配置,并且这个文件放在 config目录下
|
serviceAccount: "openim-5c6c0-firebase-adminsdk-ppwol-8765884a78.json" #帐号文件,此处需要改修配置,并且这个文件放在 config目录下
|
||||||
enable: false
|
enable: false
|
||||||
mob: #袤博推送
|
|
||||||
appKey: #帐号文件,此处需要改修配置,并且这个文件放在 config目录下
|
|
||||||
pushUrl:
|
|
||||||
scheme:
|
|
||||||
appSecret:
|
|
||||||
enable: false
|
|
||||||
|
|
||||||
manager:
|
manager:
|
||||||
#app管理员userID和对应的secret 建议修改。 用于管理后台登录,也可以用户管理后台对应的api
|
#app管理员userID和对应的secret 建议修改。 用于管理后台登录,也可以用户管理后台对应的api
|
||||||
|
@ -34,7 +34,6 @@ services:
|
|||||||
- MONGO_INITDB_DATABASE=openIM
|
- MONGO_INITDB_DATABASE=openIM
|
||||||
- MONGO_USERNAME=${USER}
|
- MONGO_USERNAME=${USER}
|
||||||
- MONGO_PASSWORD=${PASSWORD}
|
- MONGO_PASSWORD=${PASSWORD}
|
||||||
#
|
|
||||||
restart: always
|
restart: always
|
||||||
|
|
||||||
redis:
|
redis:
|
||||||
@ -84,20 +83,6 @@ services:
|
|||||||
depends_on:
|
depends_on:
|
||||||
- zookeeper
|
- 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:
|
minio:
|
||||||
image: minio/minio
|
image: minio/minio
|
||||||
ports:
|
ports:
|
||||||
@ -129,7 +114,6 @@ services:
|
|||||||
- mysql
|
- mysql
|
||||||
- mongodb
|
- mongodb
|
||||||
- redis
|
- redis
|
||||||
- etcd
|
|
||||||
- minio
|
- minio
|
||||||
network_mode: "host"
|
network_mode: "host"
|
||||||
logging:
|
logging:
|
||||||
@ -149,7 +133,6 @@ services:
|
|||||||
- mysql
|
- mysql
|
||||||
- mongodb
|
- mongodb
|
||||||
- redis
|
- redis
|
||||||
- etcd
|
|
||||||
- minio
|
- minio
|
||||||
- open_im_server
|
- open_im_server
|
||||||
network_mode: "host"
|
network_mode: "host"
|
||||||
|
4
go.mod
4
go.mod
@ -1,6 +1,6 @@
|
|||||||
module Open_IM
|
module Open_IM
|
||||||
|
|
||||||
go 1.18
|
go 1.16
|
||||||
|
|
||||||
require (
|
require (
|
||||||
firebase.google.com/go v3.13.0+incompatible
|
firebase.google.com/go v3.13.0+incompatible
|
||||||
@ -49,14 +49,12 @@ require (
|
|||||||
google.golang.org/api v0.103.0
|
google.golang.org/api v0.103.0
|
||||||
google.golang.org/grpc v1.52.3
|
google.golang.org/grpc v1.52.3
|
||||||
google.golang.org/protobuf v1.28.1
|
google.golang.org/protobuf v1.28.1
|
||||||
gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22
|
|
||||||
gopkg.in/yaml.v3 v3.0.1
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
gorm.io/driver/mysql v1.3.5
|
gorm.io/driver/mysql v1.3.5
|
||||||
gorm.io/gorm v1.23.8
|
gorm.io/gorm v1.23.8
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/envoyproxy/protoc-gen-validate v0.1.0
|
|
||||||
github.com/go-openapi/spec v0.20.6 // indirect
|
github.com/go-openapi/spec v0.20.6 // indirect
|
||||||
github.com/go-openapi/swag v0.21.1 // indirect
|
github.com/go-openapi/swag v0.21.1 // indirect
|
||||||
github.com/go-playground/locales v0.14.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.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.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/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/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 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo=
|
||||||
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
|
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
|
||||||
|
@ -11,7 +11,6 @@ import (
|
|||||||
"math"
|
"math"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
type ClearMsgTool struct {
|
type ClearMsgTool struct {
|
||||||
msgInterface controller.MsgInterface
|
msgInterface controller.MsgInterface
|
||||||
userInterface controller.UserInterface
|
userInterface controller.UserInterface
|
||||||
@ -49,12 +48,13 @@ func (c *ClearMsgTool) ClearUsersMsg(ctx context.Context, userIDList []string) {
|
|||||||
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)
|
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 {
|
if err != nil {
|
||||||
log.NewError(tracelog.GetOperationID(ctx), utils.GetSelfFuncName(), err.Error(), "GetUserMinMaxSeqInMongoAndCache failed", userID)
|
log.NewError(tracelog.GetOperationID(ctx), utils.GetSelfFuncName(), err.Error(), "GetUserMinMaxSeqInMongoAndCache failed", userID)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if
|
c.FixUserSeq(ctx, userID, minSeqCache, maxSeqCache)
|
||||||
|
c.CheckMaxSeqWithMongo(ctx, userID, maxSeqCache, maxSeqMongo, constant.WriteDiffusion)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,38 +66,40 @@ func (c *ClearMsgTool) ClearSuperGroupMsg(ctx context.Context, workingGroupIDLis
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if err := c.msgInterface.DeleteUserSuperGroupMsgsAndSetMinSeq(ctx, groupID, userIDs, int64(config.Config.Mongo.DBRetainChatRecords*24*60*60)); err != nil {
|
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)
|
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 {
|
func (c *ClearMsgTool) FixUserSeq(ctx context.Context, userID string, minSeqCache, maxSeqCache int64) {
|
||||||
var seqRedis uint64
|
if minSeqCache > maxSeqCache {
|
||||||
var err error
|
if err := c.msgInterface.SetUserMinSeq(ctx, userID, maxSeqCache); err != nil {
|
||||||
if diffusionType == constant.WriteDiffusion {
|
log.NewError(tracelog.GetOperationID(ctx), "SetUserMinSeq failed", userID, minSeqCache, maxSeqCache)
|
||||||
seqRedis, err = db.DB.GetUserMaxSeq(sourceID)
|
|
||||||
} else {
|
} else {
|
||||||
seqRedis, err = db.DB.GetGroupMaxSeq(sourceID)
|
log.NewWarn(tracelog.GetOperationID(ctx), "SetUserMinSeq success", userID, minSeqCache, maxSeqCache)
|
||||||
}
|
}
|
||||||
if err != nil {
|
|
||||||
if err == goRedis.Nil {
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
return utils.Wrap(err, "GetUserMaxSeq failed")
|
|
||||||
}
|
}
|
||||||
msg, err := db.DB.GetNewestMsg(sourceID)
|
|
||||||
if err != nil {
|
func (c *ClearMsgTool) FixGroupUserSeq(ctx context.Context, userID string, groupID string, minSeqCache, maxSeqCache int64) {
|
||||||
return utils.Wrap(err, "GetNewestMsg failed")
|
if minSeqCache > maxSeqCache {
|
||||||
}
|
if err := c.msgInterface.SetGroupUserMinSeq(ctx, groupID, userID, maxSeqCache); err != nil {
|
||||||
if msg == nil {
|
log.NewError(tracelog.GetOperationID(ctx), "SetGroupUserMinSeq failed", userID, minSeqCache, maxSeqCache)
|
||||||
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 {
|
} else {
|
||||||
log.NewInfo(operationID, utils.GetSelfFuncName(), "seqMongo, seqRedis", msg.Seq, seqRedis, sourceID, "seq and msg OK", "status:", msg.Status, msg.SendTime)
|
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)
|
||||||
}
|
}
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
if len(messages) > 0 {
|
||||||
pid, offset, err := och.producerToMongo.SendMessage(&pbMsg.MsgDataToMongoByMQ{LastSeq: lastSeq, AggregationID: aggregationID, MessageList: messages, TriggerID: triggerID}, aggregationID, triggerID)
|
pid, offset, err := och.producerToMongo.SendMessage(&pbMsg.MsgDataToMongoByMQ{LastSeq: lastSeq, AggregationID: aggregationID, MessageList: messages, TriggerID: triggerID}, aggregationID, triggerID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package logic
|
package push
|
||||||
|
|
||||||
import (
|
import (
|
||||||
cbapi "Open_IM/pkg/callbackstruct"
|
"Open_IM/pkg/callbackstruct"
|
||||||
"Open_IM/pkg/common/config"
|
"Open_IM/pkg/common/config"
|
||||||
"Open_IM/pkg/common/constant"
|
"Open_IM/pkg/common/constant"
|
||||||
"Open_IM/pkg/common/http"
|
"Open_IM/pkg/common/http"
|
||||||
@ -15,13 +15,13 @@ func url() string {
|
|||||||
return config.Config.Callback.CallbackUrl
|
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 {
|
if !config.Config.Callback.CallbackOfflinePush.Enable {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
req := &cbapi.CallbackBeforePushReq{
|
req := &callbackstruct.CallbackBeforePushReq{
|
||||||
UserStatusBatchCallbackReq: cbapi.UserStatusBatchCallbackReq{
|
UserStatusBatchCallbackReq: callbackstruct.UserStatusBatchCallbackReq{
|
||||||
UserStatusBaseCallback: cbapi.UserStatusBaseCallback{
|
UserStatusBaseCallback: callbackstruct.UserStatusBaseCallback{
|
||||||
CallbackCommand: constant.CallbackOfflinePushCommand,
|
CallbackCommand: constant.CallbackOfflinePushCommand,
|
||||||
OperationID: tracelog.GetOperationID(ctx),
|
OperationID: tracelog.GetOperationID(ctx),
|
||||||
PlatformID: int(msg.SenderPlatformID),
|
PlatformID: int(msg.SenderPlatformID),
|
||||||
@ -35,10 +35,10 @@ func CallbackOfflinePush(ctx context.Context, userIDList []string, msg *common.M
|
|||||||
GroupID: msg.GroupID,
|
GroupID: msg.GroupID,
|
||||||
ContentType: msg.ContentType,
|
ContentType: msg.ContentType,
|
||||||
SessionType: msg.SessionType,
|
SessionType: msg.SessionType,
|
||||||
AtUserIDList: msg.AtUserIDList,
|
AtUserIDs: msg.AtUserIDList,
|
||||||
Content: utils.GetContent(msg),
|
Content: utils.GetContent(msg),
|
||||||
}
|
}
|
||||||
resp := &cbapi.CallbackBeforePushResp{}
|
resp := &callbackstruct.CallbackBeforePushResp{}
|
||||||
err := http.CallBackPostReturn(url(), req, resp, config.Config.Callback.CallbackOfflinePush)
|
err := http.CallBackPostReturn(url(), req, resp, config.Config.Callback.CallbackOfflinePush)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -52,13 +52,13 @@ func CallbackOfflinePush(ctx context.Context, userIDList []string, msg *common.M
|
|||||||
return nil
|
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...) {
|
if !config.Config.Callback.CallbackOnlinePush.Enable || utils.Contain(msg.SendID, userIDList...) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
req := cbapi.CallbackBeforePushReq{
|
req := callbackstruct.CallbackBeforePushReq{
|
||||||
UserStatusBatchCallbackReq: cbapi.UserStatusBatchCallbackReq{
|
UserStatusBatchCallbackReq: callbackstruct.UserStatusBatchCallbackReq{
|
||||||
UserStatusBaseCallback: cbapi.UserStatusBaseCallback{
|
UserStatusBaseCallback: callbackstruct.UserStatusBaseCallback{
|
||||||
CallbackCommand: constant.CallbackOnlinePushCommand,
|
CallbackCommand: constant.CallbackOnlinePushCommand,
|
||||||
OperationID: operationID,
|
OperationID: operationID,
|
||||||
PlatformID: int(msg.SenderPlatformID),
|
PlatformID: int(msg.SenderPlatformID),
|
||||||
@ -71,19 +71,19 @@ func CallbackOnlinePush(operationID string, userIDList []string, msg *common.Msg
|
|||||||
GroupID: msg.GroupID,
|
GroupID: msg.GroupID,
|
||||||
ContentType: msg.ContentType,
|
ContentType: msg.ContentType,
|
||||||
SessionType: msg.SessionType,
|
SessionType: msg.SessionType,
|
||||||
AtUserIDList: msg.AtUserIDList,
|
AtUserIDs: msg.AtUserIDList,
|
||||||
Content: utils.GetContent(msg),
|
Content: utils.GetContent(msg),
|
||||||
}
|
}
|
||||||
resp := &cbapi.CallbackBeforePushResp{}
|
resp := &callbackstruct.CallbackBeforePushResp{}
|
||||||
return http.CallBackPostReturn(url(), req, resp, config.Config.Callback.CallbackOnlinePush)
|
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 {
|
if !config.Config.Callback.CallbackBeforeSuperGroupOnlinePush.Enable {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
req := cbapi.CallbackBeforeSuperGroupOnlinePushReq{
|
req := callbackstruct.CallbackBeforeSuperGroupOnlinePushReq{
|
||||||
UserStatusBaseCallback: cbapi.UserStatusBaseCallback{
|
UserStatusBaseCallback: callbackstruct.UserStatusBaseCallback{
|
||||||
CallbackCommand: constant.CallbackSuperGroupOnlinePushCommand,
|
CallbackCommand: constant.CallbackSuperGroupOnlinePushCommand,
|
||||||
OperationID: tracelog.GetOperationID(ctx),
|
OperationID: tracelog.GetOperationID(ctx),
|
||||||
PlatformID: int(msg.SenderPlatformID),
|
PlatformID: int(msg.SenderPlatformID),
|
||||||
@ -98,7 +98,7 @@ func CallbackBeforeSuperGroupOnlinePush(ctx context.Context, groupID string, msg
|
|||||||
Content: utils.GetContent(msg),
|
Content: utils.GetContent(msg),
|
||||||
Seq: msg.Seq,
|
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 {
|
if err := http.CallBackPostReturn(config.Config.Callback.CallbackUrl, req, resp, config.Config.Callback.CallbackBeforeSuperGroupOnlinePush); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
@ -3,57 +3,52 @@ package fcm
|
|||||||
import (
|
import (
|
||||||
"Open_IM/internal/push"
|
"Open_IM/internal/push"
|
||||||
"Open_IM/pkg/common/config"
|
"Open_IM/pkg/common/config"
|
||||||
"Open_IM/pkg/common/db"
|
"Open_IM/pkg/common/constant"
|
||||||
"Open_IM/pkg/common/log"
|
"Open_IM/pkg/common/db/cache"
|
||||||
"context"
|
"context"
|
||||||
go_redis "github.com/go-redis/redis/v8"
|
|
||||||
"path/filepath"
|
|
||||||
"strconv"
|
|
||||||
|
|
||||||
firebase "firebase.google.com/go"
|
firebase "firebase.google.com/go"
|
||||||
"firebase.google.com/go/messaging"
|
"firebase.google.com/go/messaging"
|
||||||
|
"github.com/go-redis/redis/v8"
|
||||||
"google.golang.org/api/option"
|
"google.golang.org/api/option"
|
||||||
|
"path/filepath"
|
||||||
)
|
)
|
||||||
|
|
||||||
const SinglePushCountLimit = 400
|
const SinglePushCountLimit = 400
|
||||||
|
|
||||||
|
var Terminal = []int{constant.IOSPlatformID, constant.AndroidPlatformID, constant.WebPlatformID}
|
||||||
|
|
||||||
type Fcm struct {
|
type Fcm struct {
|
||||||
FcmMsgCli *messaging.Client
|
fcmMsgCli *messaging.Client
|
||||||
|
cache cache.Cache
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewFcm() *Fcm {
|
func newFcmClient(cache cache.Cache) *Fcm {
|
||||||
return newFcmClient()
|
|
||||||
}
|
|
||||||
func newFcmClient() *Fcm {
|
|
||||||
opt := option.WithCredentialsFile(filepath.Join(config.Root, "config", config.Config.Push.Fcm.ServiceAccount))
|
opt := option.WithCredentialsFile(filepath.Join(config.Root, "config", config.Config.Push.Fcm.ServiceAccount))
|
||||||
fcmApp, err := firebase.NewApp(context.Background(), nil, opt)
|
fcmApp, err := firebase.NewApp(context.Background(), nil, opt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Debug("", "error initializing app: ", err.Error())
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
//授权
|
// auth
|
||||||
// fcmClient, err := fcmApp.Auth(context.Background())
|
// fcmClient, err := fcmApp.Auth(context.Background())
|
||||||
// if err != nil {
|
// if err != nil {
|
||||||
// log.Println("error getting Auth client: %v\n", err)
|
|
||||||
// return
|
// return
|
||||||
// }
|
// }
|
||||||
// log.Printf("%#v\r\n", fcmClient)
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
fcmMsgClient, err := fcmApp.Messaging(ctx)
|
fcmMsgClient, err := fcmApp.Messaging(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err.Error())
|
panic(err.Error())
|
||||||
return nil
|
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
|
// accounts->registrationToken
|
||||||
allTokens := make(map[string][]string, 0)
|
allTokens := make(map[string][]string, 0)
|
||||||
for _, account := range accounts {
|
for _, account := range userIDs {
|
||||||
var personTokens []string
|
var personTokens []string
|
||||||
for _, v := range push.PushTerminal {
|
for _, v := range Terminal {
|
||||||
Token, err := db.DB.GetFcmToken(account, v)
|
Token, err := f.cache.GetFcmToken(ctx, account, v)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
personTokens = append(personTokens, Token)
|
personTokens = append(personTokens, Token)
|
||||||
}
|
}
|
||||||
@ -63,18 +58,16 @@ func (f *Fcm) Push(accounts []string, title, detailContent, operationID string,
|
|||||||
Success := 0
|
Success := 0
|
||||||
Fail := 0
|
Fail := 0
|
||||||
notification := &messaging.Notification{}
|
notification := &messaging.Notification{}
|
||||||
notification.Body = detailContent
|
notification.Body = content
|
||||||
notification.Title = title
|
notification.Title = title
|
||||||
var messages []*messaging.Message
|
var messages []*messaging.Message
|
||||||
ctx := context.Background()
|
for userID, personTokens := range allTokens {
|
||||||
for uid, personTokens := range allTokens {
|
|
||||||
apns := &messaging.APNSConfig{Payload: &messaging.APNSPayload{Aps: &messaging.Aps{Sound: opts.IOSPushSound}}}
|
apns := &messaging.APNSConfig{Payload: &messaging.APNSPayload{Aps: &messaging.Aps{Sound: opts.IOSPushSound}}}
|
||||||
messageCount := len(messages)
|
messageCount := len(messages)
|
||||||
if messageCount >= SinglePushCountLimit {
|
if messageCount >= SinglePushCountLimit {
|
||||||
response, err := f.FcmMsgCli.SendAll(ctx, messages)
|
response, err := f.fcmMsgCli.SendAll(ctx, messages)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Fail = Fail + messageCount
|
Fail = Fail + messageCount
|
||||||
log.Info(operationID, "some token push err", err.Error(), messageCount)
|
|
||||||
} else {
|
} else {
|
||||||
Success = Success + response.SuccessCount
|
Success = Success + response.SuccessCount
|
||||||
Fail = Fail + response.FailureCount
|
Fail = Fail + response.FailureCount
|
||||||
@ -82,30 +75,30 @@ func (f *Fcm) Push(accounts []string, title, detailContent, operationID string,
|
|||||||
messages = messages[0:0]
|
messages = messages[0:0]
|
||||||
}
|
}
|
||||||
if opts.IOSBadgeCount {
|
if opts.IOSBadgeCount {
|
||||||
unreadCountSum, err := db.DB.IncrUserBadgeUnreadCountSum(uid)
|
unreadCountSum, err := f.cache.IncrUserBadgeUnreadCountSum(ctx, userID)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
apns.Payload.Aps.Badge = &unreadCountSum
|
apns.Payload.Aps.Badge = &unreadCountSum
|
||||||
} else {
|
} else {
|
||||||
log.Error(operationID, "IncrUserBadgeUnreadCountSum redis err", err.Error(), uid)
|
//log.Error(operationID, "IncrUserBadgeUnreadCountSum redis err", err.Error(), uid)
|
||||||
Fail++
|
Fail++
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
unreadCountSum, err := db.DB.GetUserBadgeUnreadCountSum(uid)
|
unreadCountSum, err := f.cache.GetUserBadgeUnreadCountSum(ctx, userID)
|
||||||
if err == nil && unreadCountSum != 0 {
|
if err == nil && unreadCountSum != 0 {
|
||||||
apns.Payload.Aps.Badge = &unreadCountSum
|
apns.Payload.Aps.Badge = &unreadCountSum
|
||||||
} else if err == go_redis.Nil || unreadCountSum == 0 {
|
} else if err == redis.Nil || unreadCountSum == 0 {
|
||||||
zero := 1
|
zero := 1
|
||||||
apns.Payload.Aps.Badge = &zero
|
apns.Payload.Aps.Badge = &zero
|
||||||
} else {
|
} else {
|
||||||
log.Error(operationID, "GetUserBadgeUnreadCountSum redis err", err.Error(), uid)
|
//log.Error(operationID, "GetUserBadgeUnreadCountSum redis err", err.Error(), uid)
|
||||||
Fail++
|
Fail++
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, token := range personTokens {
|
for _, token := range personTokens {
|
||||||
temp := &messaging.Message{
|
temp := &messaging.Message{
|
||||||
Data: map[string]string{"ex": opts.Data},
|
Data: map[string]string{"ex": opts.Ex},
|
||||||
Token: token,
|
Token: token,
|
||||||
Notification: notification,
|
Notification: notification,
|
||||||
APNS: apns,
|
APNS: apns,
|
||||||
@ -116,14 +109,14 @@ func (f *Fcm) Push(accounts []string, title, detailContent, operationID string,
|
|||||||
}
|
}
|
||||||
messageCount := len(messages)
|
messageCount := len(messages)
|
||||||
if messageCount > 0 {
|
if messageCount > 0 {
|
||||||
response, err := f.FcmMsgCli.SendAll(ctx, messages)
|
response, err := f.fcmMsgCli.SendAll(ctx, messages)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Fail = Fail + messageCount
|
Fail = Fail + messageCount
|
||||||
log.Info(operationID, "some token push err", err.Error(), messageCount)
|
//log.Info(operationID, "some token push err", err.Error(), messageCount)
|
||||||
} else {
|
} else {
|
||||||
Success = Success + response.SuccessCount
|
Success = Success + response.SuccessCount
|
||||||
Fail = Fail + response.FailureCount
|
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 (
|
import (
|
||||||
"Open_IM/internal/push"
|
"Open_IM/internal/push"
|
||||||
"Open_IM/pkg/common/config"
|
"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/common/log"
|
||||||
"Open_IM/pkg/utils"
|
"Open_IM/pkg/utils"
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"context"
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"errors"
|
|
||||||
|
|
||||||
//"crypto/sha512"
|
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
@ -20,166 +20,61 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
GetuiClient *Getui
|
|
||||||
|
|
||||||
TokenExpireError = errors.New("token expire")
|
TokenExpireError = errors.New("token expire")
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
PushURL = "/push/single/alias"
|
pushURL = "/push/single/alias"
|
||||||
AuthURL = "/auth"
|
authURL = "/auth"
|
||||||
TaskURL = "/push/list/message"
|
taskURL = "/push/list/message"
|
||||||
BatchPushURL = "/push/list/alias"
|
batchPushURL = "/push/list/alias"
|
||||||
|
|
||||||
|
tokenExpire = 10001
|
||||||
|
ttl = 0
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
type Client struct {
|
||||||
GetuiClient = newGetuiClient()
|
cache cache.Cache
|
||||||
}
|
}
|
||||||
|
|
||||||
type Getui struct{}
|
func newClient(cache cache.Cache) *Client {
|
||||||
|
return &Client{cache: cache}
|
||||||
type GetuiCommonResp struct {
|
|
||||||
Code int `json:"code"`
|
|
||||||
Msg string `json:"msg"`
|
|
||||||
Data interface{} `json:"data"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type AuthReq struct {
|
func (g *Client) Push(ctx context.Context, userIDs []string, title, content, operationID string, opts *push.Opts) error {
|
||||||
Sign string `json:"sign"`
|
token, err := g.cache.GetGetuiToken(ctx)
|
||||||
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)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.NewError(operationID, utils.GetSelfFuncName(), "GetGetuiToken failed", err.Error())
|
log.NewError(operationID, utils.GetSelfFuncName(), "GetGetuiToken failed", err.Error())
|
||||||
}
|
}
|
||||||
if token == "" || err != nil {
|
if token == "" || err != nil {
|
||||||
token, err = g.getTokenAndSave2Redis(operationID)
|
token, err = g.getTokenAndSave2Redis(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.NewError(operationID, utils.GetSelfFuncName(), "getTokenAndSave2Redis failed", err.Error())
|
log.NewError(operationID, utils.GetSelfFuncName(), "getTokenAndSave2Redis failed", err.Error())
|
||||||
return "", utils.Wrap(err, "")
|
return utils.Wrap(err, "")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pushReq := newPushReq(title, content)
|
||||||
pushReq := PushReq{PushMessage: &PushMessage{Notification: &Notification{
|
pushReq.setPushChannel(title, content)
|
||||||
Title: title,
|
pushResp := struct{}{}
|
||||||
Body: detailContent,
|
if len(userIDs) > 1 {
|
||||||
ClickType: "startapp",
|
taskID, err := g.GetTaskID(ctx, token, pushReq)
|
||||||
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)
|
|
||||||
if err != nil {
|
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
|
var IsAsync = true
|
||||||
pushReq.IsAsync = &IsAsync
|
pushReq.IsAsync = &IsAsync
|
||||||
pushReq.Taskid = &taskID
|
pushReq.TaskID = &taskID
|
||||||
err = g.request(BatchPushURL, pushReq, token, &pushResp, operationID)
|
err = g.request(ctx, batchPushURL, pushReq, token, &pushResp)
|
||||||
} else {
|
} else {
|
||||||
reqID := utils.OperationIDGenerator()
|
reqID := utils.OperationIDGenerator()
|
||||||
pushReq.RequestID = &reqID
|
pushReq.RequestID = &reqID
|
||||||
pushReq.Audience = &Audience{Alias: []string{userIDList[0]}}
|
pushReq.Audience = &Audience{Alias: []string{userIDs[0]}}
|
||||||
err = g.request(PushURL, pushReq, token, &pushResp, operationID)
|
err = g.request(ctx, pushURL, pushReq, token, &pushResp)
|
||||||
}
|
}
|
||||||
switch err {
|
switch err {
|
||||||
case TokenExpireError:
|
case TokenExpireError:
|
||||||
token, err = g.getTokenAndSave2Redis(operationID)
|
token, err = g.getTokenAndSave2Redis(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.NewError(operationID, utils.GetSelfFuncName(), "getTokenAndSave2Redis failed, ", err.Error())
|
log.NewError(operationID, utils.GetSelfFuncName(), "getTokenAndSave2Redis failed, ", err.Error())
|
||||||
} else {
|
} else {
|
||||||
@ -187,52 +82,47 @@ func (g *Getui) Push(userIDList []string, title, detailContent, operationID stri
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", utils.Wrap(err, "push failed")
|
return utils.Wrap(err, "push failed")
|
||||||
}
|
}
|
||||||
respBytes, err := json.Marshal(pushResp)
|
return utils.Wrap(err, "")
|
||||||
return string(respBytes), utils.Wrap(err, "")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Getui) Auth(operationID string, timeStamp int64) (token string, expireTime int64, err error) {
|
func (g *Client) Auth(ctx context.Context, timeStamp int64) (token string, expireTime int64, err error) {
|
||||||
log.NewInfo(operationID, utils.GetSelfFuncName(), config.Config.Push.Getui.AppKey, timeStamp, config.Config.Push.Getui.MasterSecret)
|
|
||||||
h := sha256.New()
|
h := sha256.New()
|
||||||
h.Write([]byte(config.Config.Push.Getui.AppKey + strconv.Itoa(int(timeStamp)) + config.Config.Push.Getui.MasterSecret))
|
h.Write([]byte(config.Config.Push.Getui.AppKey + strconv.Itoa(int(timeStamp)) + config.Config.Push.Getui.MasterSecret))
|
||||||
sum := h.Sum(nil)
|
sign := hex.EncodeToString(h.Sum(nil))
|
||||||
sign := hex.EncodeToString(sum)
|
|
||||||
log.NewInfo(operationID, utils.GetSelfFuncName(), "sha256 result", sign)
|
|
||||||
reqAuth := AuthReq{
|
reqAuth := AuthReq{
|
||||||
Sign: sign,
|
Sign: sign,
|
||||||
Timestamp: strconv.Itoa(int(timeStamp)),
|
Timestamp: strconv.Itoa(int(timeStamp)),
|
||||||
Appkey: config.Config.Push.Getui.AppKey,
|
AppKey: config.Config.Push.Getui.AppKey,
|
||||||
}
|
}
|
||||||
respAuth := AuthResp{}
|
respAuth := AuthResp{}
|
||||||
err = g.request(AuthURL, reqAuth, "", &respAuth, operationID)
|
err = g.request(ctx, authURL, reqAuth, "", &respAuth)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", 0, err
|
return "", 0, err
|
||||||
}
|
}
|
||||||
log.NewInfo(operationID, utils.GetSelfFuncName(), "result: ", respAuth)
|
//log.NewInfo(operationID, utils.GetSelfFuncName(), "result: ", respAuth)
|
||||||
expire, err := strconv.Atoi(respAuth.ExpireTime)
|
expire, err := strconv.Atoi(respAuth.ExpireTime)
|
||||||
return respAuth.Token, int64(expire), err
|
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{}
|
respTask := TaskResp{}
|
||||||
ttl := int64(1000 * 60 * 5)
|
ttl := int64(1000 * 60 * 5)
|
||||||
pushReq.Settings = &Settings{TTL: &ttl}
|
pushReq.Settings = &Settings{TTL: &ttl}
|
||||||
err := g.request(TaskURL, pushReq, token, &respTask, operationID)
|
err := g.request(ctx, taskURL, pushReq, token, &respTask)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", utils.Wrap(err, "")
|
return "", utils.Wrap(err, "")
|
||||||
}
|
}
|
||||||
return respTask.TaskID, nil
|
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)
|
con, err := json.Marshal(content)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
client := &http.Client{}
|
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))
|
req, err := http.NewRequest("POST", config.Config.Push.Getui.PushUrl+url, bytes.NewBuffer(con))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -250,74 +140,38 @@ func (g *Getui) request(url string, content interface{}, token string, returnStr
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
log.NewDebug(operationID, "getui", utils.GetSelfFuncName(), "resp, ", string(result))
|
//log.NewDebug(operationID, "getui", utils.GetSelfFuncName(), "resp, ", string(result))
|
||||||
commonResp := GetuiCommonResp{}
|
commonResp := CommonResp{}
|
||||||
commonResp.Data = returnStruct
|
commonResp.Data = output
|
||||||
if err := json.Unmarshal(result, &commonResp); err != nil {
|
if err := json.Unmarshal(result, &commonResp); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if commonResp.Code == 10001 {
|
if commonResp.Code == tokenExpire {
|
||||||
return TokenExpireError
|
return TokenExpireError
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pushReq *PushReq) setPushChannel(title string, body string) {
|
func (g *Client) getTokenAndSave2Redis(ctx context.Context) (token string, err error) {
|
||||||
pushReq.PushChannel = &PushChannel{}
|
token, _, err = g.Auth(ctx, time.Now().UnixNano()/1e6)
|
||||||
// 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)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", utils.Wrap(err, "Auth failed")
|
return "", utils.Wrap(err, "Auth failed")
|
||||||
}
|
}
|
||||||
log.NewDebug(operationID, "getui", utils.GetSelfFuncName(), token, expireTime, err)
|
err = g.cache.SetGetuiTaskID(ctx, token, 60*60*23)
|
||||||
err = db.DB.SetGetuiToken(token, 60*60*23)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", utils.Wrap(err, "Auth failed")
|
return "", utils.Wrap(err, "Auth failed")
|
||||||
}
|
}
|
||||||
return token, nil
|
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)
|
ttl := int64(1000 * 60 * 60 * 24)
|
||||||
pushReq.Settings = &Settings{TTL: &ttl}
|
pushReq.Settings = &Settings{TTL: &ttl}
|
||||||
taskID, err = g.GetTaskID(operationID, token, pushReq)
|
taskID, err = g.GetTaskID(ctx, token, pushReq)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", utils.Wrap(err, "GetTaskIDAndSave2Redis failed")
|
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 {
|
if err != nil {
|
||||||
return "", utils.Wrap(err, "Auth failed")
|
return "", utils.Wrap(err, "Auth failed")
|
||||||
}
|
}
|
||||||
|
@ -4,27 +4,23 @@
|
|||||||
** author("fg,Gordon@open-im.io").
|
** author("fg,Gordon@open-im.io").
|
||||||
** time(2021/3/22 15:33).
|
** time(2021/3/22 15:33).
|
||||||
*/
|
*/
|
||||||
package logic
|
package push
|
||||||
|
|
||||||
import (
|
import (
|
||||||
pusher "Open_IM/internal/push"
|
|
||||||
fcm "Open_IM/internal/push/fcm"
|
fcm "Open_IM/internal/push/fcm"
|
||||||
"Open_IM/internal/push/getui"
|
"Open_IM/internal/push/getui"
|
||||||
jpush "Open_IM/internal/push/jpush"
|
jpush "Open_IM/internal/push/jpush"
|
||||||
"Open_IM/internal/push/mobpush"
|
|
||||||
"Open_IM/pkg/common/config"
|
"Open_IM/pkg/common/config"
|
||||||
"Open_IM/pkg/common/constant"
|
"Open_IM/pkg/common/constant"
|
||||||
"Open_IM/pkg/common/kafka"
|
"Open_IM/pkg/common/prome"
|
||||||
prome "Open_IM/pkg/common/prometheus"
|
|
||||||
"Open_IM/pkg/statistics"
|
"Open_IM/pkg/statistics"
|
||||||
"fmt"
|
"fmt"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
rpcServer RPCServer
|
rpcServer RPCServer
|
||||||
pushCh PushConsumerHandler
|
pushCh ConsumerHandler
|
||||||
producer *kafka.Producer
|
offlinePusher OfflinePusher
|
||||||
offlinePusher pusher.OfflinePusher
|
|
||||||
successCount uint64
|
successCount uint64
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -34,7 +30,6 @@ func Init(rpcPort int) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
func init() {
|
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)
|
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 {
|
if *config.Config.Push.Getui.Enable {
|
||||||
offlinePusher = getui.GetuiClient
|
offlinePusher = getui.GetuiClient
|
||||||
@ -46,10 +41,6 @@ func init() {
|
|||||||
if config.Config.Push.Fcm.Enable {
|
if config.Config.Push.Fcm.Enable {
|
||||||
offlinePusher = fcm.NewFcm()
|
offlinePusher = fcm.NewFcm()
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.Config.Push.Mob.Enable {
|
|
||||||
offlinePusher = mobpush.MobPushClient
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func initPrometheus() {
|
func initPrometheus() {
|
||||||
@ -59,7 +50,7 @@ func initPrometheus() {
|
|||||||
|
|
||||||
func Run(promethuesPort int) {
|
func Run(promethuesPort int) {
|
||||||
go rpcServer.run()
|
go rpcServer.run()
|
||||||
go pushCh.pushConsumerGroup.RegisterHandleAndConsumer(&pushCh)
|
go pushCh.ConsumerGroup.RegisterHandleAndConsumer(&pushCh)
|
||||||
go func() {
|
go func() {
|
||||||
err := prome.StartPromeSrv(promethuesPort)
|
err := prome.StartPromeSrv(promethuesPort)
|
||||||
if err != nil {
|
if err != nil {
|
@ -1,4 +1,4 @@
|
|||||||
package requestbody
|
package body
|
||||||
|
|
||||||
const (
|
const (
|
||||||
TAG = "tag"
|
TAG = "tag"
|
||||||
@ -20,7 +20,6 @@ func (a *Audience) set(key string, v []string) {
|
|||||||
a.audience = make(map[string][]string)
|
a.audience = make(map[string][]string)
|
||||||
a.Object = a.audience
|
a.Object = a.audience
|
||||||
}
|
}
|
||||||
|
|
||||||
//v, ok = this.audience[key]
|
//v, ok = this.audience[key]
|
||||||
//if ok {
|
//if ok {
|
||||||
// return
|
// return
|
@ -1,4 +1,4 @@
|
|||||||
package requestbody
|
package body
|
||||||
|
|
||||||
type Message struct {
|
type Message struct {
|
||||||
MsgContent string `json:"msg_content"`
|
MsgContent string `json:"msg_content"`
|
@ -1,4 +1,4 @@
|
|||||||
package requestbody
|
package body
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"Open_IM/pkg/common/config"
|
"Open_IM/pkg/common/config"
|
@ -1,4 +1,4 @@
|
|||||||
package requestbody
|
package body
|
||||||
|
|
||||||
type Options struct {
|
type Options struct {
|
||||||
ApnsProduction bool `json:"apns_production"`
|
ApnsProduction bool `json:"apns_production"`
|
@ -1,4 +1,4 @@
|
|||||||
package requestbody
|
package body
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"Open_IM/pkg/common/constant"
|
"Open_IM/pkg/common/constant"
|
@ -1,4 +1,4 @@
|
|||||||
package requestbody
|
package body
|
||||||
|
|
||||||
type PushObj struct {
|
type PushObj struct {
|
||||||
Platform interface{} `json:"platform"`
|
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 (
|
import (
|
||||||
"Open_IM/internal/push"
|
"Open_IM/internal/push"
|
||||||
|
"Open_IM/internal/push/jpush/body"
|
||||||
"Open_IM/internal/push/jpush/common"
|
"Open_IM/internal/push/jpush/common"
|
||||||
"Open_IM/internal/push/jpush/requestBody"
|
|
||||||
"Open_IM/pkg/common/config"
|
"Open_IM/pkg/common/config"
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"encoding/base64"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
@ -33,26 +35,31 @@ func (j *JPush) SetAlias(cid, alias string) (resp string, err error) {
|
|||||||
return resp, nil
|
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) {
|
func (j *JPush) Push(accounts []string, title, detailContent, operationID string, opts push.PushOpts) (string, error) {
|
||||||
|
var pf body.Platform
|
||||||
var pf requestbody.Platform
|
|
||||||
pf.SetAll()
|
pf.SetAll()
|
||||||
var au requestbody.Audience
|
var au body.Audience
|
||||||
au.SetAlias(accounts)
|
au.SetAlias(accounts)
|
||||||
var no requestbody.Notification
|
var no body.Notification
|
||||||
|
var extras body.Extras
|
||||||
var extras requestbody.Extras
|
|
||||||
if opts.Signal.ClientMsgID != "" {
|
if opts.Signal.ClientMsgID != "" {
|
||||||
extras.ClientMsgID = opts.Signal.ClientMsgID
|
extras.ClientMsgID = opts.Signal.ClientMsgID
|
||||||
}
|
}
|
||||||
no.IOSEnableMutableContent()
|
no.IOSEnableMutableContent()
|
||||||
no.SetExtras(extras)
|
no.SetExtras(extras)
|
||||||
no.SetAlert(title)
|
no.SetAlert(title)
|
||||||
var me requestbody.Message
|
var me body.Message
|
||||||
me.SetMsgContent(detailContent)
|
me.SetMsgContent(detailContent)
|
||||||
var o requestbody.Options
|
var o body.Options
|
||||||
o.SetApnsProduction(config.Config.IOSPush.Production)
|
o.SetApnsProduction(config.Config.IOSPush.Production)
|
||||||
var po requestbody.PushObj
|
var po body.PushObj
|
||||||
po.SetPlatform(&pf)
|
po.SetPlatform(&pf)
|
||||||
po.SetAudience(&au)
|
po.SetAudience(&au)
|
||||||
po.SetNotification(&no)
|
po.SetNotification(&no)
|
||||||
@ -68,8 +75,7 @@ func (j *JPush) Push(accounts []string, title, detailContent, operationID string
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
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)
|
resp, err := client.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
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").
|
** author("fg,Gordon@tuoyun.net").
|
||||||
** time(2021/5/13 10:33).
|
** time(2021/5/13 10:33).
|
||||||
*/
|
*/
|
||||||
package logic
|
package push
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"Open_IM/pkg/common/config"
|
"Open_IM/pkg/common/config"
|
||||||
@ -18,21 +18,16 @@ import (
|
|||||||
"github.com/golang/protobuf/proto"
|
"github.com/golang/protobuf/proto"
|
||||||
)
|
)
|
||||||
|
|
||||||
type fcb func(msg []byte)
|
type ConsumerHandler struct {
|
||||||
|
|
||||||
type PushConsumerHandler struct {
|
|
||||||
msgHandle map[string]fcb
|
|
||||||
pushConsumerGroup *kfk.MConsumerGroup
|
pushConsumerGroup *kfk.MConsumerGroup
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ms *PushConsumerHandler) Init() {
|
func (c *ConsumerHandler) Init() {
|
||||||
ms.msgHandle = make(map[string]fcb)
|
c.pushConsumerGroup = kfk.NewMConsumerGroup(&kfk.MConsumerGroupConfig{KafkaVersion: sarama.V2_0_0_0,
|
||||||
ms.msgHandle[config.Config.Kafka.Ms2pschat.Topic] = ms.handleMs2PsChat
|
|
||||||
ms.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,
|
OffsetsInitial: sarama.OffsetNewest, IsReturnErr: false}, []string{config.Config.Kafka.Ms2pschat.Topic}, config.Config.Kafka.Ms2pschat.Addr,
|
||||||
config.Config.Kafka.ConsumerGroupID.MsgToPush)
|
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))
|
log.NewDebug("", "msg come from kafka And push!!!", "msg", string(msg))
|
||||||
msgFromMQ := pbChat.PushMsgDataToMQ{}
|
msgFromMQ := pbChat.PushMsgDataToMQ{}
|
||||||
if err := proto.Unmarshal(msg, &msgFromMQ); err != nil {
|
if err := proto.Unmarshal(msg, &msgFromMQ); err != nil {
|
||||||
@ -55,16 +50,14 @@ func (ms *PushConsumerHandler) handleMs2PsChat(msg []byte) {
|
|||||||
default:
|
default:
|
||||||
MsgToUser(pbData)
|
MsgToUser(pbData)
|
||||||
}
|
}
|
||||||
//Call push module to send message to the user
|
|
||||||
//MsgToUser((*pbPush.PushMsgReq)(&msgFromMQ))
|
|
||||||
}
|
}
|
||||||
func (PushConsumerHandler) Setup(_ sarama.ConsumerGroupSession) error { return nil }
|
func (ConsumerHandler) Setup(_ sarama.ConsumerGroupSession) error { return nil }
|
||||||
func (PushConsumerHandler) Cleanup(_ sarama.ConsumerGroupSession) error { return nil }
|
func (ConsumerHandler) Cleanup(_ sarama.ConsumerGroupSession) error { return nil }
|
||||||
func (ms *PushConsumerHandler) ConsumeClaim(sess sarama.ConsumerGroupSession,
|
func (c *ConsumerHandler) ConsumeClaim(sess sarama.ConsumerGroupSession,
|
||||||
claim sarama.ConsumerGroupClaim) error {
|
claim sarama.ConsumerGroupClaim) error {
|
||||||
for msg := range claim.Messages() {
|
for msg := range claim.Messages() {
|
||||||
log.NewDebug("", "kafka get info to mysql", "msgTopic", msg.Topic, "msgPartition", msg.Partition, "msg", string(msg.Value))
|
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, "")
|
sess.MarkMessage(msg, "")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
@ -1,18 +1,16 @@
|
|||||||
package push
|
package push
|
||||||
|
|
||||||
import "Open_IM/pkg/common/constant"
|
import "context"
|
||||||
|
|
||||||
var PushTerminal = []int{constant.IOSPlatformID, constant.AndroidPlatformID, constant.WebPlatformID}
|
|
||||||
|
|
||||||
type OfflinePusher interface {
|
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 {
|
type Opts struct {
|
||||||
Signal Signal
|
Signal *Signal
|
||||||
IOSPushSound string
|
IOSPushSound string
|
||||||
IOSBadgeCount bool
|
IOSBadgeCount bool
|
||||||
Data string
|
Ex string
|
||||||
}
|
}
|
||||||
|
|
||||||
type Signal struct {
|
type Signal struct {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package logic
|
package push
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"Open_IM/pkg/common/config"
|
"Open_IM/pkg/common/config"
|
||||||
@ -6,7 +6,6 @@ import (
|
|||||||
"Open_IM/pkg/common/db"
|
"Open_IM/pkg/common/db"
|
||||||
"Open_IM/pkg/common/log"
|
"Open_IM/pkg/common/log"
|
||||||
prome "Open_IM/pkg/common/prometheus"
|
prome "Open_IM/pkg/common/prometheus"
|
||||||
"Open_IM/pkg/getcdv3"
|
|
||||||
pbPush "Open_IM/pkg/proto/push"
|
pbPush "Open_IM/pkg/proto/push"
|
||||||
"Open_IM/pkg/utils"
|
"Open_IM/pkg/utils"
|
||||||
"context"
|
"context"
|
@ -4,45 +4,33 @@
|
|||||||
** author("fg,Gordon@open-im.io").
|
** author("fg,Gordon@open-im.io").
|
||||||
** time(2021/3/5 14:31).
|
** time(2021/3/5 14:31).
|
||||||
*/
|
*/
|
||||||
package logic
|
package push
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"Open_IM/internal/push"
|
|
||||||
"Open_IM/pkg/common/config"
|
"Open_IM/pkg/common/config"
|
||||||
"Open_IM/pkg/common/constant"
|
"Open_IM/pkg/common/constant"
|
||||||
"Open_IM/pkg/common/db"
|
|
||||||
"Open_IM/pkg/common/log"
|
"Open_IM/pkg/common/log"
|
||||||
"Open_IM/pkg/getcdv3"
|
"Open_IM/pkg/common/prome"
|
||||||
pbPush "Open_IM/pkg/proto/push"
|
pbPush "Open_IM/pkg/proto/push"
|
||||||
pbRelay "Open_IM/pkg/proto/relay"
|
pbRelay "Open_IM/pkg/proto/relay"
|
||||||
pbRtc "Open_IM/pkg/proto/rtc"
|
pbRtc "Open_IM/pkg/proto/rtc"
|
||||||
"Open_IM/pkg/utils"
|
"Open_IM/pkg/utils"
|
||||||
"context"
|
"context"
|
||||||
"strings"
|
|
||||||
|
|
||||||
prome "Open_IM/pkg/common/prometheus"
|
|
||||||
|
|
||||||
"github.com/golang/protobuf/proto"
|
"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 {
|
type AtContent struct {
|
||||||
Text string `json:"text"`
|
Text string `json:"text"`
|
||||||
AtUserList []string `json:"atUserList"`
|
AtUserList []string `json:"atUserList"`
|
||||||
IsAtSelf bool `json:"isAtSelf"`
|
IsAtSelf bool `json:"isAtSelf"`
|
||||||
}
|
}
|
||||||
|
|
||||||
//var grpcCons []*grpc.ClientConn
|
|
||||||
|
|
||||||
func MsgToUser(pushMsg *pbPush.PushMsgReq) {
|
func MsgToUser(pushMsg *pbPush.PushMsgReq) {
|
||||||
var wsResult []*pbRelay.SingelMsgToUserResultList
|
var wsResult []*pbRelay.SingelMsgToUserResultList
|
||||||
isOfflinePush := utils.GetSwitchFromOptions(pushMsg.MsgData.Options, constant.IsOfflinePush)
|
isOfflinePush := utils.GetSwitchFromOptions(pushMsg.MsgData.Options, constant.IsOfflinePush)
|
||||||
log.Debug(pushMsg.OperationID, "Get msg from msg_transfer And push msg", pushMsg.String())
|
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)
|
grpcCons := rpc.GetDefaultGatewayConn4Unique(config.Config.Etcd.EtcdSchema, strings.Join(config.Config.Etcd.EtcdAddr, ","), pushMsg.OperationID)
|
||||||
|
|
||||||
var UIDList = []string{pushMsg.PushToUserID}
|
var UIDList = []string{pushMsg.PushToUserID}
|
||||||
@ -277,13 +265,13 @@ func MsgToSuperGroupUser(pushMsg *pbPush.PushMsgReq) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetOfflinePushOpts(pushMsg *pbPush.PushMsgReq) (opts push.PushOpts, err error) {
|
func GetOfflinePushOpts(pushMsg *pbPush.PushMsgReq) (opts *Opts, err error) {
|
||||||
if pushMsg.MsgData.ContentType < constant.SignalingNotificationEnd && pushMsg.MsgData.ContentType > constant.SignalingNotificationBegin {
|
if pushMsg.MsgData.ContentType > constant.SignalingNotificationBegin && pushMsg.MsgData.ContentType < constant.SignalingNotificationEnd {
|
||||||
req := &pbRtc.SignalReq{}
|
req := &pbRtc.SignalReq{}
|
||||||
if err := proto.Unmarshal(pushMsg.MsgData.Content, req); err != nil {
|
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) {
|
switch req.Payload.(type) {
|
||||||
case *pbRtc.SignalReq_Invite, *pbRtc.SignalReq_InviteInGroup:
|
case *pbRtc.SignalReq_Invite, *pbRtc.SignalReq_InviteInGroup:
|
||||||
opts.Signal.ClientMsgID = pushMsg.MsgData.ClientMsgID
|
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 {
|
if pushMsg.MsgData.OfflinePushInfo != nil {
|
||||||
|
opts = &Opts{}
|
||||||
opts.IOSBadgeCount = pushMsg.MsgData.OfflinePushInfo.IOSBadgeCount
|
opts.IOSBadgeCount = pushMsg.MsgData.OfflinePushInfo.IOSBadgeCount
|
||||||
opts.IOSPushSound = pushMsg.MsgData.OfflinePushInfo.IOSPushSound
|
opts.IOSPushSound = pushMsg.MsgData.OfflinePushInfo.IOSPushSound
|
||||||
opts.Data = pushMsg.MsgData.OfflinePushInfo.Ex
|
opts.Ex = pushMsg.MsgData.OfflinePushInfo.Ex
|
||||||
}
|
}
|
||||||
|
|
||||||
return opts, nil
|
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 (
|
import (
|
||||||
tpns "Open_IM/internal/push/sdk/tpns-server-sdk-go/go"
|
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/controller"
|
||||||
"Open_IM/pkg/common/db/relation"
|
"Open_IM/pkg/common/db/relation"
|
||||||
tableRelation "Open_IM/pkg/common/db/table/relation"
|
tableRelation "Open_IM/pkg/common/db/table/relation"
|
||||||
"Open_IM/pkg/common/db/unrelation"
|
|
||||||
"Open_IM/pkg/common/log"
|
"Open_IM/pkg/common/log"
|
||||||
promePkg "Open_IM/pkg/common/prometheus"
|
"Open_IM/pkg/common/prome"
|
||||||
"Open_IM/pkg/getcdv3"
|
|
||||||
pbConversation "Open_IM/pkg/proto/conversation"
|
pbConversation "Open_IM/pkg/proto/conversation"
|
||||||
pbUser "Open_IM/pkg/proto/user"
|
pbUser "Open_IM/pkg/proto/user"
|
||||||
"Open_IM/pkg/utils"
|
"Open_IM/pkg/utils"
|
||||||
|
@ -10,7 +10,7 @@ type CallbackBeforePushReq struct {
|
|||||||
GroupID string `json:"groupID"`
|
GroupID string `json:"groupID"`
|
||||||
ContentType int32 `json:"contentType"`
|
ContentType int32 `json:"contentType"`
|
||||||
SessionType int32 `json:"sessionType"`
|
SessionType int32 `json:"sessionType"`
|
||||||
AtUserIDList []string `json:"atUserIDList"`
|
AtUserIDs []string `json:"atUserIDList"`
|
||||||
Content string `json:"content"`
|
Content string `json:"content"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -21,7 +21,6 @@ type CallbackBeforePushResp struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type CallbackBeforeSuperGroupOnlinePushReq struct {
|
type CallbackBeforeSuperGroupOnlinePushReq struct {
|
||||||
//*common.OfflinePushInfo
|
|
||||||
UserStatusBaseCallback
|
UserStatusBaseCallback
|
||||||
ClientMsgID string `json:"clientMsgID"`
|
ClientMsgID string `json:"clientMsgID"`
|
||||||
SendID string `json:"sendID"`
|
SendID string `json:"sendID"`
|
||||||
@ -30,7 +29,7 @@ type CallbackBeforeSuperGroupOnlinePushReq struct {
|
|||||||
SessionType int32 `json:"sessionType"`
|
SessionType int32 `json:"sessionType"`
|
||||||
AtUserIDList []string `json:"atUserIDList"`
|
AtUserIDList []string `json:"atUserIDList"`
|
||||||
Content string `json:"content"`
|
Content string `json:"content"`
|
||||||
Seq uint32 `json:"seq"`
|
Seq int64 `json:"seq"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type CallbackBeforeSuperGroupOnlinePushResp struct {
|
type CallbackBeforeSuperGroupOnlinePushResp struct {
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
package http
|
package http
|
||||||
|
|
||||||
import (
|
import (
|
||||||
cbapi "Open_IM/pkg/callbackstruct"
|
"Open_IM/pkg/callbackstruct"
|
||||||
"Open_IM/pkg/common/config"
|
"Open_IM/pkg/common/config"
|
||||||
"Open_IM/pkg/common/constant"
|
"Open_IM/pkg/common/constant"
|
||||||
"bytes"
|
"bytes"
|
||||||
@ -33,19 +33,17 @@ func Get(url string) (response []byte, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// application/json; charset=utf-8
|
// 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)
|
jsonStr, err := json.Marshal(data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonStr))
|
req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonStr))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
req.Close = true
|
req.Close = true
|
||||||
req.Header.Add("content-type", "application/json; charset=utf-8")
|
req.Header.Add("content-type", "application/json; charset=utf-8")
|
||||||
|
|
||||||
client := &http.Client{Timeout: time.Duration(timeOutSecond) * time.Second}
|
client := &http.Client{Timeout: time.Duration(timeOutSecond) * time.Second}
|
||||||
resp, err := client.Do(req)
|
resp, err := client.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -59,11 +57,20 @@ func Post(url string, data interface{}, timeOutSecond int) (content []byte, err
|
|||||||
return result, nil
|
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 := urlLib.Values{}
|
||||||
v.Set("callbackCommand", callbackCommand)
|
v.Set("callbackCommand", command)
|
||||||
url = url + "?" + v.Encode()
|
url = url + "?" + v.Encode()
|
||||||
b, err := Post(url, input, callbackConfig.CallbackTimeOut)
|
b, err := Post(url, nil, input, callbackConfig.CallbackTimeOut)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if callbackConfig.CallbackFailedContinue != nil && *callbackConfig.CallbackFailedContinue {
|
if callbackConfig.CallbackFailedContinue != nil && *callbackConfig.CallbackFailedContinue {
|
||||||
return constant.ErrCallbackContinue
|
return constant.ErrCallbackContinue
|
||||||
@ -79,6 +86,6 @@ func callBackPostReturn(url, callbackCommand string, input interface{}, output c
|
|||||||
return output.Parse()
|
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)
|
return callBackPostReturn(url, req.GetCallbackCommand(), req, resp, callbackConfig)
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ type SvcDiscoveryRegistry interface {
|
|||||||
UnRegister() error
|
UnRegister() error
|
||||||
GetConns(serviceName string, opts ...grpc.DialOption) ([]*grpc.ClientConn, error)
|
GetConns(serviceName string, opts ...grpc.DialOption) ([]*grpc.ClientConn, error)
|
||||||
GetConn(serviceName string, opts ...grpc.DialOption) (*grpc.ClientConn, error)
|
GetConn(serviceName string, opts ...grpc.DialOption) (*grpc.ClientConn, error)
|
||||||
|
|
||||||
//RegisterConf(conf []byte) error
|
//RegisterConf(conf []byte) error
|
||||||
//LoadConf() ([]byte, error)
|
//LoadConf() ([]byte, error)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user