261 lines
7.0 KiB
Go
261 lines
7.0 KiB
Go
package bot
|
||
|
||
import (
|
||
"fmt"
|
||
"strconv"
|
||
"strings"
|
||
"time"
|
||
|
||
tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5"
|
||
"github.com/daniil/homelab-api/internal/model"
|
||
"github.com/daniil/homelab-api/internal/repository"
|
||
)
|
||
|
||
func (b *Bot) handleMessage(msg *tgbotapi.Message) {
|
||
if !msg.IsCommand() {
|
||
return
|
||
}
|
||
|
||
switch msg.Command() {
|
||
case "start":
|
||
b.handleStart(msg)
|
||
case "tasks":
|
||
b.handleTasks(msg)
|
||
case "habits":
|
||
b.handleHabits(msg)
|
||
case "done":
|
||
b.handleDone(msg)
|
||
case "check":
|
||
b.handleCheck(msg)
|
||
case "help":
|
||
b.handleHelp(msg)
|
||
}
|
||
}
|
||
|
||
func (b *Bot) handleStart(msg *tgbotapi.Message) {
|
||
text := fmt.Sprintf(`👋 Привет! Я бот Pulse.
|
||
|
||
Твой Chat ID: <code>%d</code>
|
||
|
||
Скопируй его и вставь в настройках Pulse для получения уведомлений.
|
||
|
||
Доступные команды:
|
||
/tasks — задачи на сегодня
|
||
/habits — привычки на сегодня
|
||
/done <id> — отметить задачу выполненной
|
||
/check <id> — отметить привычку выполненной
|
||
/help — справка`, msg.Chat.ID)
|
||
|
||
b.SendMessage(msg.Chat.ID, text)
|
||
}
|
||
|
||
func (b *Bot) handleHelp(msg *tgbotapi.Message) {
|
||
text := `📚 <b>Справка по командам:</b>
|
||
|
||
/start — получить твой Chat ID
|
||
/tasks — список задач на сегодня
|
||
/habits — список привычек
|
||
/done <id> — отметить задачу выполненной
|
||
/check <id> — отметить привычку выполненной
|
||
|
||
💡 Чтобы получать уведомления, добавь свой Chat ID в настройках Pulse.`
|
||
|
||
b.SendMessage(msg.Chat.ID, text)
|
||
}
|
||
|
||
func (b *Bot) handleTasks(msg *tgbotapi.Message) {
|
||
user, err := b.userRepo.GetByTelegramChatID(msg.Chat.ID)
|
||
if err != nil {
|
||
if err == repository.ErrUserNotFound {
|
||
b.SendMessage(msg.Chat.ID, "❌ Аккаунт не найден. Добавь свой Chat ID в настройках Pulse.")
|
||
return
|
||
}
|
||
b.SendMessage(msg.Chat.ID, "❌ Ошибка при получении данных")
|
||
return
|
||
}
|
||
|
||
tasks, err := b.taskRepo.GetTodayTasks(user.ID)
|
||
if err != nil {
|
||
b.SendMessage(msg.Chat.ID, "❌ Ошибка при получении задач")
|
||
return
|
||
}
|
||
|
||
if len(tasks) == 0 {
|
||
b.SendMessage(msg.Chat.ID, "✨ На сегодня задач нет!")
|
||
return
|
||
}
|
||
|
||
text := "📋 <b>Задачи на сегодня:</b>\n\n"
|
||
for _, task := range tasks {
|
||
priority := ""
|
||
switch task.Priority {
|
||
case 3:
|
||
priority = "🔴 "
|
||
case 2:
|
||
priority = "🟡 "
|
||
case 1:
|
||
priority = "🔵 "
|
||
}
|
||
text += fmt.Sprintf("%s%s <b>%s</b>\n", priority, task.Icon, task.Title)
|
||
if task.Description != "" {
|
||
text += fmt.Sprintf(" <i>%s</i>\n", task.Description)
|
||
}
|
||
text += fmt.Sprintf(" /done_%d\n\n", task.ID)
|
||
}
|
||
|
||
b.SendMessage(msg.Chat.ID, text)
|
||
}
|
||
|
||
func (b *Bot) handleHabits(msg *tgbotapi.Message) {
|
||
user, err := b.userRepo.GetByTelegramChatID(msg.Chat.ID)
|
||
if err != nil {
|
||
if err == repository.ErrUserNotFound {
|
||
b.SendMessage(msg.Chat.ID, "❌ Аккаунт не найден. Добавь свой Chat ID в настройках Pulse.")
|
||
return
|
||
}
|
||
b.SendMessage(msg.Chat.ID, "❌ Ошибка при получении данных")
|
||
return
|
||
}
|
||
|
||
habits, err := b.habitRepo.ListByUser(user.ID, false)
|
||
if err != nil {
|
||
b.SendMessage(msg.Chat.ID, "❌ Ошибка при получении привычек")
|
||
return
|
||
}
|
||
|
||
if len(habits) == 0 {
|
||
b.SendMessage(msg.Chat.ID, "✨ У тебя пока нет привычек!")
|
||
return
|
||
}
|
||
|
||
// Filter habits for today
|
||
today := int(time.Now().Weekday())
|
||
var todayHabits []model.Habit
|
||
for _, habit := range habits {
|
||
if habit.Frequency == "daily" {
|
||
todayHabits = append(todayHabits, habit)
|
||
} else {
|
||
for _, day := range habit.TargetDays {
|
||
if day == today {
|
||
todayHabits = append(todayHabits, habit)
|
||
break
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
if len(todayHabits) == 0 {
|
||
b.SendMessage(msg.Chat.ID, "✨ На сегодня привычек нет!")
|
||
return
|
||
}
|
||
|
||
text := "🎯 <b>Привычки на сегодня:</b>\n\n"
|
||
for _, habit := range todayHabits {
|
||
completed, _ := b.habitRepo.IsHabitCompletedToday(habit.ID, user.ID)
|
||
status := "⬜"
|
||
if completed {
|
||
status = "✅"
|
||
}
|
||
text += fmt.Sprintf("%s %s <b>%s</b>\n", status, habit.Icon, habit.Name)
|
||
if habit.Description != "" {
|
||
text += fmt.Sprintf(" <i>%s</i>\n", habit.Description)
|
||
}
|
||
if !completed {
|
||
text += fmt.Sprintf(" /check_%d\n", habit.ID)
|
||
}
|
||
text += "\n"
|
||
}
|
||
|
||
b.SendMessage(msg.Chat.ID, text)
|
||
}
|
||
|
||
func (b *Bot) handleDone(msg *tgbotapi.Message) {
|
||
user, err := b.userRepo.GetByTelegramChatID(msg.Chat.ID)
|
||
if err != nil {
|
||
b.SendMessage(msg.Chat.ID, "❌ Аккаунт не найден")
|
||
return
|
||
}
|
||
|
||
// Parse task ID from command argument or from command like /done_123
|
||
var taskID int64
|
||
args := msg.CommandArguments()
|
||
if args != "" {
|
||
taskID, _ = strconv.ParseInt(args, 10, 64)
|
||
} else {
|
||
// Try to parse from command like /done_123
|
||
cmd := msg.Command()
|
||
if strings.HasPrefix(cmd, "done_") {
|
||
taskID, _ = strconv.ParseInt(strings.TrimPrefix(cmd, "done_"), 10, 64)
|
||
}
|
||
}
|
||
|
||
if taskID == 0 {
|
||
b.SendMessage(msg.Chat.ID, "❌ Укажи ID задачи: /done <id>")
|
||
return
|
||
}
|
||
|
||
err = b.taskRepo.Complete(taskID, user.ID)
|
||
if err != nil {
|
||
if err == repository.ErrTaskNotFound {
|
||
b.SendMessage(msg.Chat.ID, "❌ Задача не найдена")
|
||
return
|
||
}
|
||
b.SendMessage(msg.Chat.ID, "❌ Ошибка при выполнении задачи")
|
||
return
|
||
}
|
||
|
||
b.SendMessage(msg.Chat.ID, "✅ Задача выполнена!")
|
||
}
|
||
|
||
func (b *Bot) handleCheck(msg *tgbotapi.Message) {
|
||
user, err := b.userRepo.GetByTelegramChatID(msg.Chat.ID)
|
||
if err != nil {
|
||
b.SendMessage(msg.Chat.ID, "❌ Аккаунт не найден")
|
||
return
|
||
}
|
||
|
||
// Parse habit ID from command argument or from command like /check_123
|
||
var habitID int64
|
||
args := msg.CommandArguments()
|
||
if args != "" {
|
||
habitID, _ = strconv.ParseInt(args, 10, 64)
|
||
} else {
|
||
// Try to parse from command like /check_123
|
||
cmd := msg.Command()
|
||
if strings.HasPrefix(cmd, "check_") {
|
||
habitID, _ = strconv.ParseInt(strings.TrimPrefix(cmd, "check_"), 10, 64)
|
||
}
|
||
}
|
||
|
||
if habitID == 0 {
|
||
b.SendMessage(msg.Chat.ID, "❌ Укажи ID привычки: /check <id>")
|
||
return
|
||
}
|
||
|
||
// Verify habit exists and belongs to user
|
||
_, err = b.habitRepo.GetByID(habitID, user.ID)
|
||
if err != nil {
|
||
if err == repository.ErrHabitNotFound {
|
||
b.SendMessage(msg.Chat.ID, "❌ Привычка не найдена")
|
||
return
|
||
}
|
||
b.SendMessage(msg.Chat.ID, "❌ Ошибка при получении привычки")
|
||
return
|
||
}
|
||
|
||
// Create log for today
|
||
log := &model.HabitLog{
|
||
HabitID: habitID,
|
||
UserID: user.ID,
|
||
Date: time.Now(),
|
||
Count: 1,
|
||
}
|
||
err = b.habitRepo.CreateLog(log)
|
||
if err != nil {
|
||
b.SendMessage(msg.Chat.ID, "❌ Ошибка при отметке привычки")
|
||
return
|
||
}
|
||
|
||
b.SendMessage(msg.Chat.ID, "✅ Привычка отмечена!")
|
||
}
|