refactor: migrate from go-telegram-bot-api/v5 to go-telegram/bot

- Replaced tgbotapi with go-telegram/bot (zero-dependency, context-aware, Bot API 10.0)
- All handler methods now accept context.Context; threading ctx through all sends/edits
- Changed from function-based (NewMessage/NewEditMessageText/NewInlineKeyboardMarkup) to struct-param API (SendMessageParams/EditMessageTextParams/InlineKeyboardMarkup)
- Added colored buttons: DEL buttons in calendar use Style: 'danger' (red)
- Both polling and webhook modes preserved with new library patterns
- Context-based shutdown (signal.NotifyContext) replaces stop channel
This commit is contained in:
2026-06-24 14:56:50 +03:30
parent fb2d0ef7d1
commit 49c0e82bac
9 changed files with 581 additions and 580 deletions

View File

@@ -1,11 +1,13 @@
package bot
import (
"context"
"fmt"
"log/slog"
"time"
tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5"
bot "github.com/go-telegram/bot"
"github.com/go-telegram/bot/models"
"worktimeBot/internal/db"
)
@@ -54,13 +56,33 @@ func (h *Handler) buildStatusText(chatID int64) string {
}
// backToMenu returns to the main menu from any sub-menu.
func (h *Handler) backToMenu(chatID int64, msgID int, callbackID string) {
defer h.Bot.Request(tgbotapi.NewCallback(callbackID, ""))
func (h *Handler) backToMenu(ctx context.Context, chatID int64, msgID int, callbackID string) {
defer h.Bot.AnswerCallbackQuery(ctx, &bot.AnswerCallbackQueryParams{CallbackQueryID: callbackID})
text := h.buildStatusText(chatID)
edit := tgbotapi.NewEditMessageText(chatID, msgID, text)
kb := mainKeyboard()
edit.ReplyMarkup = &kb
h.Bot.Send(edit)
h.Bot.EditMessageText(ctx, &bot.EditMessageTextParams{
ChatID: chatID,
MessageID: msgID,
Text: text,
ReplyMarkup: &models.InlineKeyboardMarkup{
InlineKeyboard: [][]models.InlineKeyboardButton{
{
{Text: "Clock In", CallbackData: "clockin"},
{Text: "Clock Out", CallbackData: "clockout"},
},
{
{Text: "Work Type", CallbackData: "worktype"},
{Text: "Day Off", CallbackData: "dayoff"},
},
{
{Text: "Report", CallbackData: "report"},
{Text: "Export", CallbackData: "export"},
},
{
{Text: "Settings", CallbackData: "settings"},
},
},
},
})
}
// buildDailyReport builds a formatted daily report string for a given user/day.
@@ -119,7 +141,7 @@ func (h *Handler) buildDailyReport(user *db.User, day *db.Day, events []db.Event
}
// SendDailyReport sends the automated daily report to the user.
func (h *Handler) SendDailyReport(userID int64, chatID int64) {
func (h *Handler) SendDailyReport(ctx context.Context, userID int64, chatID int64) {
user, err := h.DB.GetUserByChatID(chatID)
if err != nil {
slog.Error("daily report: user not found", "user_id", userID)
@@ -143,7 +165,6 @@ func (h *Handler) SendDailyReport(userID int64, chatID int64) {
return
}
text := h.buildDailyReport(user, day, events)
reply := tgbotapi.NewMessage(chatID, text)
h.Bot.Send(reply)
h.Bot.SendMessage(ctx, &bot.SendMessageParams{ChatID: chatID, Text: text})
h.DB.MarkReportSent(user.ID, today)
}