106 lines
3.0 KiB
Go
106 lines
3.0 KiB
Go
package telegram
|
||
|
||
import (
|
||
"context"
|
||
"log/slog"
|
||
"time"
|
||
|
||
"tgVideoCall/domain/admin"
|
||
"tgVideoCall/domain/admin/models"
|
||
"tgVideoCall/pkg/config"
|
||
|
||
tele "gopkg.in/telebot.v3"
|
||
)
|
||
|
||
type Server struct {
|
||
Service Service
|
||
bot *tele.Bot
|
||
cfg config.Config
|
||
log slog.Logger
|
||
ctx context.Context
|
||
}
|
||
|
||
// NewServer создает новый экземпляр сервера Telegram-бота без регистрации хендлеров
|
||
func NewServer(ctx context.Context, log slog.Logger, cfg config.Config, Service admin.Service) *Server {
|
||
return &Server{
|
||
log: log,
|
||
cfg: cfg,
|
||
Service: Service,
|
||
bot: initTelebot(cfg, log),
|
||
ctx: ctx,
|
||
}
|
||
}
|
||
|
||
func initTelebot(cfg config.Config, log slog.Logger) *tele.Bot {
|
||
const op = "gates.telegram.server.initTelebot"
|
||
//регестрируем бота
|
||
bot, err := tele.NewBot(tele.Settings{
|
||
Token: cfg.APIKeys.Telegram,
|
||
Synchronous: true,
|
||
Verbose: false,
|
||
OnError: func(err error, msg tele.Context) {
|
||
if err != nil {
|
||
log.Error(op, "failed to send message", err)
|
||
}
|
||
},
|
||
Poller: &tele.LongPoller{Timeout: 10 * time.Second},
|
||
})
|
||
if err != nil {
|
||
panic(err)
|
||
}
|
||
return bot
|
||
}
|
||
|
||
// RunServer регистрирует все публичные и приватные команды, а также middleware
|
||
func (s *Server) RunServer() {
|
||
// публичные команды
|
||
//s.bot.Handle("/start", s.hello)
|
||
//s.bot.Handle("/help", s.help)
|
||
|
||
// middleware
|
||
adminGroup := s.bot.Group()
|
||
adminGroup.Use(s.adminMiddleware)
|
||
|
||
// приватные команды
|
||
|
||
go func(ctx context.Context) {
|
||
time.Sleep(1 * time.Second)
|
||
<-ctx.Done()
|
||
s.bot.Stop()
|
||
}(s.ctx)
|
||
s.bot.Start()
|
||
}
|
||
|
||
func (s *Server) adminMiddleware(next tele.HandlerFunc) tele.HandlerFunc {
|
||
return func(teleCtx tele.Context) error {
|
||
const op = "gates.telegram.admin.adminMiddleware"
|
||
s.log.Info(op, "trying to check admin status for user: ", teleCtx.Sender().ID)
|
||
|
||
userID := teleCtx.Sender().ID
|
||
admin, err := s.Service.GetAdmin(s.ctx, int(userID))
|
||
|
||
if err == models.ErrNotAdmin {
|
||
s.log.Debug(op, "user not found in db or not admin, user_id: ", userID)
|
||
err = teleCtx.Reply("У вас нет прав администратора")
|
||
if err != nil {
|
||
s.log.Error(op, "error sending message", err, "to user: ", teleCtx.Sender().ID)
|
||
}
|
||
return nil // Возвращаем nil чтобы не показывать стектрейс
|
||
}
|
||
|
||
if err != nil {
|
||
s.log.Error(op, "error getting admin", err)
|
||
return teleCtx.Reply("Произошла внутренняя ошибка")
|
||
}
|
||
s.log.Debug(op, "admin found: ", admin, "role: ", admin.Role)
|
||
if admin.Role != "admin" && admin.Role != "creator" {
|
||
err = teleCtx.Reply("У вас нет прав администратора")
|
||
if err != nil {
|
||
s.log.Error(op, "error sending message", err, "to user: ", teleCtx.Sender().ID)
|
||
}
|
||
return nil // как при ErrNotAdmin — не показываем стектрейс при отказе в доступе
|
||
}
|
||
return next(teleCtx)
|
||
}
|
||
}
|