71 lines
2.1 KiB
Go
71 lines
2.1 KiB
Go
package telegram
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"log/slog"
|
|
)
|
|
|
|
type Service struct {
|
|
repo Repository
|
|
sender Sender
|
|
logger *slog.Logger
|
|
}
|
|
|
|
func NewService(repo Repository, sender Sender, logger *slog.Logger) *Service {
|
|
return &Service{repo: repo, sender: sender, logger: logger}
|
|
}
|
|
|
|
func (s *Service) Get(ctx context.Context) (*Settings, error) {
|
|
return s.repo.Get(ctx)
|
|
}
|
|
|
|
// Update persists the settings. botToken == "" means "leave the currently
|
|
// stored token untouched" -- the admin never has to re-type the secret just
|
|
// to flip a checkbox, and the API never has to echo it back.
|
|
func (s *Service) Update(ctx context.Context, enabled bool, botToken, chatID string, notifyNewOrder bool) (*Settings, error) {
|
|
settings := &Settings{
|
|
Enabled: enabled,
|
|
BotToken: botToken,
|
|
ChatID: chatID,
|
|
NotifyNewOrder: notifyNewOrder,
|
|
}
|
|
if err := s.repo.Update(ctx, settings); err != nil {
|
|
return nil, err
|
|
}
|
|
return s.repo.Get(ctx)
|
|
}
|
|
|
|
func (s *Service) SendTestMessage(ctx context.Context) error {
|
|
settings, err := s.repo.Get(ctx)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if settings.BotToken == "" || settings.ChatID == "" {
|
|
return fmt.Errorf("bot token and chat id must be configured before testing")
|
|
}
|
|
return s.sender.Send(ctx, settings.BotToken, settings.ChatID, "Test notification: your Telegram integration is working.")
|
|
}
|
|
|
|
// NotifyNewOrder implements orders.OrderNotifier. It never returns an error
|
|
// to the caller: a broken/misconfigured Telegram integration must not
|
|
// prevent a customer's order from being created, so failures are only
|
|
// logged.
|
|
func (s *Service) NotifyNewOrder(ctx context.Context, summary string) {
|
|
s.notify(ctx, func(st *Settings) bool { return st.NotifyNewOrder }, summary)
|
|
}
|
|
|
|
func (s *Service) notify(ctx context.Context, shouldSend func(*Settings) bool, text string) {
|
|
settings, err := s.repo.Get(ctx)
|
|
if err != nil {
|
|
s.logger.Error("telegram: failed to load settings", "error", err)
|
|
return
|
|
}
|
|
if !settings.Enabled || !shouldSend(settings) {
|
|
return
|
|
}
|
|
if err := s.sender.Send(ctx, settings.BotToken, settings.ChatID, text); err != nil {
|
|
s.logger.Error("telegram: failed to send notification", "error", err)
|
|
}
|
|
}
|