Поиск, прослушивание и отправка музыки прямо в Telegram
🎧 Демо · 🚀 Быстрый старт · 💻 Разработка · 📝 OpenSpec · 📄 Лицензия
Бот принимает название исполнителя или трека, находит музыку во внешнем источнике и отправляет выбранную композицию пользователю. Интерфейс построен на inline-кнопках, поддерживает постраничную навигацию и отправку всех треков с текущей страницы.
Основные возможности:
- 🔎 Поиск музыки по исполнителю или названию;
- 🎧 Прослушивание и отправка аудиофайлов в Telegram;
- 🔥 Подборка популярных треков;
- 📚 История поисковых запросов в PostgreSQL;
- 🌍 Интерфейс на русском и английском языках;
- 🗣️ Автоматический выбор языка Telegram-пользователя;
- ✅ Проверка обязательной подписки на каналы;
- 🔒 Работа только в личных чатах;
- 🐳 Удобный запуск через Docker Compose;
- 📊 Adminer для просмотра и администрирования базы данных.
- 🐳 Docker с Docker Compose;
- 🔑 токен Telegram-бота от @BotFather.
git clone https://github.com/goldpulpy/TelegramMusicBot.git
cd TelegramMusicBotcp .env.example .envОткройте .env и как минимум замените токен и учётные данные базы:
BOT_TOKEN=1234567890:replace_with_your_bot_token
POSTGRES_HOST=postgres
POSTGRES_PORT=5432
POSTGRES_USER=music_bot
POSTGRES_PASSWORD=replace_with_a_strong_password
POSTGRES_DB=music_bot
ADMINER_PORT=8080
TZ=UTCImportant
Значение POSTGRES_HOST=postgres обязательно для запуска приложения внутри
основного Docker Compose-стека.
docker compose up -d --buildБудут запущены три контейнера:
- 🤖
bot- Telegram-бот; - 🐘
postgres- PostgreSQL 17; - 📊
adminer- веб-интерфейс базы данных.
Проверьте состояние и логи:
docker compose ps
docker compose logs -f botПри первом старте приложение автоматически создаёт необходимые таблицы.
После появления сообщения о запуске polling откройте бота и отправьте
/start.
# Остановить контейнеры
docker compose down
# Перезапустить бота
docker compose restart bot
# Пересобрать после изменения кода или зависимостей
docker compose up -d --build botWarning
Данные PostgreSQL хранятся в именованном Docker volume и сохраняются после
обычного docker compose down. Команда docker compose down -v удалит
volume вместе с данными - используйте её только при необходимости.
Локально удобно запускать только PostgreSQL и Adminer в Docker, а приложение - из виртуального окружения. Так изменения кода применяются без пересборки образа.
- 🐍 Python 3.12;
- 📦 uv;
- 🐳 Docker с Docker Compose;
- 🔑 токен бота.
uv syncКоманда создаст .venv и установит runtime- и dev-зависимости согласно
pyproject.toml и uv.lock.
cp .env.example .envДля локального Python-процесса измените адрес базы на localhost:
BOT_TOKEN=1234567890:replace_with_your_bot_token
POSTGRES_HOST=localhost
POSTGRES_PORT=5432
POSTGRES_USER=music_bot
POSTGRES_PASSWORD=replace_with_a_strong_password
POSTGRES_DB=music_bot
ADMINER_PORT=8080
TZ=UTCCaution
Не добавляйте .env и настоящие секреты в Git.
docker compose -f dev/docker-compose.yml --env-file .env up -dDev-конфигурация публикует PostgreSQL на localhost:5432 и Adminer на
http://localhost:8080, но не запускает контейнер приложения.
uv run poe runОстановка выполняется через Ctrl+C, инфраструктура останавливается командой:
docker compose -f dev/docker-compose.yml down| Переменная | Обязательна | Значение по умолчанию | Описание |
|---|---|---|---|
BOT_TOKEN |
да | - | токен от BotFather; минимум 16 символов |
POSTGRES_HOST |
нет | localhost |
postgres в Docker, localhost при локальном запуске |
POSTGRES_PORT |
нет | 5432 |
порт PostgreSQL |
POSTGRES_USER |
да | - | пользователь базы данных |
POSTGRES_PASSWORD |
да | - | пароль пользователя базы |
POSTGRES_DB |
да | - | имя базы данных |
ADMINER_PORT |
нет | 8080 |
опубликованный порт Adminer; используется Compose |
TZ |
нет | UTC |
часовой пояс контейнера PostgreSQL |
Настройки приложения загружаются из окружения и файла .env. Неизвестные
переменные игнорируются. Порт должен находиться в диапазоне от 1 до 65535.
Откройте http://localhost:8080 и используйте:
| Поле Adminer | Docker Compose | Локальная разработка |
|---|---|---|
| Система | PostgreSQL | PostgreSQL |
| Сервер | postgres |
postgres |
| Пользователь | значение POSTGRES_USER |
значение POSTGRES_USER |
| Пароль | значение POSTGRES_PASSWORD |
значение POSTGRES_PASSWORD |
| База данных | значение POSTGRES_DB |
значение POSTGRES_DB |
Adminer работает внутри Docker-сети, поэтому сервер в его форме называется
postgres в обоих сценариях.
- 👤
users- профиль, язык и счётчик запросов пользователя; - 🔎
search_history- запросы и найденные треки в формате JSONB; - ✅
required_subscriptions- каналы, подписка на которые обязательна.
Чтобы включить обязательную подписку, добавьте запись в
required_subscriptions через Adminer. Бот должен иметь доступ к указанному
каналу, иначе проверка участника не сможет работать корректно.
- обработчики - в
bot/handlers/, с регистрацией роутера вbot/handlers/__init__.py; - фильтры, middleware и клавиатуры - в соответствующем пакете
bot/; - модели и операции с данными - в
database/; - интеграцию с музыкальным провайдером - в
service/; - переводы - в
locales/<язык>/LC_MESSAGES/messages.po; - тесты - в
tests/, по возможности повторяя структуру исходных пакетов.
Обработчики должны оставаться небольшими и асинхронными. Сетевые запросы и
доступ к базе выносите за их границы, ошибки записывайте через logging, а не
через print.
| Команда | Назначение |
|---|---|
uv sync |
синхронизировать .venv по lock-файлу |
uv run poe run |
запустить бота локально |
uv run poe format |
отформатировать проект Ruff |
uv run poe lint |
запустить Ruff lint с автоисправлениями |
uv run poe type-check |
проверить типы Pyright |
uv run poe tests |
запустить тесты Pytest |
uv run poe lang-compile |
скомпилировать каталоги переводов |
Перед коммитом воспроизведите проверки CI:
uv run ruff format --check .
uv run poe lint
uv run poe type-check
uv run poe testsTip
Для Ruff включены автоисправления, включая unsafe fixes, поэтому после
poe lint всегда просматривайте diff.
Проект использует OpenSpec и подход spec-driven development для планирования изменений до начала реализации. OpenSpec обслуживается AI-агентом через специализированные skills: разработчику не нужно вручную вести изменения через OpenSpec CLI или редактировать его служебные файлы.
Для работы skills требуется Node.js 20.19.0 или новее и глобально установленный OpenSpec CLI:
node --version
npm install -g @fission-ai/openspec@latest
openspec --versionРепозиторий уже инициализирован, поэтому запускать openspec init после
клонирования не нужно. Другие варианты установки доступны в
официальной документации OpenSpec.
- 💭 Обсудите неясную идею с агентом через
$openspec-explore. - 📝 Попросите подготовить изменение через
$openspec-propose, описав желаемое поведение. Агент создаст proposal, design, delta-спецификации и список задач. - 👀 Проверьте и согласуйте получившийся план.
- 🛠️ Отдельным запросом запустите реализацию через
$openspec-apply-change. - 📦 После завершения и проверки реализации вызовите
$openspec-archive-change. Агент синхронизирует основные спецификации и перенесёт завершённое изменение в архив.
Например:
$openspec-propose Добавь пользователю возможность создавать плейлисты
$openspec-apply-change add-playlists
$openspec-archive-change add-playlists
При необходимости основные спецификации можно обновить без архивации через
$openspec-sync-specs. В Codex skills вызываются с префиксом $; в клиентах,
которые используют slash-команды, тот же workflow может быть доступен как
/openspec-propose, /openspec-apply-change и /openspec-archive-change.
Актуальные требования находятся в openspec/specs/, активные изменения - в
openspec/changes/, а завершённые - в openspec/changes/archive/. Эти файлы
нужно коммитить вместе с соответствующими изменениями кода.
Сейчас поддерживаются en и ru. Чтобы изменить существующий перевод:
-
Отредактируйте
messages.poнужного языка. -
Скомпилируйте каталоги:
uv run poe lang-compile
-
Перезапустите приложение и проверьте оба языка.
-
Добавьте изменённые
.poфайлы в коммит. Каталоги.moигнорируются Git и создаются локально или при сборке Docker-образа.
Чтобы добавить язык, создайте каталог
locales/<код>/LC_MESSAGES/messages.po, добавьте его в список
support_languages в locales/_support_languages.py, скомпилируйте каталог и
проверьте выбор языка и команды бота.
- в полном Docker-стеке используйте
POSTGRES_HOST=postgres; - при запуске через
uv run poe runиспользуйтеPOSTGRES_HOST=localhost; - проверьте
docker compose psи совпадение учётных данных в.env; - для dev-стека убедитесь, что порт
POSTGRES_PORTсвободен.
Получите новый токен у @BotFather, уберите пробелы и кавычки, затем перезапустите приложение. Не публикуйте токен в issue, логах или commit history.
Выполните uv run poe lang-compile и перезапустите приложение. Для Docker также
потребуется пересборка образа, поскольку каталоги компилируются во время build.
Автоматическое создание таблиц не обновляет уже существующую схему. Нужна явная миграция либо пересоздание только локальной тестовой базы, если её данные не представляют ценности.
- не коммитьте
.env, токены, пароли и сгенерированные секреты; - используйте отдельные учётные данные и сильные пароли в production;
- не публикуйте PostgreSQL наружу без необходимости;
- внимательно проверяйте обновления зависимостей и Docker-образов;
Проект распространяется по лицензии Apache License 2.0.
Created with ❤️ by goldpulpy