125 lines
3.7 KiB
Go
125 lines
3.7 KiB
Go
package telegram
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"net/http"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/perfect-panel/server/pkg/logger"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/perfect-panel/server/internal/model/auth"
|
|
"github.com/perfect-panel/server/internal/model/user"
|
|
"github.com/perfect-panel/server/internal/svc"
|
|
"github.com/perfect-panel/server/internal/types"
|
|
"github.com/perfect-panel/server/pkg/tool"
|
|
"github.com/perfect-panel/server/pkg/xerr"
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
func GetTelegramConfig(ctx context.Context, svcCtx *svc.ServiceContext) (*types.TelegramConfig, error) {
|
|
|
|
data, err := svcCtx.AuthModel.FindOneByMethod(ctx, "telegram")
|
|
if err != nil {
|
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "get Telegram config failed: %v", err.Error())
|
|
}
|
|
var telegramConfig auth.TelegramAuthConfig
|
|
err = json.Unmarshal([]byte(data.Config), &telegramConfig)
|
|
if err != nil {
|
|
logger.WithContext(ctx).Error("unmarshal telegram config failed", logger.Field("error", err.Error()))
|
|
return nil, err
|
|
}
|
|
|
|
return &types.TelegramConfig{
|
|
TelegramBotToken: telegramConfig.BotToken,
|
|
TelegramNotify: *data.Enabled,
|
|
TelegramWebHookDomain: telegramConfig.WebHookDomain,
|
|
}, nil
|
|
}
|
|
|
|
func ApiLink(ctx *gin.Context, svcCtx *svc.ServiceContext, method string) string {
|
|
cfg, _ := GetTelegramConfig(ctx, svcCtx)
|
|
return "https://api.telegram.org/bot" + cfg.TelegramBotToken + "/" + method
|
|
}
|
|
|
|
func SendUserMessage(ctx *gin.Context, svcCtx *svc.ServiceContext, u user.User, text string, parseMode string) {
|
|
req, _ := http.NewRequest("GET", ApiLink(ctx, svcCtx, "sendMessage"), nil)
|
|
q := req.URL.Query()
|
|
|
|
userTelegramChatId, ok := findTelegram(&u)
|
|
if !ok {
|
|
return
|
|
}
|
|
q.Add("chat_id", strconv.FormatInt(userTelegramChatId, 10))
|
|
if parseMode == "markdown" {
|
|
text = strings.ReplaceAll(text, "_", "\\_")
|
|
}
|
|
q.Add("text", text)
|
|
q.Add("parse_mode", parseMode)
|
|
req.URL.RawQuery = q.Encode()
|
|
_, _ = http.DefaultClient.Do(req)
|
|
|
|
}
|
|
|
|
func SendAdminMessage(ctx *gin.Context, svcCtx *svc.ServiceContext, text string, parseMode string) {
|
|
var adminTelegram []int64
|
|
f := false
|
|
adminTelegramJson, err := svcCtx.Redis.Get(ctx, "adminTelegram").Result()
|
|
if err == nil {
|
|
err = json.Unmarshal([]byte(adminTelegramJson), &adminTelegram)
|
|
if err == nil {
|
|
f = true
|
|
}
|
|
}
|
|
if !f {
|
|
svcCtx.DB.Model(&user.User{}).Where("is_admin = true").Pluck("telegram", &adminTelegram)
|
|
val, _ := json.Marshal(adminTelegram)
|
|
_ = svcCtx.Redis.Set(ctx, "TelegramConfig", string(val), time.Duration(3600)*time.Second).Err()
|
|
}
|
|
req, _ := http.NewRequest("GET", ApiLink(ctx, svcCtx, "sendMessage"), nil)
|
|
q := req.URL.Query()
|
|
if parseMode == "markdown" {
|
|
text = strings.ReplaceAll(text, "_", "\\_")
|
|
}
|
|
q.Add("text", text)
|
|
q.Add("parse_mode", parseMode)
|
|
for _, telegram := range adminTelegram {
|
|
q.Add("chat_id", strconv.FormatInt(telegram, 10))
|
|
req.URL.RawQuery = q.Encode()
|
|
_, _ = http.DefaultClient.Do(req)
|
|
}
|
|
}
|
|
|
|
func SetWebhook(ctx *gin.Context, svcCtx *svc.ServiceContext) error {
|
|
configs, _ := svcCtx.SystemModel.GetSiteConfig(ctx)
|
|
cfg := &types.SiteConfig{}
|
|
tool.SystemConfigSliceReflectToStruct(configs, cfg)
|
|
req, _ := http.NewRequest("GET", ApiLink(ctx, svcCtx, "setWebhook"), nil)
|
|
q := req.URL.Query()
|
|
q.Add("url", cfg.Host+"/telegram/webhook")
|
|
req.URL.RawQuery = q.Encode()
|
|
_, err := http.DefaultClient.Do(req)
|
|
if err != nil {
|
|
return errors.Wrapf(xerr.NewErrCode(xerr.ERROR), "set webhook error: %v", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func findTelegram(u *user.User) (int64, bool) {
|
|
for _, item := range u.AuthMethods {
|
|
if item.AuthType == "telegram" {
|
|
// string to int64
|
|
parseInt, err := strconv.ParseInt(item.AuthIdentifier, 10, 64)
|
|
if err != nil {
|
|
return 0, false
|
|
}
|
|
return parseInt, true
|
|
}
|
|
|
|
}
|
|
return 0, false
|
|
}
|