Skip to content

Commit 1c2ea4b

Browse files
author
Pavel Loginov
committed
ref-ing - N messengers
1 parent f2e5898 commit 1c2ea4b

16 files changed

Lines changed: 839 additions & 596 deletions

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,6 @@ recap
77
state.txt
88
*.tar.gz
99

10+
notes.md
11+
1012
recap.yaml

README.md

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ _Mainly, this bot is for using Sber's free tokens, which is why everything is in
44

55
Telegram бот для создания краткого содержания из голосовых сообщений и видео-кружочков.
66

7+
Теперь поддерживает и другие мессенджеры через плагины.
8+
79
Повтор попыток через очередь, ротация токенов Сбера, резевные модели в OpenRouter.
810

911
Коротко: Go, Sber Speech, OpenRouter, Telegram, ffmpeg.
@@ -16,7 +18,7 @@ Telegram бот для создания краткого содержания и
1618

1719
В основе лежит **канал taskQueue** через который проходят все операции:
1820

19-
1. **Receive** → Telegram сообщения попадают в taskQueue
21+
1. **Receive** → Telegram (и другие) сообщения попадают в taskQueue
2022
2. **Download** → Загрузка файла из Telegram + конвертация видео в аудио (если нужно)
2123
3. **STT** → Speech-to-Text преобразование
2224
4. **Summarize** → OpenRouter создает краткое содержание
@@ -27,6 +29,8 @@ Telegram бот для создания краткого содержания и
2729
## Настройка
2830

2931
1. Создайте бота в Telegram через [@BotFather](https://t.me/BotFather) и получите токен.
32+
33+
*Для других мессенджеров что-то подобное будет.*
3034

3135
2. Получите API ключи:
3236
- **Sber**: client_secret (может быть парой client_id:secret в base64, либо укажите client_id отдельно)
@@ -66,14 +70,18 @@ tar xfz recap_x64.tar.gz
6670

6771
Бот будет отвечать на голосовые сообщения и видео-кружочки в группе, как и в личных сообщениях.
6872

73+
*Для других мессенджеров настройки групп могут отличаться. Но часто нужны права на чтение сообщений.*
74+
6975
## Структура проекта
7076

7177
- `main.go` - точка входа, настройка и запуск
7278
- `bot.go` - основная логика бота, обработчики сообщений
7379
- `config.go` - конфигурация и типы
7480
- `logger.go` - настройка логирования
7581
- `worker.go` - обработка задач в воркерах
76-
- `telegram.go` - работа с Telegram API
82+
- `messenger.go` - интерфейсы мессенджеров (плагинная архитектура)
83+
- `messenger_telegram.go` - работа с Telegram API
84+
- `messenger_*` - прочие мессенджеры
7785
- `media.go` - конвертация медиафайлов
7886
- `yandex.go` - интеграция с Yandex SpeechKit
7987
- `sber.go` - интеграция с Sber SpeechKit
@@ -102,3 +110,5 @@ go run main.go
102110
## TODO
103111
- [ ] ограничения на размер войса в минутах (конфиг)
104112
- [ ] лимиты по вермению на юзера/группу (в памяти)
113+
- [ ] новый слой Bot, отделить мессенджер от текство и промптов
114+

bot.go

Lines changed: 0 additions & 218 deletions
This file was deleted.

config.go

Lines changed: 51 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package main
22

33
import (
4+
"fmt"
45
"os"
56
"time"
67

@@ -9,31 +10,35 @@ import (
910
)
1011

1112
type Config struct {
12-
Recognizer string `yaml:"recognizer" default:"sber"`
13-
Telegram struct {
14-
Token string `yaml:"token"`
15-
} `yaml:"telegram"`
16-
Max struct {
17-
Token string `yaml:"token"`
18-
} `yaml:"max"`
19-
Sber struct {
20-
Tokens []struct {
21-
Name string `yaml:"name"`
22-
ClientID string `yaml:"client_id"`
23-
ClientSecret string `yaml:"client_secret"`
24-
Cooldown time.Duration `yaml:"cooldown"`
25-
Limit time.Duration `yaml:"limit"`
26-
} `yaml:"tokens"`
27-
} `yaml:"sber"`
28-
Openrouter ConfigOpenrouter `yaml:"openrouter"`
29-
Prompts ConfigPrompts `yaml:"prompts"`
30-
Messages ConfigMessages `yaml:"messages"`
31-
RateLimit ConfigRateLimit `yaml:"rate_limit"`
32-
NumWorkers int `yaml:"num_workers" default:"2"`
33-
WaitOnError time.Duration `yaml:"wait_on_error" default:"3s"`
34-
FFmpegPath string `yaml:"ffmpeg_path"`
35-
SaveDebugMedia bool `yaml:"save_debug_media" default:"false"`
36-
StateFile string `yaml:"state_file"`
13+
Recognizer string `yaml:"recognizer" default:"sber"`
14+
Sber ConfigSber `yaml:"sber"`
15+
Openrouter ConfigOpenrouter `yaml:"openrouter"`
16+
Prompts ConfigPrompts `yaml:"prompts"`
17+
Messages ConfigMessages `yaml:"messages"`
18+
RateLimit ConfigRateLimit `yaml:"rate_limit"`
19+
NumWorkers int `yaml:"num_workers" default:"2"`
20+
WaitOnError time.Duration `yaml:"wait_on_error" default:"3s"`
21+
FFmpegPath string `yaml:"ffmpeg_path" default:"ffmpeg"`
22+
SaveDebugMedia bool `yaml:"save_debug_media" default:"false"`
23+
StateFile string `yaml:"state_file"`
24+
Bots map[string]ConfigBot `yaml:"bots"`
25+
}
26+
27+
type ConfigBot struct {
28+
ID string `yaml:"id"`
29+
Messenger MessengerType `yaml:"messenger"`
30+
Token string `yaml:"token"`
31+
Prompt string `yaml:"prompt"`
32+
}
33+
34+
type ConfigSber struct {
35+
Tokens []struct {
36+
Name string `yaml:"name"`
37+
ClientID string `yaml:"client_id"`
38+
ClientSecret string `yaml:"client_secret"`
39+
Cooldown time.Duration `yaml:"cooldown"`
40+
Limit time.Duration `yaml:"limit"`
41+
} `yaml:"tokens"`
3742
}
3843

3944
type ConfigOpenrouter struct {
@@ -46,18 +51,17 @@ type ConfigOpenrouter struct {
4651
}
4752

4853
type ConfigPrompts struct {
49-
Prompts struct {
50-
SystemPrompt string `yaml:"system"`
51-
UserPrompt string `yaml:"user"`
52-
} `yaml:"prompts"`
54+
SystemPrompt string `yaml:"system"`
55+
UserPrompt string `yaml:"user"`
5356
}
5457

5558
type ConfigMessages struct {
56-
Listening string `yaml:"listening" default:"Listening"`
57-
StartMessage string `yaml:"start" default:"Send me a voice message and I'll transcribe it for you!"`
58-
ErrorMessage string `yaml:"error" default:"An error occurred while processing your message. Please try again."`
59-
FailureMessage string `yaml:"failure" default:"Failed to transcribe the audio. Please check the audio quality and try again."`
60-
RetryMessage string `yaml:"retry" default:"Retrying..."`
59+
Listening string `yaml:"listening" default:"Listening"`
60+
StartMessage string `yaml:"start" default:"Send me a voice message and I'll transcribe it for you!"`
61+
ErrorMessage string `yaml:"error" default:"An error occurred while processing your message. Please try again."`
62+
FailureMessage string `yaml:"failure" default:"Failed to transcribe the audio. Please check the audio quality and try again."`
63+
RetryMessage string `yaml:"retry" default:"Retrying..."`
64+
RateLimitMessage string `yaml:"rate_limit" default:"Rate limit exceeded. Please try again later."`
6165
}
6266

6367
type ConfigRateLimit struct {
@@ -81,5 +85,18 @@ func loadConfig(filename string) (*Config, error) {
8185
return nil, err
8286
}
8387

88+
// Validate that at least one bot is configured
89+
if len(config.Bots) == 0 {
90+
return nil, fmt.Errorf("at least one bot must be configured")
91+
}
92+
93+
// Fill ID from map keys if not set
94+
for botID, botConfig := range config.Bots {
95+
if botConfig.ID == "" {
96+
botConfig.ID = botID
97+
config.Bots[botID] = botConfig
98+
}
99+
}
100+
84101
return &config, nil
85102
}

0 commit comments

Comments
 (0)