You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何用Discord.Net SDK捕获Discord语音频道成员进出事件?

How to Trigger Methods on Discord Voice Channel Join/Leave with Discord.Net (C#)

Absolutely! You can absolutely build this functionality with the Discord.Net SDK, and the official documentation covers everything you need to make it work. You won’t have to deal with raw Gateway "Voice State Update" events directly—Discord.Net wraps that into a clean, easy-to-use event for you.

Here’s a step-by-step breakdown to implement this:

1. Set Up Dependencies & Required Intents

First, make sure you’re using the latest version of Discord.Net, specifically the Discord.Net.WebSocket package since we need the WebSocket client to receive real-time events.

Critical note: Discord requires your bot to request specific Gateway Intents to receive voice state updates. You’ll need to enable GuildVoiceStates in your client configuration, plus Guilds to access server data. If your bot is in 100+ servers, you’ll also need to toggle the "Guild Voice States Intent" under Privileged Intents in the Discord Developer Portal for your application.

2. Subscribe to the VoiceStateUpdated Event

Discord.Net’s DiscordSocketClient exposes a VoiceStateUpdated event that fires whenever a user’s voice state changes—this includes joining a channel, leaving one, or switching channels. The event gives you access to the user, their old voice state, and their new voice state.

Full Code Example

Here’s a complete, runnable snippet to get you started:

using Discord;
using Discord.WebSocket;
using System.Threading.Tasks;

class VoiceTrackingBot
{
    private DiscordSocketClient _client;
    private const ulong TargetTextChannelId = 123456789012345678; // Replace with your text channel ID

    public static async Task Main(string[] args)
    {
        var bot = new VoiceTrackingBot();
        await bot.RunAsync();
    }

    public async Task RunAsync()
    {
        // Configure client with required intents
        var config = new DiscordSocketConfig
        {
            GatewayIntents = GatewayIntents.Guilds | GatewayIntents.GuildVoiceStates
        };

        _client = new DiscordSocketClient(config);

        // Subscribe to core events
        _client.Log += LogAsync;
        _client.VoiceStateUpdated += HandleVoiceStateChange;

        // Login and start the bot
        await _client.LoginAsync(TokenType.Bot, "YOUR_BOT_TOKEN"); // Replace with your bot token
        await _client.StartAsync();

        // Keep the bot running indefinitely
        await Task.Delay(-1);
    }

    private async Task HandleVoiceStateChange(SocketUser user, SocketVoiceState oldState, SocketVoiceState newState)
    {
        // User joined a voice channel
        if (oldState.VoiceChannel == null && newState.VoiceChannel != null)
        {
            await OnUserJoinedVoiceChannel(user, newState.VoiceChannel);
        }
        // User left a voice channel
        else if (oldState.VoiceChannel != null && newState.VoiceChannel == null)
        {
            await OnUserLeftVoiceChannel(user, oldState.VoiceChannel);
        }
        // User switched between voice channels
        else if (oldState.VoiceChannel != null && newState.VoiceChannel != null && oldState.VoiceChannel.Id != newState.VoiceChannel.Id)
        {
            await OnUserSwitchedVoiceChannels(user, oldState.VoiceChannel, newState.VoiceChannel);
        }
    }

    private async Task OnUserJoinedVoiceChannel(SocketUser user, SocketVoiceChannel channel)
    {
        var textChannel = channel.Guild.GetTextChannel(TargetTextChannelId);
        await textChannel.SendMessageAsync($"{user.Mention} just joined **{channel.Name}**! 🎙️");
    }

    private async Task OnUserLeftVoiceChannel(SocketUser user, SocketVoiceChannel channel)
    {
        var textChannel = channel.Guild.GetTextChannel(TargetTextChannelId);
        await textChannel.SendMessageAsync($"{user.Mention} left **{channel.Name}**. 👋");
    }

    private async Task OnUserSwitchedVoiceChannels(SocketUser user, SocketVoiceChannel oldChannel, SocketVoiceChannel newChannel)
    {
        var textChannel = oldChannel.Guild.GetTextChannel(TargetTextChannelId);
        await textChannel.SendMessageAsync($"{user.Mention} moved from **{oldChannel.Name}** to **{newChannel.Name}**!");
    }

    private Task LogAsync(LogMessage log)
    {
        System.Console.WriteLine(log.ToString());
        return Task.CompletedTask;
    }
}

3. Official Docs Coverage

All of this functionality is well-documented in the Discord.Net docs:

  • The VoiceStateUpdated event is detailed under the DiscordSocketClient class, explaining parameters and trigger conditions.
  • Gateway Intents are covered in setup guides, including which intents are required for voice state tracking.
  • SocketVoiceState properties like VoiceChannel are explained to help you check a user’s current/previous channel status.

Key Tips to Avoid Issues

  • Double-check that your bot has permissions to send messages in the target text channel and view voice channels in the server.
  • For bots in <100 servers, you don’t need to enable Privileged Intents in the Developer Portal—just include them in your client config.
  • Add exception handling to your event handlers if you’re adding complex logic (like database calls) to prevent the bot from crashing.

内容的提问来源于stack exchange,提问作者Mastro

火山引擎 最新活动