Move monitoring PF infrastructure to Go
This commit is contained in:
187
cmd/bot/main.go
Normal file
187
cmd/bot/main.go
Normal file
@@ -0,0 +1,187 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"os"
|
||||
"os/signal"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"monitoring-pf/internal/pf"
|
||||
)
|
||||
|
||||
func main() {
|
||||
cfg := pf.LoadConfig()
|
||||
logger := slog.New(slog.NewJSONHandler(os.Stdout, nil))
|
||||
slog.SetDefault(logger)
|
||||
|
||||
ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
|
||||
defer stop()
|
||||
|
||||
app, err := pf.OpenApp(ctx, cfg)
|
||||
if err != nil {
|
||||
slog.Error("db_open_failed", "error", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
defer app.Close()
|
||||
if !app.TG.Enabled() {
|
||||
slog.Error("telegram_token_missing")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
slog.Info("monitoring_pf_go_bot_started")
|
||||
var offset int64
|
||||
for ctx.Err() == nil {
|
||||
updates, err := app.TG.GetUpdates(ctx, offset)
|
||||
if err != nil {
|
||||
slog.Warn("telegram_get_updates_failed", "error", err)
|
||||
time.Sleep(3 * time.Second)
|
||||
continue
|
||||
}
|
||||
for _, update := range updates {
|
||||
offset = update.UpdateID + 1
|
||||
if update.Message != nil {
|
||||
handleMessage(ctx, app, update.Message)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func handleMessage(ctx context.Context, app *pf.App, msg *pf.TGMessage) {
|
||||
text := strings.TrimSpace(msg.Text)
|
||||
if text == "" || !strings.HasPrefix(text, "/") {
|
||||
return
|
||||
}
|
||||
command, arg := splitCommand(text)
|
||||
switch command {
|
||||
case "/start":
|
||||
handleStart(ctx, app, msg, arg)
|
||||
case "/whoami":
|
||||
handleWhoami(ctx, app, msg)
|
||||
case "/list":
|
||||
handleList(ctx, app, msg)
|
||||
case "/check":
|
||||
handleCheck(ctx, app, msg)
|
||||
}
|
||||
}
|
||||
|
||||
func splitCommand(text string) (string, string) {
|
||||
parts := strings.Fields(text)
|
||||
if len(parts) == 0 {
|
||||
return "", ""
|
||||
}
|
||||
command := strings.Split(parts[0], "@")[0]
|
||||
arg := ""
|
||||
if len(parts) > 1 {
|
||||
arg = parts[1]
|
||||
}
|
||||
return command, arg
|
||||
}
|
||||
|
||||
func handleStart(ctx context.Context, app *pf.App, msg *pf.TGMessage, portalUserID string) {
|
||||
chatID := strconv.FormatInt(msg.Chat.ID, 10)
|
||||
user := msg.From
|
||||
username := ""
|
||||
name := "user_" + chatID
|
||||
if user != nil {
|
||||
username = user.Username
|
||||
name = user.FullName()
|
||||
}
|
||||
if portalUserID == "" {
|
||||
_ = app.TG.SendMessage(ctx, chatID,
|
||||
"Откройте Portal → Мониторинг PF и нажмите подключение Telegram.\n"+
|
||||
"Бот должен получить команду вида:\n<code>/start ваш_код_из_Portal</code>")
|
||||
return
|
||||
}
|
||||
emp, err := app.LinkTelegram(ctx, portalUserID, chatID, username, name)
|
||||
if err != nil {
|
||||
_ = app.TG.SendMessage(ctx, chatID, "Не удалось подключить Telegram: "+err.Error())
|
||||
return
|
||||
}
|
||||
_ = app.TG.SendMessage(ctx, chatID,
|
||||
fmt.Sprintf("✅ Привет, <b>%s</b>! Telegram подключен к вашему аккаунту Portal.\nТеперь можно добавлять объекты мониторинга в Portal.", emp.Name))
|
||||
}
|
||||
|
||||
func handleWhoami(ctx context.Context, app *pf.App, msg *pf.TGMessage) {
|
||||
chatID := strconv.FormatInt(msg.Chat.ID, 10)
|
||||
emp, err := app.EmployeeByChatID(ctx, chatID)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
_ = app.TG.SendMessage(ctx, chatID, "Вы пока не подключены. Откройте Portal → Мониторинг PF и запустите подключение.\nchat_id: <code>"+chatID+"</code>")
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
_ = app.TG.SendMessage(ctx, chatID, "Ошибка: "+err.Error())
|
||||
return
|
||||
}
|
||||
_ = app.TG.SendMessage(ctx, chatID, fmt.Sprintf("Вы: <b>%s</b>\nchat_id: <code>%s</code>", emp.Name, chatID))
|
||||
}
|
||||
|
||||
func handleList(ctx context.Context, app *pf.App, msg *pf.TGMessage) {
|
||||
chatID := strconv.FormatInt(msg.Chat.ID, 10)
|
||||
emp, err := app.EmployeeByChatID(ctx, chatID)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
_ = app.TG.SendMessage(ctx, chatID, "Сначала подключитесь через Portal → Мониторинг PF.")
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
_ = app.TG.SendMessage(ctx, chatID, "Ошибка: "+err.Error())
|
||||
return
|
||||
}
|
||||
projects, err := app.ListProjects(ctx, emp.ID)
|
||||
if err != nil {
|
||||
_ = app.TG.SendMessage(ctx, chatID, "Ошибка: "+err.Error())
|
||||
return
|
||||
}
|
||||
if len(projects) == 0 {
|
||||
_ = app.TG.SendMessage(ctx, chatID, "У вас пока нет проектов.")
|
||||
return
|
||||
}
|
||||
lines := []string{fmt.Sprintf("<b>Ваши проекты (%d):</b>", len(projects))}
|
||||
for _, p := range projects {
|
||||
permit := "—"
|
||||
if p.DLDPermit != nil {
|
||||
permit = *p.DLDPermit
|
||||
}
|
||||
lines = append(lines, fmt.Sprintf("• #%d %s — <code>%s</code> (%s)", p.ID, p.Title, permit, p.DealType))
|
||||
}
|
||||
_ = app.TG.SendMessage(ctx, chatID, strings.Join(lines, "\n"))
|
||||
}
|
||||
|
||||
func handleCheck(ctx context.Context, app *pf.App, msg *pf.TGMessage) {
|
||||
chatID := strconv.FormatInt(msg.Chat.ID, 10)
|
||||
emp, err := app.EmployeeByChatID(ctx, chatID)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
_ = app.TG.SendMessage(ctx, chatID, "Сначала подключитесь через Portal → Мониторинг PF.")
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
_ = app.TG.SendMessage(ctx, chatID, "Ошибка: "+err.Error())
|
||||
return
|
||||
}
|
||||
projects, err := app.ListProjects(ctx, emp.ID)
|
||||
if err != nil {
|
||||
_ = app.TG.SendMessage(ctx, chatID, "Ошибка: "+err.Error())
|
||||
return
|
||||
}
|
||||
if len(projects) == 0 {
|
||||
_ = app.TG.SendMessage(ctx, chatID, "У вас нет проектов.")
|
||||
return
|
||||
}
|
||||
_ = app.TG.SendMessage(ctx, chatID, fmt.Sprintf("⏳ Запускаю проверку %d проектов…", len(projects)))
|
||||
total := 0
|
||||
for _, p := range projects {
|
||||
changes, err := app.Worker.CheckProject(ctx, p.ID)
|
||||
if err != nil {
|
||||
slog.Warn("check_project_failed", "project_id", p.ID, "error", err)
|
||||
continue
|
||||
}
|
||||
total += changes
|
||||
}
|
||||
_ = app.TG.SendMessage(ctx, chatID, fmt.Sprintf("✅ Готово. Изменений: %d", total))
|
||||
}
|
||||
Reference in New Issue
Block a user