mirror of
				https://github.com/openimsdk/open-im-server.git
				synced 2025-11-04 11:22:10 +08:00 
			
		
		
		
	Merge remote-tracking branch 'origin/main' into list
# Conflicts: # go.mod # go.sum
This commit is contained in:
		
						commit
						ec40d824f6
					
				@ -23,7 +23,9 @@ geTui:
 | 
				
			|||||||
  channelID: ''
 | 
					  channelID: ''
 | 
				
			||||||
  channelName: ''
 | 
					  channelName: ''
 | 
				
			||||||
fcm:
 | 
					fcm:
 | 
				
			||||||
  serviceAccount: "x.json"
 | 
					  # Prioritize using file paths. If the file path is empty, use URL
 | 
				
			||||||
 | 
					  filePath: ""  # File path is concatenated with the parameters passed in through - c(`mage` default pass in `config/`) and filePath. 
 | 
				
			||||||
 | 
					  authURL: ""  #  Must start with https or http.
 | 
				
			||||||
jpns:
 | 
					jpns:
 | 
				
			||||||
  appKey: ''
 | 
					  appKey: ''
 | 
				
			||||||
  masterSecret: ''
 | 
					  masterSecret: ''
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										2
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								go.mod
									
									
									
									
									
								
							@ -176,5 +176,3 @@ require (
 | 
				
			|||||||
	golang.org/x/crypto v0.21.0 // indirect
 | 
						golang.org/x/crypto v0.21.0 // indirect
 | 
				
			||||||
	gopkg.in/ini.v1 v1.67.0 // indirect
 | 
						gopkg.in/ini.v1 v1.67.0 // indirect
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					 | 
				
			||||||
//replace github.com/openimsdk/protocol => /Users/chao/Desktop/project/protocol
 | 
					 | 
				
			||||||
 | 
				
			|||||||
@ -16,8 +16,11 @@ package fcm
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"context"
 | 
						"context"
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
	"github.com/openimsdk/open-im-server/v3/internal/push/offlinepush/options"
 | 
						"github.com/openimsdk/open-im-server/v3/internal/push/offlinepush/options"
 | 
				
			||||||
 | 
						"github.com/openimsdk/tools/utils/httputil"
 | 
				
			||||||
	"path/filepath"
 | 
						"path/filepath"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	firebase "firebase.google.com/go"
 | 
						firebase "firebase.google.com/go"
 | 
				
			||||||
	"firebase.google.com/go/messaging"
 | 
						"firebase.google.com/go/messaging"
 | 
				
			||||||
@ -40,13 +43,25 @@ type Fcm struct {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// NewClient initializes a new FCM client using the Firebase Admin SDK.
 | 
					// NewClient initializes a new FCM client using the Firebase Admin SDK.
 | 
				
			||||||
// It requires the FCM service account credentials file located within the project's configuration directory.
 | 
					// It requires the FCM service account credentials file located within the project's configuration directory.
 | 
				
			||||||
func NewClient(pushConf *config.Push, cache cache.ThirdCache) (*Fcm, error) {
 | 
					func NewClient(pushConf *config.Push, cache cache.ThirdCache, fcmConfigPath string) (*Fcm, error) {
 | 
				
			||||||
	projectRoot, err := config.GetProjectRoot()
 | 
						var opt option.ClientOption
 | 
				
			||||||
	if err != nil {
 | 
						switch {
 | 
				
			||||||
		return nil, err
 | 
						case len(pushConf.FCM.FilePath) != 0:
 | 
				
			||||||
 | 
							// with file path
 | 
				
			||||||
 | 
							credentialsFilePath := filepath.Join(fcmConfigPath, pushConf.FCM.FilePath)
 | 
				
			||||||
 | 
							opt = option.WithCredentialsFile(credentialsFilePath)
 | 
				
			||||||
 | 
						case len(pushConf.FCM.AuthURL) != 0:
 | 
				
			||||||
 | 
							// with authentication URL
 | 
				
			||||||
 | 
							client := httputil.NewHTTPClient(httputil.NewClientConfig())
 | 
				
			||||||
 | 
							resp, err := client.Get(pushConf.FCM.AuthURL)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return nil, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							opt = option.WithCredentialsJSON(resp)
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return nil, errs.New("no FCM config").Wrap()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	credentialsFilePath := filepath.Join(projectRoot, "config", pushConf.FCM.ServiceAccount)
 | 
					
 | 
				
			||||||
	opt := option.WithCredentialsFile(credentialsFilePath)
 | 
					 | 
				
			||||||
	fcmApp, err := firebase.NewApp(context.Background(), nil, opt)
 | 
						fcmApp, err := firebase.NewApp(context.Background(), nil, opt)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, errs.Wrap(err)
 | 
							return nil, errs.Wrap(err)
 | 
				
			||||||
@ -56,7 +71,6 @@ func NewClient(pushConf *config.Push, cache cache.ThirdCache) (*Fcm, error) {
 | 
				
			|||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, errs.Wrap(err)
 | 
							return nil, errs.Wrap(err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	return &Fcm{fcmMsgCli: fcmMsgClient, cache: cache}, nil
 | 
						return &Fcm{fcmMsgCli: fcmMsgClient, cache: cache}, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -79,6 +93,8 @@ func (f *Fcm) Push(ctx context.Context, userIDs []string, title, content string,
 | 
				
			|||||||
	notification.Body = content
 | 
						notification.Body = content
 | 
				
			||||||
	notification.Title = title
 | 
						notification.Title = title
 | 
				
			||||||
	var messages []*messaging.Message
 | 
						var messages []*messaging.Message
 | 
				
			||||||
 | 
						var sendErrBuilder strings.Builder
 | 
				
			||||||
 | 
						var msgErrBuilder strings.Builder
 | 
				
			||||||
	for userID, personTokens := range allTokens {
 | 
						for userID, 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)
 | 
				
			||||||
@ -86,9 +102,21 @@ func (f *Fcm) Push(ctx context.Context, userIDs []string, title, content string,
 | 
				
			|||||||
			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
 | 
				
			||||||
 | 
									// Record push error
 | 
				
			||||||
 | 
									sendErrBuilder.WriteString(err.Error())
 | 
				
			||||||
 | 
									sendErrBuilder.WriteByte('.')
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				Success = Success + response.SuccessCount
 | 
									Success = Success + response.SuccessCount
 | 
				
			||||||
				Fail = Fail + response.FailureCount
 | 
									Fail = Fail + response.FailureCount
 | 
				
			||||||
 | 
									if response.FailureCount != 0 {
 | 
				
			||||||
 | 
										// Record message error
 | 
				
			||||||
 | 
										for i := range response.Responses {
 | 
				
			||||||
 | 
											if !response.Responses[i].Success {
 | 
				
			||||||
 | 
												msgErrBuilder.WriteString(response.Responses[i].Error.Error())
 | 
				
			||||||
 | 
												msgErrBuilder.WriteByte('.')
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			messages = messages[0:0]
 | 
								messages = messages[0:0]
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@ -134,5 +162,9 @@ func (f *Fcm) Push(ctx context.Context, userIDs []string, title, content string,
 | 
				
			|||||||
			Fail = Fail + response.FailureCount
 | 
								Fail = Fail + response.FailureCount
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						if Fail != 0 {
 | 
				
			||||||
 | 
							return errs.New(fmt.Sprintf("%d message send failed;send err:%s;message err:%s",
 | 
				
			||||||
 | 
								Fail, sendErrBuilder.String(), msgErrBuilder.String())).Wrap()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -36,13 +36,13 @@ type OfflinePusher interface {
 | 
				
			|||||||
	Push(ctx context.Context, userIDs []string, title, content string, opts *options.Opts) error
 | 
						Push(ctx context.Context, userIDs []string, title, content string, opts *options.Opts) error
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func NewOfflinePusher(pushConf *config.Push, cache cache.ThirdCache) (OfflinePusher, error) {
 | 
					func NewOfflinePusher(pushConf *config.Push, cache cache.ThirdCache, fcmConfigPath string) (OfflinePusher, error) {
 | 
				
			||||||
	var offlinePusher OfflinePusher
 | 
						var offlinePusher OfflinePusher
 | 
				
			||||||
	switch pushConf.Enable {
 | 
						switch pushConf.Enable {
 | 
				
			||||||
	case geTUI:
 | 
						case geTUI:
 | 
				
			||||||
		offlinePusher = getui.NewClient(pushConf, cache)
 | 
							offlinePusher = getui.NewClient(pushConf, cache)
 | 
				
			||||||
	case firebase:
 | 
						case firebase:
 | 
				
			||||||
		return fcm.NewClient(pushConf, cache)
 | 
							return fcm.NewClient(pushConf, cache, fcmConfigPath)
 | 
				
			||||||
	case jPush:
 | 
						case jPush:
 | 
				
			||||||
		offlinePusher = jpush.NewClient(pushConf)
 | 
							offlinePusher = jpush.NewClient(pushConf)
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
 | 
				
			|||||||
@ -29,6 +29,7 @@ type Config struct {
 | 
				
			|||||||
	WebhooksConfig     config.Webhooks
 | 
						WebhooksConfig     config.Webhooks
 | 
				
			||||||
	LocalCacheConfig   config.LocalCache
 | 
						LocalCacheConfig   config.LocalCache
 | 
				
			||||||
	Discovery          config.Discovery
 | 
						Discovery          config.Discovery
 | 
				
			||||||
 | 
						FcmConfigPath      string
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (p pushServer) PushMsg(ctx context.Context, req *pbpush.PushMsgReq) (*pbpush.PushMsgResp, error) {
 | 
					func (p pushServer) PushMsg(ctx context.Context, req *pbpush.PushMsgReq) (*pbpush.PushMsgResp, error) {
 | 
				
			||||||
@ -50,7 +51,7 @@ func Start(ctx context.Context, config *Config, client discovery.SvcDiscoveryReg
 | 
				
			|||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	cacheModel := redis.NewThirdCache(rdb)
 | 
						cacheModel := redis.NewThirdCache(rdb)
 | 
				
			||||||
	offlinePusher, err := offlinepush.NewOfflinePusher(&config.RpcConfig, cacheModel)
 | 
						offlinePusher, err := offlinepush.NewOfflinePusher(&config.RpcConfig, cacheModel, config.FcmConfigPath)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
				
			|||||||
@ -16,6 +16,7 @@ package auth
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"context"
 | 
						"context"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/openimsdk/open-im-server/v3/pkg/common/config"
 | 
						"github.com/openimsdk/open-im-server/v3/pkg/common/config"
 | 
				
			||||||
	redis2 "github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache/redis"
 | 
						redis2 "github.com/openimsdk/open-im-server/v3/pkg/common/storage/cache/redis"
 | 
				
			||||||
	"github.com/openimsdk/tools/db/redisutil"
 | 
						"github.com/openimsdk/tools/db/redisutil"
 | 
				
			||||||
@ -32,7 +33,6 @@ import (
 | 
				
			|||||||
	"github.com/openimsdk/tools/discovery"
 | 
						"github.com/openimsdk/tools/discovery"
 | 
				
			||||||
	"github.com/openimsdk/tools/errs"
 | 
						"github.com/openimsdk/tools/errs"
 | 
				
			||||||
	"github.com/openimsdk/tools/log"
 | 
						"github.com/openimsdk/tools/log"
 | 
				
			||||||
	"github.com/openimsdk/tools/mcontext"
 | 
					 | 
				
			||||||
	"github.com/openimsdk/tools/tokenverify"
 | 
						"github.com/openimsdk/tools/tokenverify"
 | 
				
			||||||
	"google.golang.org/grpc"
 | 
						"google.golang.org/grpc"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
@ -153,21 +153,19 @@ func (s *authServer) ForceLogout(ctx context.Context, req *pbauth.ForceLogoutReq
 | 
				
			|||||||
	if err := authverify.CheckAdmin(ctx, s.config.Share.IMAdminUserID); err != nil {
 | 
						if err := authverify.CheckAdmin(ctx, s.config.Share.IMAdminUserID); err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if err := s.forceKickOff(ctx, req.UserID, req.PlatformID, mcontext.GetOperationID(ctx)); err != nil {
 | 
						if err := s.forceKickOff(ctx, req.UserID, req.PlatformID); err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return &pbauth.ForceLogoutResp{}, nil
 | 
						return &pbauth.ForceLogoutResp{}, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (s *authServer) forceKickOff(ctx context.Context, userID string, platformID int32, operationID string) error {
 | 
					func (s *authServer) forceKickOff(ctx context.Context, userID string, platformID int32) error {
 | 
				
			||||||
	conns, err := s.RegisterCenter.GetConns(ctx, s.config.Share.RpcRegisterName.MessageGateway)
 | 
						conns, err := s.RegisterCenter.GetConns(ctx, s.config.Share.RpcRegisterName.MessageGateway)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	for _, v := range conns {
 | 
						for _, v := range conns {
 | 
				
			||||||
		log.ZDebug(ctx, "forceKickOff", "conn", v.Target())
 | 
							log.ZDebug(ctx, "forceKickOff", "conn", v.Target())
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	for _, v := range conns {
 | 
					 | 
				
			||||||
		client := msggateway.NewMsgGatewayClient(v)
 | 
							client := msggateway.NewMsgGatewayClient(v)
 | 
				
			||||||
		kickReq := &msggateway.KickUserOfflineReq{KickUserIDList: []string{userID}, PlatformID: platformID}
 | 
							kickReq := &msggateway.KickUserOfflineReq{KickUserIDList: []string{userID}, PlatformID: platformID}
 | 
				
			||||||
		_, err := client.KickUserOffline(ctx, kickReq)
 | 
							_, err := client.KickUserOffline(ctx, kickReq)
 | 
				
			||||||
@ -175,8 +173,24 @@ func (s *authServer) forceKickOff(ctx context.Context, userID string, platformID
 | 
				
			|||||||
			log.ZError(ctx, "forceKickOff", err, "kickReq", kickReq)
 | 
								log.ZError(ctx, "forceKickOff", err, "kickReq", kickReq)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						m, err := s.authDatabase.GetTokensWithoutError(ctx, userID, int(platformID))
 | 
				
			||||||
 | 
						if err != nil && err != redis.Nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for k := range m {
 | 
				
			||||||
 | 
							m[k] = constant.KickedToken
 | 
				
			||||||
 | 
							log.ZDebug(ctx, "set token map is ", "token map", m, "userID",
 | 
				
			||||||
 | 
								userID, "token", k)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							err = s.authDatabase.SetTokenMapByUidPid(ctx, userID, int(platformID), m)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (s *authServer) InvalidateToken(ctx context.Context, req *pbauth.InvalidateTokenReq) (*pbauth.InvalidateTokenResp, error) {
 | 
					func (s *authServer) InvalidateToken(ctx context.Context, req *pbauth.InvalidateTokenReq) (*pbauth.InvalidateTokenResp, error) {
 | 
				
			||||||
	m, err := s.authDatabase.GetTokensWithoutError(ctx, req.UserID, int(req.PlatformID))
 | 
						m, err := s.authDatabase.GetTokensWithoutError(ctx, req.UserID, int(req.PlatformID))
 | 
				
			||||||
	if err != nil && err != redis.Nil {
 | 
						if err != nil && err != redis.Nil {
 | 
				
			||||||
 | 
				
			|||||||
@ -47,6 +47,7 @@ func NewPushRpcCmd() *PushRpcCmd {
 | 
				
			|||||||
	ret.RootCmd = NewRootCmd(program.GetProcessName(), WithConfigMap(ret.configMap))
 | 
						ret.RootCmd = NewRootCmd(program.GetProcessName(), WithConfigMap(ret.configMap))
 | 
				
			||||||
	ret.ctx = context.WithValue(context.Background(), "version", config.Version)
 | 
						ret.ctx = context.WithValue(context.Background(), "version", config.Version)
 | 
				
			||||||
	ret.Command.RunE = func(cmd *cobra.Command, args []string) error {
 | 
						ret.Command.RunE = func(cmd *cobra.Command, args []string) error {
 | 
				
			||||||
 | 
							ret.pushConfig.FcmConfigPath = ret.ConfigPath()
 | 
				
			||||||
		return ret.runE()
 | 
							return ret.runE()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return ret
 | 
						return ret
 | 
				
			||||||
 | 
				
			|||||||
@ -31,6 +31,11 @@ type RootCmd struct {
 | 
				
			|||||||
	prometheusPort int
 | 
						prometheusPort int
 | 
				
			||||||
	log            config.Log
 | 
						log            config.Log
 | 
				
			||||||
	index          int
 | 
						index          int
 | 
				
			||||||
 | 
						configPath     string
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (r *RootCmd) ConfigPath() string {
 | 
				
			||||||
 | 
						return r.configPath
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (r *RootCmd) Index() int {
 | 
					func (r *RootCmd) Index() int {
 | 
				
			||||||
@ -153,6 +158,7 @@ func (r *RootCmd) getFlag(cmd *cobra.Command) (string, int, error) {
 | 
				
			|||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return "", 0, errs.Wrap(err)
 | 
							return "", 0, errs.Wrap(err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						r.configPath = configDirectory
 | 
				
			||||||
	index, err := cmd.Flags().GetInt(FlagTransferIndex)
 | 
						index, err := cmd.Flags().GetInt(FlagTransferIndex)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return "", 0, errs.Wrap(err)
 | 
							return "", 0, errs.Wrap(err)
 | 
				
			||||||
 | 
				
			|||||||
@ -202,7 +202,8 @@ type Push struct {
 | 
				
			|||||||
		ChannelName  string `mapstructure:"channelName"`
 | 
							ChannelName  string `mapstructure:"channelName"`
 | 
				
			||||||
	} `mapstructure:"geTui"`
 | 
						} `mapstructure:"geTui"`
 | 
				
			||||||
	FCM struct {
 | 
						FCM struct {
 | 
				
			||||||
		ServiceAccount string `mapstructure:"serviceAccount"`
 | 
							FilePath string `mapstructure:"filePath"`
 | 
				
			||||||
 | 
							AuthURL  string `mapstructure:"authURL"`
 | 
				
			||||||
	} `mapstructure:"fcm"`
 | 
						} `mapstructure:"fcm"`
 | 
				
			||||||
	JPNS struct {
 | 
						JPNS struct {
 | 
				
			||||||
		AppKey       string `mapstructure:"appKey"`
 | 
							AppKey       string `mapstructure:"appKey"`
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user