如何使用C#的Discord.NET实时获取自身用户消息并处理事件?
问题解答与代码示例
1. 是否需要在开发者门户创建应用?
不需要专门创建Bot应用,但必须明确:Discord官方严格禁止使用用户账户(非Bot)进行自动化操作(即Self-Bot),违反此条款可能导致你的账号被永久封禁。即使是个人测试,也请谨慎操作。
2. C# 基于Discord Gateway读取自身消息示例
以下是使用System.Net.WebSockets实现的基础示例,用于连接Discord Gateway并监听自身发送的消息:
using System; using System.Net.WebSockets; using System.Text; using System.Text.Json; using System.Threading; using System.Threading.Tasks; class DiscordSelfGatewayClient { private ClientWebSocket _webSocket; private readonly string _token; private const string _gatewayUrl = "wss://gateway.discord.gg/?v=10&encoding=json"; public DiscordSelfGatewayClient(string token) { _token = token; _webSocket = new ClientWebSocket(); } public async Task StartAsync() { await _webSocket.ConnectAsync(new Uri(_gatewayUrl), CancellationToken.None); Console.WriteLine("已连接到Discord Gateway"); // 发送身份验证 payload var identifyPayload = new { op = 2, d = new { token = _token, properties = new { $os = Environment.OSVersion.ToString(), $browser = "SelfClientDemo", $device = "SelfClientDemo" }, intents = 513 // 启用GUILD_MESSAGES和DIRECT_MESSAGES意图,可按需调整 } }; await SendPayloadAsync(identifyPayload); // 持续接收网关消息 var buffer = new byte[4096]; while (_webSocket.State == WebSocketState.Open) { var result = await _webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None); var message = Encoding.UTF8.GetString(buffer, 0, result.Count); if (!string.IsNullOrWhiteSpace(message)) { await HandleGatewayMessageAsync(message); } } } private async Task SendPayloadAsync(object payload) { var json = JsonSerializer.Serialize(payload); var bytes = Encoding.UTF8.GetBytes(json); await _webSocket.SendAsync(new ArraySegment<byte>(bytes), WebSocketMessageType.Text, true, CancellationToken.None); } private async Task HandleGatewayMessageAsync(string message) { var jsonDoc = JsonDocument.Parse(message); var opCode = jsonDoc.RootElement.GetProperty("op").GetInt32(); switch (opCode) { case 0: // 事件推送 var eventType = jsonDoc.RootElement.GetProperty("t").GetString(); if (eventType == "MESSAGE_CREATE") { var messageData = jsonDoc.RootElement.GetProperty("d"); var authorId = messageData.GetProperty("author").GetProperty("id").GetString(); var content = messageData.GetProperty("content").GetString(); // 过滤自身发送的消息 if (authorId == "你的用户ID") // 替换为你自己的Discord用户ID { Console.WriteLine($"自身消息内容: {content}"); // 在这里添加你的自定义处理逻辑 } } break; case 1: // 心跳请求 await SendPayloadAsync(new { op = 1, d = jsonDoc.RootElement.GetProperty("d").GetInt32() }); break; case 10: // Hello帧,启动心跳循环 var heartbeatInterval = jsonDoc.RootElement.GetProperty("d").GetProperty("heartbeat_interval").GetInt32(); _ = Task.Run(async () => await HeartbeatLoopAsync(heartbeatInterval)); break; } } private async Task HeartbeatLoopAsync(int intervalMs) { while (_webSocket.State == WebSocketState.Open) { await Task.Delay(intervalMs); await SendPayloadAsync(new { op = 1, d = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() }); } } static async Task Main(string[] args) { var token = "你的用户账户令牌"; // 替换为你的Discord用户令牌 var client = new DiscordSelfGatewayClient(token); await client.StartAsync(); } }
关键提示:
- 替换代码中的
你的用户账户令牌和你的用户ID为实际值,用户令牌请勿泄露给他人。 - 此示例仅用于技术学习,使用时必须遵守Discord服务条款,避免账号风险。
内容的提问来源于stack exchange,提问作者Jaume
相关产品推荐
相关产品推荐

