Files
transmission-telegram/internal/bot/bot.go

139 lines
3.9 KiB
Go

package bot
import (
"context"
"strings"
tgbotapi "gopkg.in/telegram-bot-api.v4"
"transmission-telegram/internal/config"
"transmission-telegram/internal/logger"
transmissionClient "transmission-telegram/internal/transmission"
)
// Bot represents the Telegram bot
type Bot struct {
api *tgbotapi.BotAPI
client transmissionClient.Client
cfg *config.Config
logger *logger.Logger
updates <-chan tgbotapi.Update
}
// NewBot creates a new bot instance
func NewBot(api *tgbotapi.BotAPI, client transmissionClient.Client, cfg *config.Config, log *logger.Logger, updates <-chan tgbotapi.Update) *Bot {
return &Bot{
api: api,
client: client,
cfg: cfg,
logger: log,
updates: updates,
}
}
// Run starts the bot's main loop
func (b *Bot) Run(ctx context.Context) {
for {
select {
case <-ctx.Done():
return
case update := <-b.updates:
b.handleUpdate(update)
}
}
}
// SendMessage sends a message to a chat
func (b *Bot) SendMessage(chatID int64, text string, markdown bool) int {
return sendMessage(b.api, chatID, text, markdown)
}
// handleUpdate processes a Telegram update
func (b *Bot) handleUpdate(update tgbotapi.Update) {
if update.Message == nil {
return
}
// Check if user is master
if !b.cfg.IsMaster(update.Message.From.UserName) {
b.logger.Printf("[INFO] Ignored a message from: %s", update.Message.From.String())
return
}
// Tokenize the update
tokens := strings.Split(update.Message.Text, " ")
// Preprocess message based on URL schema
if len(tokens) > 0 && (strings.HasPrefix(tokens[0], "magnet") || strings.HasPrefix(tokens[0], "http")) {
tokens = append([]string{"add"}, tokens...)
}
command := strings.ToLower(tokens[0])
// Route to appropriate handler
switch command {
case "list", "/list", "li", "/li", "/ls", "ls":
go b.handleList(update, tokens[1:])
case "head", "/head", "he", "/he":
go b.handleHead(update, tokens[1:])
case "tail", "/tail", "ta", "/ta":
go b.handleTail(update, tokens[1:])
case "downs", "/downs", "dg", "/dg":
go b.handleDowns(update)
case "seeding", "/seeding", "sd", "/sd":
go b.handleSeeding(update)
case "paused", "/paused", "pa", "/pa":
go b.handlePaused(update)
case "checking", "/checking", "ch", "/ch":
go b.handleChecking(update)
case "active", "/active", "ac", "/ac":
go b.handleActive(update)
case "errors", "/errors", "er", "/er":
go b.handleErrors(update)
case "sort", "/sort", "so", "/so":
go b.handleSort(update, tokens[1:])
case "trackers", "/trackers", "tr", "/tr":
go b.handleTrackers(update)
case "downloaddir", "dd":
go b.handleDownloadDir(update, tokens[1:])
case "add", "/add", "ad", "/ad":
go b.handleAdd(update, tokens[1:])
case "search", "/search", "se", "/se":
go b.handleSearch(update, tokens[1:])
case "latest", "/latest", "la", "/la":
go b.handleLatest(update, tokens[1:])
case "info", "/info", "in", "/in":
go b.handleInfo(update, tokens[1:])
case "stop", "/stop", "sp", "/sp":
go b.handleStop(update, tokens[1:])
case "start", "/start", "st", "/st":
go b.handleStart(update, tokens[1:])
case "check", "/check", "ck", "/ck":
go b.handleCheck(update, tokens[1:])
case "stats", "/stats", "sa", "/sa":
go b.handleStats(update)
case "downlimit", "dl":
go b.handleDownLimit(update, tokens[1:])
case "uplimit", "ul":
go b.handleUpLimit(update, tokens[1:])
case "speed", "/speed", "ss", "/ss":
go b.handleSpeed(update)
case "count", "/count", "co", "/co":
go b.handleCount(update)
case "del", "/del", "rm", "/rm":
go b.handleDel(update, tokens[1:])
case "deldata", "/deldata":
go b.handleDelData(update, tokens[1:])
case "help", "/help":
go b.sendMessage(update.Message.Chat.ID, HelpText, true)
case "version", "/version", "ver", "/ver":
go b.handleVersion(update)
case "":
// might be a file received
go b.handleReceiveTorrent(update)
default:
// no such command
go b.sendMessage(update.Message.Chat.ID, "No such command, try /help", false)
}
}