All checks were successful
itom-platform auto build image / build (push) Successful in 3m17s
218 lines
8.4 KiB
Go
218 lines
8.4 KiB
Go
package chat
|
||
|
||
import (
|
||
"context"
|
||
"errors"
|
||
"fmt"
|
||
"net/http"
|
||
"os"
|
||
"os/signal"
|
||
"strings"
|
||
"syscall"
|
||
"time"
|
||
|
||
chatmw "git.imall.cloud/openim/chat/internal/api/mw"
|
||
"git.imall.cloud/openim/chat/internal/api/util"
|
||
"git.imall.cloud/openim/chat/pkg/common/config"
|
||
"git.imall.cloud/openim/chat/pkg/common/imapi"
|
||
"git.imall.cloud/openim/chat/pkg/common/kdisc"
|
||
disetcd "git.imall.cloud/openim/chat/pkg/common/kdisc/etcd"
|
||
adminclient "git.imall.cloud/openim/chat/pkg/protocol/admin"
|
||
chatclient "git.imall.cloud/openim/chat/pkg/protocol/chat"
|
||
"github.com/gin-gonic/gin"
|
||
"github.com/openimsdk/tools/discovery/etcd"
|
||
"github.com/openimsdk/tools/errs"
|
||
"github.com/openimsdk/tools/mw"
|
||
"github.com/openimsdk/tools/system/program"
|
||
"github.com/openimsdk/tools/utils/datautil"
|
||
"github.com/openimsdk/tools/utils/runtimeenv"
|
||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||
"google.golang.org/grpc"
|
||
"google.golang.org/grpc/credentials/insecure"
|
||
)
|
||
|
||
type Config struct {
|
||
ApiConfig config.API
|
||
Discovery config.Discovery
|
||
Share config.Share
|
||
Redis config.Redis
|
||
|
||
RuntimeEnv string
|
||
}
|
||
|
||
func Start(ctx context.Context, index int, cfg *Config) error {
|
||
cfg.RuntimeEnv = runtimeenv.PrintRuntimeEnvironment()
|
||
|
||
if len(cfg.Share.ChatAdmin) == 0 {
|
||
return errs.New("share chat admin not configured")
|
||
}
|
||
apiPort, err := datautil.GetElemByIndex(cfg.ApiConfig.Api.Ports, index)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
client, err := kdisc.NewDiscoveryRegister(&cfg.Discovery, cfg.RuntimeEnv, nil)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
chatConn, err := client.GetConn(ctx, cfg.Discovery.RpcService.Chat, grpc.WithTransportCredentials(insecure.NewCredentials()), mw.GrpcClient())
|
||
if err != nil {
|
||
return err
|
||
}
|
||
adminConn, err := client.GetConn(ctx, cfg.Discovery.RpcService.Admin, grpc.WithTransportCredentials(insecure.NewCredentials()), mw.GrpcClient())
|
||
if err != nil {
|
||
return err
|
||
}
|
||
chatClient := chatclient.NewChatClient(chatConn)
|
||
adminClient := adminclient.NewAdminClient(adminConn)
|
||
im := imapi.New(cfg.Share.OpenIM.ApiURL, cfg.Share.OpenIM.Secret, cfg.Share.OpenIM.AdminUserID)
|
||
base := util.Api{
|
||
ImUserID: cfg.Share.OpenIM.AdminUserID,
|
||
ProxyHeader: cfg.Share.ProxyHeader,
|
||
ChatAdminUserID: cfg.Share.ChatAdmin[0],
|
||
}
|
||
adminApi := New(chatClient, adminClient, im, &base)
|
||
mwApi := chatmw.New(adminClient)
|
||
gin.SetMode(gin.ReleaseMode)
|
||
engine := gin.New()
|
||
engine.Use(gin.Recovery(), mw.CorsHandler(), mw.GinParseOperationID())
|
||
|
||
// 可选的 Prometheus metrics 端点
|
||
// 支持配置文件或环境变量控制(环境变量优先)
|
||
prometheusEnable := cfg.ApiConfig.Prometheus.Enable
|
||
if envEnable := os.Getenv("PROMETHEUS_ENABLE"); envEnable != "" {
|
||
prometheusEnable = strings.ToLower(envEnable) == "true" || envEnable == "1"
|
||
}
|
||
if prometheusEnable {
|
||
metricsPath := cfg.ApiConfig.Prometheus.Path
|
||
if envPath := os.Getenv("PROMETHEUS_PATH"); envPath != "" {
|
||
metricsPath = envPath
|
||
}
|
||
if metricsPath == "" {
|
||
metricsPath = "/metrics"
|
||
}
|
||
engine.GET(metricsPath, gin.WrapH(promhttp.Handler()))
|
||
}
|
||
|
||
SetChatRoute(engine, adminApi, mwApi)
|
||
|
||
var (
|
||
netDone = make(chan struct{}, 1)
|
||
netErr error
|
||
)
|
||
server := http.Server{Addr: fmt.Sprintf(":%d", apiPort), Handler: engine}
|
||
go func() {
|
||
err = server.ListenAndServe()
|
||
if err != nil && !errors.Is(err, http.ErrServerClosed) {
|
||
netErr = errs.WrapMsg(err, fmt.Sprintf("api start err: %s", server.Addr))
|
||
netDone <- struct{}{}
|
||
}
|
||
}()
|
||
if cfg.Discovery.Enable == kdisc.ETCDCONST {
|
||
cm := disetcd.NewConfigManager(client.(*etcd.SvcDiscoveryRegistryImpl).GetClient(),
|
||
[]string{
|
||
config.ChatAPIChatCfgFileName,
|
||
config.DiscoveryConfigFileName,
|
||
config.ShareFileName,
|
||
config.LogConfigFileName,
|
||
},
|
||
)
|
||
cm.Watch(ctx)
|
||
}
|
||
shutdown := func() error {
|
||
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
|
||
defer cancel()
|
||
err := server.Shutdown(ctx)
|
||
if err != nil {
|
||
return errs.WrapMsg(err, "shutdown err")
|
||
}
|
||
return nil
|
||
}
|
||
disetcd.RegisterShutDown(shutdown)
|
||
|
||
sigs := make(chan os.Signal, 1)
|
||
signal.Notify(sigs, syscall.SIGTERM)
|
||
select {
|
||
case <-sigs:
|
||
program.SIGTERMExit()
|
||
if err := shutdown(); err != nil {
|
||
return err
|
||
}
|
||
case <-netDone:
|
||
close(netDone)
|
||
return netErr
|
||
}
|
||
return nil
|
||
}
|
||
|
||
func SetChatRoute(router gin.IRouter, chat *Api, mw *chatmw.MW) {
|
||
account := router.Group("/account")
|
||
account.GET("/captcha", chat.GetCaptchaImage) // Get captcha image
|
||
account.POST("/code/send", chat.SendVerifyCode) // Send verification code
|
||
account.POST("/code/verify", chat.VerifyCode) // Verify the verification code
|
||
account.POST("/register", mw.CheckAdminOrNil, chat.RegisterUser) // Register
|
||
account.POST("/login", chat.Login) // Login
|
||
account.POST("/password/reset", chat.ResetPassword) // Forgot password
|
||
account.POST("/password/change", mw.CheckToken, chat.ChangePassword) // Change password
|
||
|
||
user := router.Group("/user", mw.CheckToken)
|
||
user.POST("/update", chat.UpdateUserInfo) // Edit personal information
|
||
user.POST("/find/public", chat.FindUserPublicInfo) // Get user's public information
|
||
user.POST("/find/full", chat.FindUserFullInfo) // Get all information of the user
|
||
user.POST("/search/full", chat.SearchUserFullInfo) // Search user's public information
|
||
user.POST("/search/public", chat.SearchUserPublicInfo) // Search all information of the user
|
||
user.POST("/rtc/get_token", chat.GetTokenForVideoMeeting) // Get token for video meeting for the user
|
||
|
||
router.POST("/friend/search", mw.CheckToken, chat.SearchFriend)
|
||
router.POST("/friend/add", mw.CheckToken, chat.AddFriend)
|
||
|
||
router.Group("/applet").POST("/find", mw.CheckToken, chat.FindApplet) // Applet list
|
||
|
||
router.Group("/client_config").POST("/get", chat.GetClientConfig) // Get client initialization configuration
|
||
|
||
applicationGroup := router.Group("application")
|
||
applicationGroup.POST("/latest_version", chat.LatestApplicationVersion)
|
||
applicationGroup.POST("/page_versions", chat.PageApplicationVersion)
|
||
|
||
router.Group("/callback").POST("/open_im", chat.OpenIMCallback) // Callback
|
||
|
||
// 系统配置相关接口(客户端)
|
||
systemConfig := router.Group("/system_config")
|
||
systemConfig.POST("/get_app_configs", chat.GetAppSystemConfigs) // 获取APP端配置(show_in_app=true 且 enabled=true)
|
||
|
||
// 钱包相关接口(客户端)
|
||
wallet := router.Group("/wallet", mw.CheckToken)
|
||
wallet.POST("/balance", chat.GetWalletBalance) // 获取钱包余额
|
||
wallet.POST("/info", chat.GetWalletInfo) // 获取钱包详细信息
|
||
wallet.POST("/balance_records", chat.GetWalletBalanceRecords) // 获取余额明细
|
||
wallet.POST("/payment_password/set", chat.SetPaymentPassword) // 设置支付密码(首次设置或修改)
|
||
wallet.POST("/withdraw_account/set", chat.SetWithdrawAccount) // 设置提现账号
|
||
wallet.POST("/withdraw/apply", chat.CreateWithdrawApplication) // 申请提现
|
||
wallet.POST("/withdraw/list", chat.GetWithdrawApplications) // 获取提现申请列表
|
||
wallet.POST("/real_name_auth", chat.RealNameAuth) // 实名认证
|
||
|
||
// 敏感词相关接口(客户端)
|
||
sensitive := router.Group("/sensitive_word", mw.CheckToken)
|
||
sensitive.POST("/get", chat.GetSensitiveWords) // 获取敏感词列表
|
||
sensitive.POST("/check", chat.CheckSensitiveWords) // 检测敏感词
|
||
|
||
// 收藏相关接口
|
||
favorite := router.Group("/favorite", mw.CheckToken)
|
||
favorite.POST("/create", chat.CreateFavorite) // 创建收藏
|
||
favorite.POST("/get", chat.GetFavorite) // 获取收藏详情
|
||
favorite.POST("/list", chat.GetFavorites) // 获取收藏列表
|
||
favorite.POST("/search", chat.SearchFavorites) // 搜索收藏
|
||
favorite.POST("/update", chat.UpdateFavorite) // 更新收藏
|
||
favorite.POST("/delete", chat.DeleteFavorite) // 删除收藏
|
||
favorite.POST("/tags", chat.GetFavoritesByTags) // 根据标签获取收藏
|
||
favorite.POST("/count", chat.GetFavoriteCount) // 获取收藏数量
|
||
|
||
// 定时任务相关接口
|
||
scheduledTask := router.Group("/scheduled_task", mw.CheckToken)
|
||
scheduledTask.POST("/create", chat.CreateScheduledTask) // 创建定时任务
|
||
scheduledTask.POST("/get", chat.GetScheduledTask) // 获取定时任务详情
|
||
scheduledTask.POST("/list", chat.GetScheduledTasks) // 获取定时任务列表
|
||
scheduledTask.POST("/update", chat.UpdateScheduledTask) // 更新定时任务
|
||
scheduledTask.POST("/delete", chat.DeleteScheduledTask) // 删除定时任务
|
||
}
|