Ugrás a tartalomra

Parancsok

Első parancsunk

A legegyértelműbb kommunikációs forma a parancsok használata. Erre a feladatra egy csodálatos keretrendszer áll rendelkezésünkre.

Hozzunk is létre gyorsan egy mappát a parancsaiknak, abba pedig egy új C# fájlt. Próbálgatni a dolgokat én készítek egy Test parancsot. A namespace-t annyival módosítom, hogy kövesse a mappastruktúrát.

using Discord.Interactions;

namespace DNetTutorial.Commands;

// Az InteractionModuleBase-ből örökölünk, hogy a Interactions-ben
// lévő metódusokat használhassuk.
public class Test : InteractionModuleBase
{
  [RequireOwner] // Hogy csak a tulajdonos használhassa
  [SlashCommand("test", "Teszt parancs")] // (név, leírás)
  public async Task Run()
  {
    await RespondAsync("Hello World!");
  }
}

Ezzel egy nagyon egyszerű parancs létre is lett hozva. Most menjünk vissza a kiinduló osztályunkhoz, hogy elkészítsük a logikát, ami meg fogja hívni a megfelelő parancs metódusát.

using Discord;
using Discord.Interactions;
using Discord.WebSocket;
using Microsoft.Extensions.DependencyInjection; // NuGet-ről telepíteni

namespace DNetTutorial;

public class DNetTutorial
{
    private readonly IServiceProvider services;

    public DiscordSocketClient Client { get; }
    // A Discord Interactions API-val kommunikáló osztály
    public InteractionService Interaction { get; }

    public DNetTutorial()
    {
        Client = new();
        Interaction = new(Client);

        // Összegyűjtjük a szükséges osztályokat, hogy injektálva
        // lehessenek. Ez azért hasznos, mert így nem kell mindenhol
        // újra példányosítani az osztályokat. Az eltárolt értékek is
        // megmaradnak. A parancsoknál is könnyedén lesznek.
        this.services = new ServiceCollection()
            .AddSingleton(Client)
            .AddSingleton(Interaction)
            .BuildServiceProvider();
    }

    public async Task MainAsync()
    {
        Client.Log += Log;

        string token = "A.TOKEN.AMIT.KIMÁSOLTÁL";

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

        // Minden perjeles parancs használatánál lefut ez a metódus.
        Client.SlashCommandExecuted += async (interaction) =>
        {
            // Itt létrehozunk egy Context-et, amiben eltárol
            // néhány hasznos információt, amit a parancsok 
            // használnak/használhatnak.
            SocketInteractionContext context = new(
                Client, interaction);
            // Majd kegyes egszerűséggel futtatjuk a parancsot.
            await Interaction.ExecuteCommandAsync(
                context, this.services);
        };

        // Ha a bot elindult, akkor ez a metódus fog lefutni.
        Client.Ready += async () =>
        {
            // Ez a metódus megkeresi az összes osztály a
            // projektünkben, ami örökli a korábban a parancsnál
            // használt ModuleBase osztályt.
            await Interaction.AddModulesAsync(
                typeof(DNetTutorial).Assembly, this.services);

            // Az már ismert modulok segítségével regisztráljuk a
            // létrehozott parancsokat egy általunk kiválasztott
            // szerverre.
            // A true azt jelenti, hogy törli azokat a parancsokat,
            // amiket nem talál meg a modulok között.
            await Interaction.RegisterCommandsToGuildAsync(
                712287958274801695, true);
        };

        await Task.Delay(-1);
    }

    private Task Log(LogMessage message)
    {
        Console.WriteLine(message.ToString());
        return Task.CompletedTask;
    }
}

Ezennel el is készült minden, ami a parancs futtatásához szükséges. Innentől akármennyit létrehozhatunk, és biztosak lehetünk benne, hogy regisztrálva lesz, és használható.

Ha futtatjuk a /test parancsot, akkor a botunk válaszol is az előre beállított szöveggel.

A /test parancs futtatásának eredménye. A bot kiírta a chatre, hogy Hello World!
A /test parancs futtatásának eredménye. A bot kiírta a chatre, hogy Hello World!

Parancs csoportok

Az egyszerű parancsok unalmasak. Mi lenne, ha parancs csoportokat csinálnánk? Szerencsére ehhez szinte semmi speciálisat nem kell csinálni. Menjünk vissza a Test parancsunkhoz és csináljunk belőle alparancsot!

using Discord;
using Discord.Interactions;
using Discord.WebSocket;

namespace DNetTutorial.Commands;

[RequireOwner] // Így az összes al-parancsot csak a használhatja
[Group("test", "Teszt parancsok")] // (név, leírás)
public class Test : InteractionModuleBase
{
    // Ha létrehozunk egy publikusan elérhető property-t, akkor a
    // DI automatikusan beinjektálja a fő osztályunkban property-k
    // alapján, ha a név megegyezik. Ebben a példában a kérjük
    // be, hogy az egyik parancsban kiolvashassunk belőle egy
    // információt.
    public DiscordSocketClient Client { get; set;}

    [SlashCommand("hello-world", "Hello World parancs")]
    public async Task HelloWorld()
    {
        await RespondAsync("Hello World!");
    }

    // A metódus paraméterei a parancsban megadott argumentumok.
    // A Summary attribútummal felülírhatjuk a paraméterek nevét és
    // leírását.
    [SlashCommand("hi", "Üdvözlő parancs")]
    public async Task Hi(
        [Summary(name: "Tag", description: "Akit üdvözölünk")]
        IUser user)
    {
        await RespondAsync($"Hello {user.Mention}!");
    }

    // Most nem számuljuk ki a bot pingjét, hanem csak kipróbáljuk,
    // hogyan lehet megemlíteni az aktuális felhasználót.
    [SlashCommand("ping", "Ping parancs")]
    public async Task Ping()
    {
        // A Context változóban találunk jópár hasznos dolgot.
        await RespondAsync($"Pong! {Context.User.Mention}");
    }

    [SlashCommand("guild-count", "Szerverek száma, ahol a bot van")]
    public async Task GuildCount()
    {
        await RespondAsync(
            $"A bot **`{Client.Guilds.Count}`** szerveren van bent."
        );
    }
}

Végül nézzük meg Discordon, hogy mit alkottunk. A parancsok mind megjelennek ugyan abban a kategóriában.

A Discordon megjelenő parancsok listája.
A Discordon megjelenő parancsok listája.

Az egyes parancsokat futtatva pedig ezeket a válaszokat kapjuk:

Képernyőkép a parancsok futtatásakor visszakapott üzenetekről.
Képernyőkép a parancsok futtatásakor visszakapott üzenetekről.

Köszönöm, hogy végigolvastad ezt az egyszerű kis tutorialt! Remélem tanultál valami újat. Ha meglesnéd a kész botot, akkor látogass el GitHub Repositoryjába. További információt a Discord.NET-ről a hivatalos oldalukon találsz.

Bot használata

A bot használatához az alábbi videó nyújt segítséget.

Teljes szövegű leírás

Alapvetően a Discord botokat nagyon egyszerű használni.

Miután be van hívva egy szerverre a botunk, a chaten mindössze a perjel beírásával már fel is dobja a Discord a lehetséges parancsok futtatását.

Mi ezek közül a saját botunk parancsaira vagyunk kíváncsi.

Ha rákattintunk az ikonunkra, akkor feldobja az összes lehetőséget.

Jelenleg a teszt parancsunk áll rendelkezésre, ezen belül négy alparancs.

Bármelyiket ki lehet választani, és akkor betölti.

Kattintással betöltötte az egészet, de gépelni is tökéletesen megfelel.

Most például üzenni fogok EricTheBestnek.

A parancsot mindössze az ENTER lenyomásával el lehet küldeni, és meg is kapjuk a választ.

Másik parancsot ha futtatni akarok, akkor beírom, TAB lenyomásával kiegészíti, ez is segít, és ez is tökéletesen működik.