package notification import ( "bytes" "fmt" "os" "strconv" "text/template" "git.ctrlz.es/mgdelacroix/birthdaybot/model" "git.ctrlz.es/mgdelacroix/birthdaybot/utils" "github.com/charmbracelet/log" tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5" ) type TelegramNotificationService struct { logger *log.Logger config *model.Config bot *tgbotapi.BotAPI } func NewTelegramNotificationService(logger *log.Logger, config *model.Config) (*TelegramNotificationService, error) { bot, err := tgbotapi.NewBotAPI(config.TelegramNotifications.BotToken) if err != nil { return nil, fmt.Errorf("cannot create bot: %w", err) } botUser, err := bot.GetMe() if err != nil { return nil, fmt.Errorf("cannot get bot information: %w", err) } logger.Info("telegram bot initialized", "id", botUser.ID, "username", botUser.UserName) return &TelegramNotificationService{ logger: logger, config: config, bot: bot, }, nil } func (tns *TelegramNotificationService) Notify(birthday *model.Birthday, template *template.Template) error { var msgText string if template != nil { var stringBuffer bytes.Buffer if err := template.Execute(&stringBuffer, birthday.ToMap()); err != nil { return fmt.Errorf("cannot execute template for birthday: %w", err) } msgText = stringBuffer.String() } else { msgText = fmt.Sprintf("It's %s's birthday! You can reach them out at %s or %s", birthday.Name, birthday.Email, birthday.Phone) } chatID, err := strconv.Atoi(tns.config.TelegramNotifications.ChannelID) if err != nil { return fmt.Errorf("cannot parse ChannelID: %w", err) } picture, err := utils.GetPictureForBirthday(birthday, tns.config.Birthdays.Pictures) if err != nil && !os.IsNotExist(err) { return fmt.Errorf("cannot get picture for birthday: %w", err) } var msg tgbotapi.Chattable if picture == "" { msg = tgbotapi.NewMessage(int64(chatID), msgText) } else { photo := tgbotapi.NewPhoto(int64(chatID), tgbotapi.FilePath(picture)) photo.Caption = msgText msg = photo } if _, err := tns.bot.Send(msg); err != nil { return fmt.Errorf("error sending message: %w", err) } return nil }