如何在discord.py中实现用户通过表情反应从等候室语音频道转移至目标语音频道的功能?
Absolutely, this is totally feasible with a Discord bot—here’s a clear, actionable breakdown using popular frameworks like discord.js (JS/TS) or discord.py to build this feature:
The idea is to listen for two key events:
- Verify a user’s current voice state (that they’re in the designated waiting room) when they react to a message
- Detect when a user adds your specific emoji reaction to the target text channel message
Once both conditions are met, the bot will automatically move the user to your desired voice channel.
1. Set Up Your Bot & Permissions
First, create a Discord bot in the Discord Developer Portal and invite it to your server with these critical permissions:
Move Members: Required to transfer users between voice channelsRead Message History: To access the target message users will react toGuild Voice States: To track users’ voice channel presenceGuild Message Reactions: To detect when users add the trigger emoji
Make sure the bot has access to both the waiting room voice channel and the target voice channel.
2. Track User Voice State & Reaction Events
You don’t need to pre-track every user in the waiting room—instead, when a reaction is added, you’ll check if the user is currently in the waiting room. This keeps your code simpler and avoids maintaining unnecessary state.
3. Add Logic to Validate & Execute the Move
In your bot code, you’ll need to:
- Ignore reactions from bots
- Verify the reaction is on your specified message (using the message ID)
- Verify the reaction uses your exact trigger emoji (supports both default and custom emojis)
- Confirm the user is in the waiting room voice channel
- If all checks pass, move the user to the target channel and send optional feedback
Discord.js (JavaScript/TypeScript)
const { Client, GatewayIntentBits } = require('discord.js'); const client = new Client({ intents: [ GatewayIntentBits.Guilds, GatewayIntentBits.GuildVoiceStates, GatewayIntentBits.GuildMessageReactions, GatewayIntentBits.MessageContent ] }); // Customize these values with your server's IDs const CONFIG = { WAITING_ROOM_ID: '123456789012345678', // Waiting room voice channel ID TARGET_VOICE_ID: '987654321098765432', // Target voice channel ID TRIGGER_MESSAGE_ID: '112233445566778899', // Text channel message users react to TRIGGER_EMOJI: '✅' // Use emoji ID for custom emojis (e.g., '123456789012345678') }; client.on('ready', () => { console.log(`Logged in as ${client.user.tag}!`); }); client.on('messageReactionAdd', async (reaction, user) => { // Skip bot reactions if (user.bot) return; // Check if reaction is on the correct message if (reaction.message.id !== CONFIG.TRIGGER_MESSAGE_ID) return; // Check if reaction matches the trigger emoji const isMatchingEmoji = reaction.emoji.name === CONFIG.TRIGGER_EMOJI || reaction.emoji.id === CONFIG.TRIGGER_EMOJI; if (!isMatchingEmoji) return; // Fetch the user's guild member data const guild = reaction.message.guild; const member = await guild.members.fetch(user.id); const currentVoiceChannel = member.voice.channel; // Verify user is in the waiting room if (!currentVoiceChannel || currentVoiceChannel.id !== CONFIG.WAITING_ROOM_ID) { await user.send('You need to join the waiting room voice channel first to use this feature!'); return; } // Get target voice channel const targetChannel = guild.channels.cache.get(CONFIG.TARGET_VOICE_ID); if (!targetChannel) { console.error('Target voice channel not found!'); await user.send('Sorry, the target channel doesn\'t exist. Contact an admin.'); return; } // Move the user try { await member.voice.setChannel(targetChannel); await user.send(`Successfully moved you to **${targetChannel.name}**!`); } catch (error) { console.error('Failed to move user:', error); await user.send('Sorry, I couldn\'t move you to the target channel. Contact an admin.'); } }); client.login('YOUR_BOT_TOKEN');
Discord.py (Python)
import discord from discord.ext import commands # Enable required intents intents = discord.Intents.default() intents.message_content = True intents.guilds = True intents.voice_states = True intents.message_reactions = True bot = commands.Bot(command_prefix='!', intents=intents) # Customize these values with your server's IDs CONFIG = { "WAITING_ROOM_ID": 123456789012345678, "TARGET_VOICE_ID": 987654321098765432, "TRIGGER_MESSAGE_ID": 112233445566778899, "TRIGGER_EMOJI": "✅" # For custom emojis: discord.PartialEmoji(id='123456789012345678', name='emoji_name') } @bot.event async def on_ready(): print(f'Logged in as {bot.user}') @bot.event async def on_reaction_add(reaction, user): # Skip bot reactions if user.bot: return # Check if reaction is on the correct message if reaction.message.id != CONFIG["TRIGGER_MESSAGE_ID"]: return # Check if reaction matches the trigger emoji if isinstance(reaction.emoji, discord.Emoji): emoji_match = reaction.emoji.id == CONFIG["TRIGGER_EMOJI"] else: emoji_match = reaction.emoji == CONFIG["TRIGGER_EMOJI"] if not emoji_match: return # Fetch user's member data guild = reaction.message.guild member = guild.get_member(user.id) or await guild.fetch_member(user.id) current_voice = member.voice.channel if member.voice else None # Verify user is in the waiting room if not current_voice or current_voice.id != CONFIG["WAITING_ROOM_ID"]: await user.send("You need to join the waiting room voice channel first to use this feature!") return # Get target voice channel target_channel = guild.get_channel(CONFIG["TARGET_VOICE_ID"]) if not target_channel: print("Target voice channel not found!") await user.send("Sorry, the target channel doesn't exist. Contact an admin.") return # Move the user try: await member.move_to(target_channel) await user.send(f"Successfully moved you to **{target_channel.name}**!") except Exception as e: print(f"Failed to move user: {e}") await user.send("Sorry, I couldn't move you to the target channel. Contact an admin.") bot.run("YOUR_BOT_TOKEN")
- Intents: Double-check that you’ve enabled all required intents in both your code and the Discord Developer Portal—missing intents will cause the bot to not detect reactions or voice state changes.
- Old Messages: If your trigger message was sent before the bot started, use
reaction.message.fetch()to ensure the message is loaded into the bot’s cache. - Custom Emojis: For custom emojis, always use the emoji’s ID instead of its name (since names can be duplicated across servers).
- Permissions: Ensure the bot has the
Move Memberspermission at the server level, and that it can view and connect to both the waiting room and target voice channels.
内容的提问来源于stack exchange,提问作者user15609381

