Discord

NAME

API::Discord - Perl6 interface to Discord API

DESCRIPTION

This provides a lowish-level interface to the Discord API. It supplies a stream of messages and other events to which your app can listen.

SYNOPSIS

use API::Discord;
    use API::Discord::Debug; # remove to disable debug output
my $d = API::Discord.new(:token(my-bot-token), :script-mode);
$d.connect;
    await $d.ready;
react {
        whenever $d.messages -> $m {
            ...
        }
# Events not yet implemented
        #whenever $d.events -> $e {
        #    ...
        #}
    }

USING OBJECTS

API::Discord models the various API objects in corresponding classes. These classes can either be used directly, or used via the API object. The API object has the advantage of also having connections to Discord, thus allowing you to fetch and send data without doing it manually.

Most of the time, you will want to use an existing object to create and send another object.

For example, Discord communicates with us which Guilds and Channels we are in, so the API constantly keeps a cache of these, since they are usually few and rarely change. Therefore, to create a Channel, you might do it via Guild, and to send a Message, you might do it via Channel.

Channel and Guild are usually your entrypoints to doing things.

$api.get-channel($id).send-message("Hi I'm a bot");
    $api.get-guild($id).create-channel({ ... });

The other entrypoint to information are the message and event supplies. These emit complete objects, which can be used to perform further actions. For example, the Message class stores the Channel from which it came, and Channel has send-message:

whenever $api.messages -> $m {
        $m.channel.send-message("I heard that!");
    }

All of these classes use the API to fetch and send if they need to. This prevents them from having to know about one another, which would result in circular dependencies. It also makes them easier to test [1].

Ultimately, you can always just create and send an object to Discord if you want to do it that way.

my $m = API::Discord::Message.new(...);
    $api.send($m);

This requires you to know all the parts you need for the operation to be successful, however.

CRUD

The core of the Discord API is simple CRUD mechanics over REST. The general idea in API::Discord is that if an object has an ID, then send will update it; otherwise, it will create it and populate the ID from the response.

This way, the same few methods handle most of the interaction you will have with Discord: editing a message is done by calling send with a Message object that already has an ID; whereas posting a new message would simply be calling send with a message with no ID, but of course a channel ID instead.

API::Discord also handles deflating your objects into JSON. The structures defined by the Discord docs are supported recursively, which means if you set an object on another object, the inner object will also be deflated—into the correct JSON property—to be sent along with the outer object. However, if the Discord API doesn't support that structure in a particular situation, it just won't try to do it.

For example, you can set an Embed on a Message and just send the Message, and this will serialise the Embed and send that too.

my $m = API::Discord::Message.new(:channel($channel));
    $m.embed(...);
API::Discord.send($m);

This example will serialise the Message and the Embed and send them, but will not attempt to serialise the entire Channel object into the Message object because that is not supported. Instead, it will take the channel ID from the Channel object and put that in the expected place.

Naturally, one cannot delete an object with no ID, just as one cannot attempt to read an object given anything but an ID. (Searching notwithstanding.)

SHARDING

Discord implements sharding but you have to set it up yourself. This allows you to run multiple processes to handle data.

To do so, pass a value for shard and a value for shards-max in each process. You have to know how many processes you are running altogether. To add a shard, it is therefore necessary to restart all of your existing shards; otherwise, it would suddenly change which process is handling data for which guild.

Remember that only shard 0 will receive DMs.

By default, the connection will assume you have only one shard.

PROPERTIES

script-mode

This is a fake boolean property. If set, we handle SIGINT for you and disconnect properly.

Factories and fetchers

inflate- and create- methods return the object directly because they do not involve communication. All the other methods return a Promise that resolve to the documented return value.

[1]If we ever did that

The Camelia image is copyright 2009 by Larry Wall. "Raku" is trademark of the Yet Another Society. All rights reserved.