Discord.NET V3 音樂機器人開發筆記:建立專案與初始化

發表於

開發

這邊搭配 Discord.NET V3 的框架並使用 .NET 6.0 主控台程式來進行 Discord 機器人開發,目標是讓使用者透過文字指令來控制機器人播放、停止存在本機的音樂。

本系列會分成多篇撰寫,最後統整於每篇的開頭後。


框架資訊


安裝框架

一、使用 Visual Studio 2022 建立一個 .NET 6.0 的主控台應用程式專案。

二、於專案上滑鼠右鍵 > 管理 NuGet 套件。

三、搜尋「Discord.NET」並完成安裝。

建立機器人

一、前往 Discord Developer Portal — My Applications 建立一個新的機器人,進入「Bot」分頁將「Public Bot」啟用。

二、切換到「OAuth2」分頁,設定 Authorization Method 為「In-app Authorization」,並勾選 Scopes 的「bot、applications.commands」和 Bot Permissions 的「Administrator」。前者的權限範圍分別是機器人和之後會用到的斜線指令,後者是機器人要開啟的權限,設定 Administrator 代表全開。

三、切換到 URL Generator 分頁,一樣勾選「bot、applications.commands、Administrator」後用下方給的網址開新分頁,將此機器人邀請到自己的伺服器中。

初始化連線

接下來編輯 Program.cs,在開始寫功能前要先做好以下幾樣事情:

  1. Discord Developer Portal — My Applications 的 Bot 分頁複製你的機器人 Token,並放到程式中 (一開始先 Hard Code 沒關係,未來再把它改寫到 JSON 檔案中即可)。
  2. 建立 DiscordSocketClient。
  3. 監聽 Log、Ready、MessageReceived 與 SlashCommandExecuted 四個常用的事件,分別是紀錄、初始化完成、接收到頻道文字訊息與偵測到這隻機器人的斜線指令。
  4. 執行 client.LoginAsync 與 client.StartAsync 完成機器人初始化。

LogAsync 我們直接使用官方範例,是個不錯的樣板。

using Discord;
using Discord.Commands;
using Discord.WebSocket;

var token = "YOUR BOT TOKEN";
var client = new DiscordSocketClient();

client.Log += LogAsync;
client.Ready += OnReady;
client.MessageReceived += OnReceiveMessage;
client.SlashCommandExecuted += OnReceiveSlashCommand;

await client.LoginAsync(TokenType.Bot, token);
await client.StartAsync();

Task LogAsync(LogMessage message)
{
    if (message.Exception is CommandException cmdException)
    {
        Console.WriteLine($"[Command/{message.Severity}] {cmdException.Command.Aliases.First()}"
            + $" failed to execute in {cmdException.Context.Channel}.");
        Console.WriteLine(cmdException);
    }
    else
        Console.WriteLine($"[General/{message.Severity}] {message}");

    return Task.CompletedTask;
}

async Task OnReady() { }
async Task OnReceiveMessage(SocketMessage msg) { }
async Task OnReceiveSlashCommand(SocketSlashCommand cmd) { }

按下 F5 建置專案後即可看到你的機器人已於 Discord 中上線。

常用功能寫法統整

以下語法皆是以上方的初始化連線範例為基礎。

列出機器人已加入的伺服器

foreach (var e in client.Guilds)
{
    var guild = client.GetGuild(e.Id);
    // TODO
}

取得指令發送者的資料

可用於 OnReceiveMessage 與 OnReceiveSlashCommand 中。

OnReceiveMessage:

var user = msg.Author as SocketGuildUser;

OnReceiveSlashCommand:

var user = cmd.User as SocketGuildUser;

取得指令發送者所在的語音頻道

var voiceChannel = user.VoiceChannel;

檢查機器人是否存在於指令發送者所在的語音頻道

var isExist = user.VoiceChannel.GetUser(client.CurrentUser.Id) == null;

回覆斜線指令訊息

每次的斜線指令執行後必須要回覆一次,否則 Discord 上會顯示錯誤。

await cmd.RespondAsync("TEXT HERE");

取得回覆的斜線指令訊息

var lastMsg = await cmd.GetOriginalResponseAsync();

刪除回覆的斜線指令訊息

var lastMsg = await cmd.GetOriginalResponseAsync();
lastMsg.DeleteAsync();

發送訊息至文字頻道

可用於 OnReceiveMessage 與 OnReceiveSlashCommand 中。

OnReceiveMessage:

await msg.Channel.SendMessageAsync("TEXT HERE");

OnReceiveSlashCommand:

await cmd.Channel.SendMessageAsync("TEXT HERE");

重啟機器人

重新啟動整支控制台應用程式。

System.Diagnostics.Process.Start(AppDomain.CurrentDomain.FriendlyName);
Environment.Exit(0);