Чтобы сделать Discord-бота на Python, создайте приложение в Developer Portal, сохраните токен в .env, подключите discord.py и зарегистрируйте slash-команду /hello. Команда будет доступна только на тестовом сервере и ответит пользователю по имени. Для неё не нужен привилегированный доступ к содержимому всех сообщений, поэтому стартовая конфигурация остаётся небольшой и понятной.
У Discord есть два разных объекта, которые новичок часто смешивает. Application описывает интеграцию и команды, а bot user представляет её в сервере. Токен позволяет программе действовать от имени этого бота, поэтому его нельзя вставлять в статью, отправлять в чат или коммитить в Git. В этом проекте секрет останется в локальном файле .env, а код получит его через переменную окружения.
Заводим приложение и bot user в официальном Developer Portal.
Запускаем discord.py с обычными intents и тестовым guild id.
Регистрируем /hello и отправляем ответ на interaction.
Что подготовить в Discord и в папке проекта
Откройте Discord Developer Portal, создайте новое приложение и добавьте bot user в разделе Bot. Скопируйте токен один раз в .env. Затем включите Developer Mode в настройках клиента Discord и скопируйте ID своего тестового сервера. ID не является паролем, но токен является. Для быстрой разработки используем guild-команду: Discord рекомендует команды сервера для тестирования, а глобальные оставляет для готовой публичной версии.
| Значение | Где взять | Где хранить |
|---|---|---|
| Bot token | Developer Portal, раздел Bot | .env, никогда не в Git |
| Guild ID | Copy Server ID в Discord | .env для тестового сервера |
| Код приложения | Файл bot.py | В репозитории без секретов |
| Зависимости | discord.py и python-dotenv | В отдельном виртуальном окружении |
| Команда | /hello | Регистрируется через CommandTree |

Приложение хранит настройки, bot user виден на сервере, а Python-процесс подключается по секретному токену.
Пишем бота со slash-командой /hello
Создайте виртуальное окружение командами python -m venv .venv и python -m pip install -U discord.py python-dotenv. В .env положите строки DISCORD_TOKEN=... и DISCORD_GUILD_ID=.... Сам файл назовите bot.py, а не discord.py, иначе он перекроет импорт установленной библиотеки.
import os
import discord
from discord import app_commands
from dotenv import load_dotenv
load_dotenv()
TOKEN = os.getenv("DISCORD_TOKEN")
GUILD_ID = os.getenv("DISCORD_GUILD_ID")
if not TOKEN or not GUILD_ID:
raise RuntimeError("Заполните DISCORD_TOKEN и DISCORD_GUILD_ID в .env")
TEST_GUILD = discord.Object(id=int(GUILD_ID))
class CodikClient(discord.Client):
async def setup_hook(self) -> None:
commands = await tree.sync(guild=TEST_GUILD)
print(f"Синхронизировано команд: {len(commands)}")
intents = discord.Intents.default()
client = CodikClient(intents=intents)
tree = app_commands.CommandTree(client)
@tree.command(
name="hello",
description="Поздороваться с ботом",
guild=TEST_GUILD,
)
async def hello(interaction: discord.Interaction) -> None:
await interaction.response.send_message(
f"Привет, {interaction.user.display_name}! Бот работает."
)
@client.event
async def on_ready() -> None:
print(f"Вошли как {client.user}")
client.run(TOKEN)load_dotenv()читает локальный файл, после чегоos.getenv()получает два значения без встраивания секрета в код.setup_hook()синхронизирует дерево команд с тестовым сервером до обычной работы клиента.- Декоратор
@tree.commandсвязывает имяhelloс асинхронной функцией ответа. interaction.response.send_message()отвечает именно на вызов команды, а не читает все сообщения канала.

Пользователь вызывает команду, Discord передаёт interaction, а обработчик отправляет один ответ.
Как добавить приложение на тестовый сервер
В разделе Installation или OAuth2 URL Generator выберите установку на сервер и scope bot. Scope applications.commands включается вместе с bot scope, но интерфейс портала может показывать его отдельно. Для нашего ответа достаточно разрешения отправлять сообщения. Не выдавайте Administrator ради удобства: минимальные права проще объяснить и безопаснее отлаживать.
| Настройка | Для /hello | Почему |
|---|---|---|
| Guild install | Да | Добавляет приложение на тестовый сервер |
| bot scope | Да | Добавляет bot user |
| applications.commands | Нужен командам | Делает slash-команды доступными в клиенте |
| Send Messages | Да | Позволяет ответить в канале |
| Administrator | Нет | Не нужен для одного ответа |
| Message Content Intent | Нет | Slash-команда приходит как interaction |
!hello должна читать содержимое сообщений и требует соответствующего intent. Нативная /hello появляется в интерфейсе и передаётся приложению как interaction.Практика: запускаем и проверяем первый ответ
Запускайте бота из активированного виртуального окружения. Пока процесс работает, соединение с Discord остаётся открытым. Сначала дождитесь двух сообщений в терминале: количество синхронизированных команд и имя вошедшего пользователя. Затем откройте канал тестового сервера и начните вводить /hello. Guild-команда обычно удобна тем, что изменения предназначены именно для быстрой проверки.
- Создайте
.venv, активируйте его и установите две зависимости черезpython -m pip. - Создайте
.envс реальным токеном и guild id, а в.gitignoreдобавьте строки.envи.venv/. - Добавьте приложение на собственный тестовый сервер с минимальным разрешением отправки сообщений.
- Запустите
python bot.pyи дождитесь строк о синхронизации и входе. - Введите
/helloв канале, выберите команду из подсказки и отправьте её. - Убедитесь, что ответ содержит ваше отображаемое имя и что в терминале нет traceback.
- Остановите процесс сочетанием Ctrl+C и проверьте: офлайн-бот больше не отвечает. Это ожидаемо.
- В списке участников bot user отображается онлайн, пока
bot.pyзапущен. - Команда
/helloвидна в подсказках тестового сервера. - После отправки появляется ответ с вашим именем и фразой «Бот работает».
- В коде и истории Git нет реального токена.

Симптом определяет слой проверки: Python, регистрация команды, установка или права канала.
Почему бот офлайн или команда не появляется
Разделите проблему на три уровня. Если программа не стартует, читайте traceback Python. Если клиент вошёл, но команда отсутствует, проверяйте guild id, установку и синхронизацию. Если команда видна, но ответ завершается ошибкой, смотрите функцию обработчика и права в конкретном канале. Такой порядок быстрее, чем многократный сброс токена без причины.
Python импортирует ваш файл вместо библиотеки. Переименуйте его и удалите созданный кэш модуля.
Проверьте точные имена переменных и отсутствие лишних символов. Не печатайте токен для диагностики.
Команда синхронизируется не туда, где вы её ищете. Скопируйте ID при включённом Developer Mode.
Синхронизация сама по себе не добавляет интеграцию. Пройдите установочную ссылку под владельцем тестового сервера.
Это может скрыть неправильно выбранные разрешения. Верните минимальный набор и проверьте доступ канала отдельно.
.env. Технические детали сверены с официальной документацией Discord по application commands.Чем application отличается от bot user?
Application описывает интеграцию и команды, bot user представляет её среди участников сервера.
Можно ли хранить токен в bot.py?
Не стоит. Храните его в локальном .env, исключённом из Git.
Зачем нужен guild id?
В примере команда регистрируется только на тестовом сервере, что удобно для быстрой разработки.
Нужен ли Message Content Intent?
Нет, потому что /hello является application command и приходит как interaction.
Почему бот офлайн после закрытия терминала?
Локальный Python-процесс поддерживает соединение. После его остановки выполнять код некому.
Асинхронные функции, строки и условия удобно закрепить в курсе Python. Если установка библиотек ещё путается, начните с виртуального окружения и диагностики команды pip.
Затем добавьте к /hello строковый параметр или случайный ответ и сравните архитектуру с Telegram-ботом на Python. Идеи для следующих небольших инструментов собраны в статье об автоматизации на Python.