initial commit

This commit is contained in:
JkLondon
2025-07-30 18:32:35 +02:00
parent 9343ddef85
commit 5c56f44618
5 changed files with 152 additions and 0 deletions

11
Dockerfile Normal file
View File

@ -0,0 +1,11 @@
FROM golang:1.24.4 AS builder
WORKDIR /app
COPY . .
RUN go mod tidy && go build -o bot main.go
FROM debian:bookworm-slim
WORKDIR /app
RUN apt-get update && apt-get install -y ca-certificates && update-ca-certificates
COPY --from=builder /app/bot .
CMD ["./bot"]

14
docker-compose.yml Normal file
View File

@ -0,0 +1,14 @@
version: "3.9"
services:
todemon:
build: .
container_name: todemon
restart: always
env_file:
- .env
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"

5
go.mod Normal file
View File

@ -0,0 +1,5 @@
module git1337.ilyamikheev.com/ilyam/todemon
go 1.24.4
require github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1

2
go.sum Normal file
View File

@ -0,0 +1,2 @@
github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1 h1:wG8n/XJQ07TmjbITcGiUaOtXxdrINDz1b0J1w0SzqDc=
github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1/go.mod h1:A2S0CWkNylc2phvKXWBBdD3K0iGnDBGbzRpISP2zBl8=

120
main.go Normal file
View File

@ -0,0 +1,120 @@
package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
"os"
"strings"
"time"
tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5"
)
type Task struct {
ID string `json:"id"`
Content string `json:"content"`
Due *struct {
Date string `json:"date"`
} `json:"due"`
}
var (
todoistToken = os.Getenv("TODOIST_TOKEN")
telegramToken = os.Getenv("TELEGRAM_TOKEN")
chatID = os.Getenv("CHAT_ID")
bot *tgbotapi.BotAPI
overdueTasks = map[string]bool{}
)
func getOverdueTasks() []Task {
log.Println("[INFO] Запрашиваю задачи из Todoist...")
req, _ := http.NewRequest("GET", "https://api.todoist.com/rest/v2/tasks", nil)
req.Header.Set("Authorization", "Bearer "+todoistToken)
resp, err := http.DefaultClient.Do(req)
if err != nil {
log.Println("Ошибка запроса Todoist:", err)
return nil
}
defer resp.Body.Close()
var tasks []Task
if err := json.NewDecoder(resp.Body).Decode(&tasks); err != nil {
log.Println("Ошибка парсинга задач:", err)
return nil
}
now := time.Now().Format("2006-01-02T15:04")
var overdue []Task
for _, task := range tasks {
if task.Due != nil && strings.Compare(task.Due.Date, now) < 0 {
overdue = append(overdue, task)
}
}
return overdue
}
func closeTask(taskID string) {
url := fmt.Sprintf("https://api.todoist.com/rest/v2/tasks/%s/close", taskID)
req, _ := http.NewRequest("POST", url, nil)
req.Header.Set("Authorization", "Bearer "+todoistToken)
http.DefaultClient.Do(req)
}
func spamCheck() {
tasks := getOverdueTasks()
for _, task := range tasks {
if !overdueTasks[task.ID] {
msg := tgbotapi.NewMessage(toInt64(chatID), fmt.Sprintf("🔥 Просрочено: %s", task.Content))
button := tgbotapi.NewInlineKeyboardMarkup(
tgbotapi.NewInlineKeyboardRow(
tgbotapi.NewInlineKeyboardButtonData("✅ Сделал", task.ID),
),
)
msg.ReplyMarkup = button
bot.Send(msg)
overdueTasks[task.ID] = true
} else {
bot.Send(tgbotapi.NewMessage(toInt64(chatID), "⏰ Ну что, сделал уже?!"))
}
}
}
func toInt64(s string) int64 {
var n int64
fmt.Sscan(s, &n)
return n
}
func main() {
var err error
bot, err = tgbotapi.NewBotAPI(telegramToken)
if err != nil {
log.Fatal("Ошибка запуска бота:", err)
}
log.Println("[INFO] Бот запущен")
u := tgbotapi.NewUpdate(0)
u.Timeout = 60
updates := bot.GetUpdatesChan(u)
ticker := time.NewTicker(1 * time.Hour)
go func() {
spamCheck()
for range ticker.C {
spamCheck()
}
}()
for update := range updates {
if update.CallbackQuery != nil {
taskID := update.CallbackQuery.Data
closeTask(taskID)
bot.Send(tgbotapi.NewMessage(update.CallbackQuery.Message.Chat.ID, "✅ Задача закрыта!"))
delete(overdueTasks, taskID)
}
}
}