initial commit
This commit is contained in:
11
Dockerfile
Normal file
11
Dockerfile
Normal 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
14
docker-compose.yml
Normal 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
5
go.mod
Normal 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
2
go.sum
Normal 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
120
main.go
Normal 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user