Axelly
Axelly

Reputation: 859

Sending message to Discord channel

What I want to achieve:

I want to send message on Discord channel whenever console_app.exe is executed by an external program, so I decided to use pure rest:

I created APP via https://discord.com/developers/applications

I have ClientId and ClientSecret and now I'd want to sign in from code and send message on specific channel

I'm obtaining Token without problems with response like:

{
  "access_token": "6qrZcUqja781...HBFG",
  "token_type": "Bearer",
  "expires_in": 604800,
  "scope": "identify connections"
}

but when I try to send message (function WriteMessage) then I'm Unauthorized for some reason

The whole code:

private static readonly RestClient client = new RestClient("https://discord.com");

public string Perform()
{
    client.Authenticator = new HttpBasicAuthenticator(_config.ClientId, _config.ClientSecret);
    var token = GetToken();
    client.Authenticator = null;
    return WriteMessage(token);
}

private string GetToken()
{
    var signInRequest = new RestRequest("/api/v6/oauth2/token", Method.POST);
    signInRequest.AddHeader("content-type", "application/x-www-form-urlencoded");
    signInRequest.AddParameter("grant_type", "client_credentials");
    signInRequest.AddParameter("scope", "identify connections");

    var result = client.Execute<AuthResult>(signInRequest);

    return result.Data.access_token;
}

private string WriteMessage(string token)
{
    var request = new RestRequest("/api/v8/channels/.../messages", Method.POST);

    request.AddHeader("Authorization", $"Bearer {token}");
    //request.AddHeader("Authorization", $"{token}");
    
    var msg = new DiscordMessage
    {
        content = "Test",
        nonce = "78714914815023104",
        tts = false
    };

    request.AddJsonBody(msg);

    IRestResponse response = client.Execute(request);
    var content = response.Content;

    Console.WriteLine(response.StatusCode); // Unauthorized
    Console.WriteLine(response.Content);
    return content;
}

What I may be doing wrong?

Upvotes: 1

Views: 2585

Answers (2)

Axelly
Axelly

Reputation: 859

Here's solution using Discord.NET

public DiscordWrapper(string token)
{
    _token = token;
}

public async Task SendMessage()
{
    _client = new DiscordSocketClient();

    await _client.LoginAsync(TokenType.Bot, _token);
    await _client.StartAsync();

    // this is important
    // found it here:
    // https://github.com/discord-net/Discord.Net/issues/1100
    _client.Ready += _client_Ready;

     await Task.Delay(-1);
}

private async Task _client_Ready()
{
    var guild = _client.GetGuild(7....3); // guild id

    var channel = guild.GetTextChannel(79034....63); // channel id

    await channel.SendMessageAsync("my_message");

    Environment.Exit(0);
}

Upvotes: 0

jjxtra
jjxtra

Reputation: 21140

It might be easier to use this C# API which is quite popular on github: https://github.com/discord-net/Discord.Net

Writing auth from scratch can be painful.

It's worth a few minutes to try the library maybe it just works. You'll want to read the readme as there are 4 add-on nuget packages as well that might interest you.

Upvotes: 7

Related Questions