MiniappGoService/internal/infrastructure/botService/bot.go

98 lines
2.6 KiB
Go

package botService
import (
"log"
"net/http"
"os"
"os/signal"
"syscall"
"time"
"gitea.cybertalant.ru/VisionCareerMiniapp/MiniappGoService/internal/config"
tele "gopkg.in/telebot.v4"
)
func Start(
botCfg *config.Bot,
loggerInstance loggerInstance,
pgDBInstance pgDBInstance,
supportAPIInstance supportAPIInstance,
) error {
// Create bot instance with optimized settings
bot, err := tele.NewBot(tele.Settings{
Token: botCfg.BotToken,
// Optimal number of updates for high load
Updates: 100,
// Asynchronous processing for maximum performance
Synchronous: false,
// Error handler with error type separation
OnError: func(err error, c tele.Context) {
// Filter out common API errors to avoid log spam
if c == nil {
log.Printf("🚨 Critical error: %v", err)
return
}
log.Printf("⚠️ Error in update: %v (Chat: %d)", err, c.Chat().ID)
},
// Telegram API URL
URL: "https://api.telegram.org",
// HTTP client with performance optimizations
Client: &http.Client{
Timeout: 30 * time.Second, // Reduced from 50s for faster failover
Transport: &http.Transport{
MaxIdleConns: 100, // Increased for better connection reuse
MaxIdleConnsPerHost: 20, // Added for connection pooling
IdleConnTimeout: 90 * time.Second, // Reduced for faster cleanup
MaxConnsPerHost: 50, // Added to limit connections per host
},
},
// Default parse mode for messages
ParseMode: tele.ModeHTML,
// Long poller configuration
Poller: &tele.LongPoller{
Timeout: 10 * time.Second, // Reduced timeout for faster update retrieval
AllowedUpdates: []string{
"message", // text messages
"callback_query", // callback from buttons
"inline_query", // inline queries
"chosen_inline_result", // chosen inline result
"edited_message", // edited messages
},
},
})
if err != nil {
return err
}
// Add global middlewares
// Create repositories
// Create services
// Create handlers
// Start cron jobs
// Create channels for graceful shutdown
errChan := make(chan error, 1)
quit := make(chan os.Signal, 1)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
// Start bot in goroutine
go func() {
log.Println("🤖 Starting Telegram bot...")
bot.Start()
}()
// Wait for shutdown signal or error
select {
case <-quit:
log.Println("🛑 Received shutdown signal, stopping bot...")
bot.Stop()
log.Println("✅ Bot stopped gracefully")
return nil
case err := <-errChan:
log.Printf("❌ Bot error: %v", err)
return err
}
}