--- title: Интерактивные голосовые функции weight: 3 --- **Цель:** Реализовать сложные голосовые взаимодействия, которые учитывают границы серверов (гильдий) и управляют временными ресурсами. ## 1. Стратегия ограничения ресурсов Голосовые функции **ОБЯЗАТЕЛЬНО** должны быть ограничены рамками Гильдии (Guild). - **Паттерн:** Контроллер поддерживает `Map`. - **Поведение:** - **Подключение (Join):** Создать Player для `Гильдии A`, если он еще не существует. - **Отключение (Leave):** Уничтожить Player и освободить соединения. - **Изоляция:** Команды в `Гильдии B` никогда не влияют на `Гильдию A`. ## 2. Оркестрация команд Голосовые функции требуют набора команд, координируемых через Контроллер. | Команда | Действие | Логика Контроллера | | :--- | :--- | :--- | | `/join` | Подключиться к каналу | `createPlayer(guildId, channelId)` | | `/play` | Добавить трек в очередь | `getPlayer(guildId).enqueue(track)` | | `/stop` | Отключиться | `destroyPlayer(guildId)` | ## 3. Сохранение состояния Аудиосессии эфемерны. - **Временное состояние:** Активный аудиопоток (Теряется при отключении). - **Постоянное состояние:** Очередь / Плейлист (Сохраняется в Контроллере до перезапуска). > [!TIP] > **Устойчивость:** Разделяйте логику _Очереди_ и логику _Голосового соединения_. Это позволяет боту переподключаться без потери плейлиста пользователя. ## 4. Пример реализации ```typescript // lib/MusicController.ts class MusicController { private players = new Map(); getPlayer(guildId: string): AudioPlayer { if (!this.players.has(guildId)) { this.players.set(guildId, new AudioPlayer()); } return this.players.get(guildId); } destroyPlayer(guildId: string) { this.players.get(guildId)?.disconnect(); this.players.delete(guildId); } } ``` --- **См. также:** - [Руководство Discord.js Voice](https://discordjs.guide/voice/)