Add basic telegram bot
This commit is contained in:
@@ -19,3 +19,7 @@ S3_ENDPOINT=
|
|||||||
YANDEX_CLOUD_API_KEY=your_api_key_here
|
YANDEX_CLOUD_API_KEY=your_api_key_here
|
||||||
# ID папки в Yandex Cloud (получить в консоли Yandex Cloud)
|
# ID папки в Yandex Cloud (получить в консоли Yandex Cloud)
|
||||||
YANDEX_CLOUD_FOLDER_ID=your_folder_id_here
|
YANDEX_CLOUD_FOLDER_ID=your_folder_id_here
|
||||||
|
|
||||||
|
# Telegram Bot Configuration
|
||||||
|
# Токен Telegram бота (получить у @BotFather в Telegram)
|
||||||
|
TELEGRAM_BOT_TOKEN=your_telegram_bot_token_here
|
||||||
|
1
go.mod
1
go.mod
@@ -10,6 +10,7 @@ require (
|
|||||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.86.0
|
github.com/aws/aws-sdk-go-v2/service/s3 v1.86.0
|
||||||
github.com/doug-martin/goqu/v9 v9.19.0
|
github.com/doug-martin/goqu/v9 v9.19.0
|
||||||
github.com/gin-gonic/gin v1.10.1
|
github.com/gin-gonic/gin v1.10.1
|
||||||
|
github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1
|
||||||
github.com/google/uuid v1.6.0
|
github.com/google/uuid v1.6.0
|
||||||
github.com/joho/godotenv v1.5.1
|
github.com/joho/godotenv v1.5.1
|
||||||
github.com/mattn/go-sqlite3 v1.14.17
|
github.com/mattn/go-sqlite3 v1.14.17
|
||||||
|
2
go.sum
2
go.sum
@@ -77,6 +77,8 @@ github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91
|
|||||||
github.com/go-playground/validator/v10 v10.22.0 h1:k6HsTZ0sTnROkhS//R0O+55JgM8C4Bx7ia+JlgcnOao=
|
github.com/go-playground/validator/v10 v10.22.0 h1:k6HsTZ0sTnROkhS//R0O+55JgM8C4Bx7ia+JlgcnOao=
|
||||||
github.com/go-playground/validator/v10 v10.22.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
|
github.com/go-playground/validator/v10 v10.22.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
|
||||||
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||||
|
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=
|
||||||
github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA=
|
github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA=
|
||||||
github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
||||||
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
|
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
|
||||||
|
328
internal/controller/tg/tg.go
Normal file
328
internal/controller/tg/tg.go
Normal file
@@ -0,0 +1,328 @@
|
|||||||
|
package tg
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"log/slog"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"git.vakhrushev.me/av/transcriber/internal/contract"
|
||||||
|
"git.vakhrushev.me/av/transcriber/internal/service"
|
||||||
|
tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5"
|
||||||
|
)
|
||||||
|
|
||||||
|
type TelegramController struct {
|
||||||
|
bot *tgbotapi.BotAPI
|
||||||
|
transcribeService *service.TranscribeService
|
||||||
|
jobRepo contract.TranscriptJobRepository
|
||||||
|
logger *slog.Logger
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewTelegramController(transcribeService *service.TranscribeService, jobRepo contract.TranscriptJobRepository, logger *slog.Logger) (*TelegramController, error) {
|
||||||
|
botToken := os.Getenv("TELEGRAM_BOT_TOKEN")
|
||||||
|
if botToken == "" {
|
||||||
|
return nil, &EmptyBotTokenError{}
|
||||||
|
}
|
||||||
|
|
||||||
|
bot, err := tgbotapi.NewBotAPI(botToken)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
controller := &TelegramController{
|
||||||
|
bot: bot,
|
||||||
|
transcribeService: transcribeService,
|
||||||
|
jobRepo: jobRepo,
|
||||||
|
logger: logger,
|
||||||
|
}
|
||||||
|
|
||||||
|
return controller, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *TelegramController) Start() {
|
||||||
|
c.logger.Info("Telegram bot started", "username", c.bot.Self.UserName)
|
||||||
|
|
||||||
|
u := tgbotapi.NewUpdate(0)
|
||||||
|
u.Timeout = 60
|
||||||
|
|
||||||
|
updates := c.bot.GetUpdatesChan(u)
|
||||||
|
|
||||||
|
for update := range updates {
|
||||||
|
if update.Message == nil { // ignore any non-Message updates
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle commands
|
||||||
|
if update.Message.IsCommand() {
|
||||||
|
// Extract the command from the Message
|
||||||
|
switch update.Message.Command() {
|
||||||
|
case "start":
|
||||||
|
c.handleStartCommand(update.Message)
|
||||||
|
case "help":
|
||||||
|
c.handleHelpCommand(update.Message)
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle audio messages and files
|
||||||
|
if update.Message.Audio != nil {
|
||||||
|
c.handleAudioMessage(update.Message)
|
||||||
|
} else if update.Message.Voice != nil {
|
||||||
|
c.handleVoiceMessage(update.Message)
|
||||||
|
} else if update.Message.Document != nil {
|
||||||
|
c.handleDocumentMessage(update.Message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *TelegramController) Stop() {
|
||||||
|
c.logger.Info("Telegram bot stopped")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *TelegramController) handleStartCommand(message *tgbotapi.Message) {
|
||||||
|
msg := tgbotapi.NewMessage(message.Chat.ID, "Привет! Я бот для расшифровки аудиосообщений. Отправь мне голосовое сообщение или аудиофайл, и я пришлю тебе текст.")
|
||||||
|
msg.ReplyToMessageID = message.MessageID
|
||||||
|
|
||||||
|
c.bot.Send(msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *TelegramController) handleHelpCommand(message *tgbotapi.Message) {
|
||||||
|
helpText := `Я бот для расшифровки аудиосообщений и аудиофайлов.
|
||||||
|
|
||||||
|
Просто отправь мне:
|
||||||
|
- Голосовое сообщение
|
||||||
|
- Аудиофайл (mp3, wav, ogg и др.)
|
||||||
|
|
||||||
|
Я пришлю тебе текст расшифровки.
|
||||||
|
|
||||||
|
Команды:
|
||||||
|
/start - Начало работы с ботом
|
||||||
|
/help - Показать эту справку`
|
||||||
|
|
||||||
|
msg := tgbotapi.NewMessage(message.Chat.ID, helpText)
|
||||||
|
msg.ReplyToMessageID = message.MessageID
|
||||||
|
|
||||||
|
c.bot.Send(msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *TelegramController) handleAudioMessage(message *tgbotapi.Message) {
|
||||||
|
// Отправляем сообщение о начале обработки
|
||||||
|
progressMsg := tgbotapi.NewMessage(message.Chat.ID, "Обрабатываю аудиофайл...")
|
||||||
|
progressMsg.ReplyToMessageID = message.MessageID
|
||||||
|
sentProgressMsg, err := c.bot.Send(progressMsg)
|
||||||
|
if err != nil {
|
||||||
|
c.logger.Error("Failed to send progress message", "error", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Скачиваем файл
|
||||||
|
fileReader, fileName, err := c.downloadAudioFile(message.Audio.FileID)
|
||||||
|
if err != nil {
|
||||||
|
c.logger.Error("Failed to download audio file", "error", err)
|
||||||
|
errorMsg := tgbotapi.NewMessage(message.Chat.ID, "Ошибка при скачивании аудиофайла. Попробуйте еще раз.")
|
||||||
|
c.bot.Send(errorMsg)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer fileReader.Close()
|
||||||
|
|
||||||
|
// Обрабатываем файл
|
||||||
|
job, err := c.transcribeService.CreateTranscribeJob(fileReader, fileName)
|
||||||
|
if err != nil {
|
||||||
|
c.logger.Error("Failed to create transcribe job", "error", err)
|
||||||
|
errorMsg := tgbotapi.NewMessage(message.Chat.ID, "Ошибка при создании задачи на расшифровку. Попробуйте еще раз.")
|
||||||
|
c.bot.Send(errorMsg)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Отправляем сообщение об успешном создании задачи
|
||||||
|
successMsg := tgbotapi.NewMessage(message.Chat.ID, fmt.Sprintf("Задача на расшифровку создана. ID задачи: %s", job.Id))
|
||||||
|
successMsg.ReplyToMessageID = message.MessageID
|
||||||
|
c.bot.Send(successMsg)
|
||||||
|
|
||||||
|
// Отправляем результат расшифровки (асинхронно)
|
||||||
|
go c.sendTranscriptionResult(message.Chat.ID, job.Id, sentProgressMsg.MessageID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *TelegramController) handleVoiceMessage(message *tgbotapi.Message) {
|
||||||
|
// Отправляем сообщение о начале обработки
|
||||||
|
progressMsg := tgbotapi.NewMessage(message.Chat.ID, "Обрабатываю голосовое сообщение...")
|
||||||
|
progressMsg.ReplyToMessageID = message.MessageID
|
||||||
|
sentProgressMsg, err := c.bot.Send(progressMsg)
|
||||||
|
if err != nil {
|
||||||
|
c.logger.Error("Failed to send progress message", "error", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Скачиваем файл
|
||||||
|
fileReader, fileName, err := c.downloadAudioFile(message.Voice.FileID)
|
||||||
|
if err != nil {
|
||||||
|
c.logger.Error("Failed to download voice file", "error", err)
|
||||||
|
errorMsg := tgbotapi.NewMessage(message.Chat.ID, "Ошибка при скачивании голосового сообщения. Попробуйте еще раз.")
|
||||||
|
c.bot.Send(errorMsg)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer fileReader.Close()
|
||||||
|
|
||||||
|
// Обрабатываем файл
|
||||||
|
job, err := c.transcribeService.CreateTranscribeJob(fileReader, fileName)
|
||||||
|
if err != nil {
|
||||||
|
c.logger.Error("Failed to create transcribe job", "error", err)
|
||||||
|
errorMsg := tgbotapi.NewMessage(message.Chat.ID, "Ошибка при создании задачи на расшифровку. Попробуйте еще раз.")
|
||||||
|
c.bot.Send(errorMsg)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Отправляем сообщение об успешном создании задачи
|
||||||
|
successMsg := tgbotapi.NewMessage(message.Chat.ID, fmt.Sprintf("Задача на расшифровку создана. ID задачи: %s", job.Id))
|
||||||
|
successMsg.ReplyToMessageID = message.MessageID
|
||||||
|
c.bot.Send(successMsg)
|
||||||
|
|
||||||
|
// Отправляем результат расшифровки (асинхронно)
|
||||||
|
go c.sendTranscriptionResult(message.Chat.ID, job.Id, sentProgressMsg.MessageID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *TelegramController) handleDocumentMessage(message *tgbotapi.Message) {
|
||||||
|
// Проверяем, является ли документ аудиофайлом
|
||||||
|
if !c.isAudioDocument(message.Document) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Отправляем сообщение о начале обработки
|
||||||
|
progressMsg := tgbotapi.NewMessage(message.Chat.ID, "Обрабатываю аудиофайл...")
|
||||||
|
progressMsg.ReplyToMessageID = message.MessageID
|
||||||
|
sentProgressMsg, err := c.bot.Send(progressMsg)
|
||||||
|
if err != nil {
|
||||||
|
c.logger.Error("Failed to send progress message", "error", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Скачиваем файл
|
||||||
|
fileReader, fileName, err := c.downloadAudioFile(message.Document.FileID)
|
||||||
|
if err != nil {
|
||||||
|
c.logger.Error("Failed to download document file", "error", err)
|
||||||
|
errorMsg := tgbotapi.NewMessage(message.Chat.ID, "Ошибка при скачивании аудиофайла. Попробуйте еще раз.")
|
||||||
|
c.bot.Send(errorMsg)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer fileReader.Close()
|
||||||
|
|
||||||
|
// Обрабатываем файл
|
||||||
|
job, err := c.transcribeService.CreateTranscribeJob(fileReader, fileName)
|
||||||
|
if err != nil {
|
||||||
|
c.logger.Error("Failed to create transcribe job", "error", err)
|
||||||
|
errorMsg := tgbotapi.NewMessage(message.Chat.ID, "Ошибка при создании задачи на расшифровку. Попробуйте еще раз.")
|
||||||
|
c.bot.Send(errorMsg)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Отправляем сообщение об успешном создании задачи
|
||||||
|
successMsg := tgbotapi.NewMessage(message.Chat.ID, fmt.Sprintf("Задача на расшифровку создана. ID задачи: %s", job.Id))
|
||||||
|
successMsg.ReplyToMessageID = message.MessageID
|
||||||
|
c.bot.Send(successMsg)
|
||||||
|
|
||||||
|
// Отправляем результат расшифровки (асинхронно)
|
||||||
|
go c.sendTranscriptionResult(message.Chat.ID, job.Id, sentProgressMsg.MessageID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *TelegramController) downloadAudioFile(fileID string) (io.ReadCloser, string, error) {
|
||||||
|
// Получаем информацию о файле
|
||||||
|
file, err := c.bot.GetFile(tgbotapi.FileConfig{FileID: fileID})
|
||||||
|
if err != nil {
|
||||||
|
return nil, "", fmt.Errorf("failed to get file info: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Скачиваем файл
|
||||||
|
fileURL := file.Link(c.bot.Token)
|
||||||
|
resp, err := http.Get(fileURL)
|
||||||
|
if err != nil {
|
||||||
|
return nil, "", fmt.Errorf("failed to download file: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Получаем имя файла из URL
|
||||||
|
fileName := file.FilePath
|
||||||
|
if fileName == "" {
|
||||||
|
fileName = "audio.ogg"
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp.Body, fileName, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *TelegramController) sendTranscriptionResult(chatID int64, jobID string, progressMessageID int) {
|
||||||
|
// Периодически проверяем статус задачи
|
||||||
|
ticker := time.NewTicker(5 * time.Second)
|
||||||
|
defer ticker.Stop()
|
||||||
|
|
||||||
|
timeout := time.After(10 * time.Minute) // Максимальное время ожидания 10 минут
|
||||||
|
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-ticker.C:
|
||||||
|
// Проверяем статус задачи
|
||||||
|
job, err := c.jobRepo.GetByID(jobID)
|
||||||
|
if err != nil {
|
||||||
|
c.logger.Error("Failed to get job", "job_id", jobID, "error", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
switch job.State {
|
||||||
|
case "done":
|
||||||
|
// Отправляем результат
|
||||||
|
if job.TranscriptionText != nil {
|
||||||
|
resultMsg := tgbotapi.NewMessage(chatID, *job.TranscriptionText)
|
||||||
|
resultMsg.ReplyToMessageID = progressMessageID
|
||||||
|
c.bot.Send(resultMsg)
|
||||||
|
} else {
|
||||||
|
resultMsg := tgbotapi.NewMessage(chatID, "Расшифровка завершена, но текст пуст.")
|
||||||
|
resultMsg.ReplyToMessageID = progressMessageID
|
||||||
|
c.bot.Send(resultMsg)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
case "failed":
|
||||||
|
// Отправляем сообщение об ошибке
|
||||||
|
var errorMsg string
|
||||||
|
if job.ErrorText != nil {
|
||||||
|
errorMsg = fmt.Sprintf("Ошибка при расшифровке: %s", *job.ErrorText)
|
||||||
|
} else {
|
||||||
|
errorMsg = "Ошибка при расшифровке аудиофайла."
|
||||||
|
}
|
||||||
|
resultMsg := tgbotapi.NewMessage(chatID, errorMsg)
|
||||||
|
resultMsg.ReplyToMessageID = progressMessageID
|
||||||
|
c.bot.Send(resultMsg)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
case <-timeout:
|
||||||
|
// Время ожидания истекло
|
||||||
|
resultMsg := tgbotapi.NewMessage(chatID, "Время ожидания результата расшифровки истекло. Попробуйте позже проверить статус задачи.")
|
||||||
|
resultMsg.ReplyToMessageID = progressMessageID
|
||||||
|
c.bot.Send(resultMsg)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *TelegramController) isAudioDocument(document *tgbotapi.Document) bool {
|
||||||
|
// Проверяем MIME-тип документа
|
||||||
|
if document.MimeType != "" {
|
||||||
|
return strings.HasPrefix(document.MimeType, "audio/") || strings.HasPrefix(document.MimeType, "video/")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Проверяем расширение файла
|
||||||
|
audioExtensions := []string{".mp3", ".wav", ".ogg", ".flac", ".m4a", ".aac", ".wma"}
|
||||||
|
filename := document.FileName
|
||||||
|
for _, ext := range audioExtensions {
|
||||||
|
if len(filename) >= len(ext) && strings.ToLower(filename[len(filename)-len(ext):]) == ext {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
type EmptyBotTokenError struct{}
|
||||||
|
|
||||||
|
func (e *EmptyBotTokenError) Error() string {
|
||||||
|
return "telegram bot token is empty"
|
||||||
|
}
|
33
main.go
33
main.go
@@ -17,6 +17,7 @@ import (
|
|||||||
"git.vakhrushev.me/av/transcriber/internal/adapter/recognizer/yandex"
|
"git.vakhrushev.me/av/transcriber/internal/adapter/recognizer/yandex"
|
||||||
"git.vakhrushev.me/av/transcriber/internal/adapter/repo/sqlite"
|
"git.vakhrushev.me/av/transcriber/internal/adapter/repo/sqlite"
|
||||||
httpcontroller "git.vakhrushev.me/av/transcriber/internal/controller/http"
|
httpcontroller "git.vakhrushev.me/av/transcriber/internal/controller/http"
|
||||||
|
tgcontroller "git.vakhrushev.me/av/transcriber/internal/controller/tg"
|
||||||
"git.vakhrushev.me/av/transcriber/internal/controller/worker"
|
"git.vakhrushev.me/av/transcriber/internal/controller/worker"
|
||||||
"git.vakhrushev.me/av/transcriber/internal/service"
|
"git.vakhrushev.me/av/transcriber/internal/service"
|
||||||
"github.com/doug-martin/goqu/v9"
|
"github.com/doug-martin/goqu/v9"
|
||||||
@@ -93,6 +94,31 @@ func main() {
|
|||||||
// Создаем сервисы
|
// Создаем сервисы
|
||||||
transcribeService := service.NewTranscribeService(jobRepo, fileRepo, metaviewer, converter, recognizer, logger)
|
transcribeService := service.NewTranscribeService(jobRepo, fileRepo, metaviewer, converter, recognizer, logger)
|
||||||
|
|
||||||
|
// Создаем контекст для graceful shutdown
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
// Создаем WaitGroup для ожидания завершения всех воркеров
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
|
||||||
|
// Создаем Telegram бот
|
||||||
|
tgController, err := tgcontroller.NewTelegramController(transcribeService, jobRepo, logger)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("Failed to create Telegram controller", "error", err)
|
||||||
|
// Не останавливаем приложение, если Telegram бот не создан
|
||||||
|
} else {
|
||||||
|
// Запускаем Telegram бот в отдельной горутине
|
||||||
|
wg.Add(1)
|
||||||
|
go func() {
|
||||||
|
defer wg.Done()
|
||||||
|
logger.Info("Starting Telegram bot")
|
||||||
|
tgController.Start()
|
||||||
|
}()
|
||||||
|
|
||||||
|
// Добавляем функцию остановки бота в контекст завершения
|
||||||
|
defer tgController.Stop()
|
||||||
|
}
|
||||||
|
|
||||||
// Создаем воркеры
|
// Создаем воркеры
|
||||||
conversionWorker := worker.NewCallbackWorker("conversion_worker", transcribeService.FindAndRunConversionJob, logger)
|
conversionWorker := worker.NewCallbackWorker("conversion_worker", transcribeService.FindAndRunConversionJob, logger)
|
||||||
transcribeWorker := worker.NewCallbackWorker("transcribe_worker", transcribeService.FindAndRunTranscribeJob, logger)
|
transcribeWorker := worker.NewCallbackWorker("transcribe_worker", transcribeService.FindAndRunTranscribeJob, logger)
|
||||||
@@ -104,13 +130,6 @@ func main() {
|
|||||||
checkWorker,
|
checkWorker,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Создаем контекст для graceful shutdown
|
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
// Создаем WaitGroup для ожидания завершения всех воркеров
|
|
||||||
var wg sync.WaitGroup
|
|
||||||
|
|
||||||
// Запускаем воркеры в отдельных горутинах
|
// Запускаем воркеры в отдельных горутинах
|
||||||
for _, w := range workers {
|
for _, w := range workers {
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
|
Reference in New Issue
Block a user