Events

Events are how Discord communicates and interacts with our application. In Ekztazy.jl, we use the Handler type in conjunction with the Context type to handle them.

Handler

A Handler is simple to register for an event. To register a handler for the Ready event:

# `c` is a client generated previously.
h = OnReady() do (ctx)
    println("I'm ready!")
end

add_handler!(c, h)

There is also a convenience method to create handlers. As such the following code is fully equivalent:

on_ready!(c) do (ctx)
    println("I'm ready!")
end

(on_ready! creates an OnReady handler and adds it to the client.) You can find a list of all gateway events here. Simply add On before their NAME to get the name of the associated handler!

Ekztazy.HandlerType
Handler(
    f::Function
    d::Dict{Symbol, Any}
)

Handler is a wrapper for a Dict{Symbol, Any} that also contains a function.

source

Context

The context is simply the payload received from the interaction. Exceptions:

  • The MessageCreate context contains a Message.
  • The OnGuildCreate and OnGuildUpdate contexts contain a Guild.
  • The OnInteractionCreate context contains an Interaction.

You can find the expected payloads for events here.

Ekztazy.ContextType
Context(
    data::Dict{Symbol, Any}
)

Context is a wrapper for a Dict{Symbol, Any} with some special functionality.

source

Commands

Commands are the core of any Discord Application, and as such they are also the core of Ekztazy. Let us define the most basic of functions there can be.

# ... c is a client struct 
# ... g is a guild id for testing
command!(ctx->reply(c, ctx, content="pong"), c, g, "ping", "Ping!")

For more information on each of the arguments, check the documentation of command! below. For more complicated functions, there are two ways for them to work. The default Discord.jl inspired "legacy style", which is deprecated, and the "new style". Let us look at both of these with two more complicated commands. New style

# ... c is a client struct 
# ... g is a guild id for testing
command!(c, g, "greet", "greets a user", legacy=false, options=Options(
    [User, "u", "The user to greet"]
)) do ctx, u::Member
    reply(client, ctx, content="Hello, $(u)!")
end

command!(c, g, "eval", "evaluates a string as julia code", options=Options(
    [String, "str", "the string to evaluate"]
)) do ctx, str::String 
    @info "$str"
    reply(c, ctx, content="```julia\n$(eval(Meta.parse(str)))\n```")
end

Legacy style

# ... c is a client struct 
# ... g is a guild id for testing
command!(c, g, "greet", "greets a user", options=[
    opt("u", "the user to greet")
]) do ctx
    reply(client, ctx, content="Hello, <@$(opt(ctx)["u"])>!")
end

command!(c, g, "eval", "evaluates a string as julia code", options=[
    opt("str", "the string to evaluate")
]) do ctx 
    reply(c, ctx, content="```julia\n$(eval(Meta.parse(opt(ctx)["str"])))\n```")
end

There a few key differences. In the legacy style, we have to use the opt function to get a Dict of Option name => User input, in the new style these are automatically provided to the handler function and are automatically type converted to the right type. In the legacy style, all command options are string, in the new style they can be strings, ints, bools, Users, Roles and DiscordChannels. You can check examples to see many different command definitions.

Handlers

Ekztazy.command!Function
command!(
    f::Function
    c::Client
    name::AbstractString
    description::AbstractString;
    kwargs...
)

Adds a handler for INTERACTION CREATE gateway events where the InteractionData's name field matches name. Adds this command to c.commands or c.guild_commands based on the presence of guild. The f parameter signature should be:

    (ctx::Context, args...) -> Any 

Where args is a list of all the Command Options

For example a command that takes a user u and a number n as input should have this signature:

(ctx::Context, u::User, n::Int) -> Any

and the arguments would automatically get converted.

Note: The argument names must match the Option names. The arguments can be ordered in any way. If no type is specified, no conversion will be performed, so Discord objects will be Snowflakes.

source
Ekztazy.component!Function
component!(
    f::Function
    c::Client
    custom_id::AbstractString
    kwargs...
)

Adds a handler for INTERACTION CREATE gateway events where the InteractionData's custom_id field matches custom_id. The f parameter signature should be:

(ctx::Context) -> Any 
source
Ekztazy.on_message_create!Function
on_message_create!(
    f::Function
    c::Client
)

Adds a handler for the MESSAGE_CREATE gateway event. The f parameter's signature should be:

    (ctx::Context) -> Any 
source
Ekztazy.on_guild_members_chunk!Function
on_guild_members_chunk!(
    f::Function
    c::Client
)

Adds a handler for the GUILD_MEMBERS_CHUNK gateway event. The f parameter's signature should be:

    (ctx::Context) -> Any 
source
Ekztazy.on_channel_delete!Function
on_channel_delete!(
    f::Function
    c::Client
)

Adds a handler for the CHANNEL_DELETE gateway event. The f parameter's signature should be:

    (ctx::Context) -> Any 
source
Ekztazy.on_guild_integrations_update!Function
on_guild_integrations_update!(
    f::Function
    c::Client
)

Adds a handler for the GUILD_INTEGRATIONS_UPDATE gateway event. The f parameter's signature should be:

    (ctx::Context) -> Any 
source
Ekztazy.on_guild_member_update!Function
on_guild_member_update!(
    f::Function
    c::Client
)

Adds a handler for the GUILD_MEMBER_UPDATE gateway event. The f parameter's signature should be:

    (ctx::Context) -> Any 
source
Ekztazy.on_presence_update!Function
on_presence_update!(
    f::Function
    c::Client
)

Adds a handler for the PRESENCE_UPDATE gateway event. The f parameter's signature should be:

    (ctx::Context) -> Any 
source
Ekztazy.on_channel_create!Function
on_channel_create!(
    f::Function
    c::Client
)

Adds a handler for the CHANNEL_CREATE gateway event. The f parameter's signature should be:

    (ctx::Context) -> Any 
source
Ekztazy.on_message_delete_bulk!Function
on_message_delete_bulk!(
    f::Function
    c::Client
)

Adds a handler for the MESSAGE_DELETE_BULK gateway event. The f parameter's signature should be:

    (ctx::Context) -> Any 
source
Ekztazy.on_message_reaction_add!Function
on_message_reaction_add!(
    f::Function
    c::Client
)

Adds a handler for the MESSAGE_REACTION_ADD gateway event. The f parameter's signature should be:

    (ctx::Context) -> Any 
source
Ekztazy.on_guild_role_delete!Function
on_guild_role_delete!(
    f::Function
    c::Client
)

Adds a handler for the GUILD_ROLE_DELETE gateway event. The f parameter's signature should be:

    (ctx::Context) -> Any 
source
Ekztazy.on_ready!Function
on_ready!(
    f::Function
    c::Client
)

Adds a handler for the READY gateway event. The f parameter's signature should be:

    (ctx::Context) -> Any 
source
Ekztazy.on_user_update!Function
on_user_update!(
    f::Function
    c::Client
)

Adds a handler for the USER_UPDATE gateway event. The f parameter's signature should be:

    (ctx::Context) -> Any 
source
Ekztazy.on_guild_create!Function
on_guild_create!(
    f::Function
    c::Client
)

Adds a handler for the GUILD_CREATE gateway event. The f parameter's signature should be:

    (ctx::Context) -> Any 
source
Ekztazy.on_guild_member_remove!Function
on_guild_member_remove!(
    f::Function
    c::Client
)

Adds a handler for the GUILD_MEMBER_REMOVE gateway event. The f parameter's signature should be:

    (ctx::Context) -> Any 
source
Ekztazy.on_typing_start!Function
on_typing_start!(
    f::Function
    c::Client
)

Adds a handler for the TYPING_START gateway event. The f parameter's signature should be:

    (ctx::Context) -> Any 
source
Ekztazy.on_message_update!Function
on_message_update!(
    f::Function
    c::Client
)

Adds a handler for the MESSAGE_UPDATE gateway event. The f parameter's signature should be:

    (ctx::Context) -> Any 
source
Ekztazy.on_guild_emojis_update!Function
on_guild_emojis_update!(
    f::Function
    c::Client
)

Adds a handler for the GUILD_EMOJIS_UPDATE gateway event. The f parameter's signature should be:

    (ctx::Context) -> Any 
source
Ekztazy.on_interaction_create!Function
on_interaction_create!(
    f::Function
    c::Client
)

Adds a handler for the INTERACTION_CREATE gateway event. The f parameter's signature should be:

    (ctx::Context) -> Any 
source
Ekztazy.on_guild_delete!Function
on_guild_delete!(
    f::Function
    c::Client
)

Adds a handler for the GUILD_DELETE gateway event. The f parameter's signature should be:

    (ctx::Context) -> Any 
source
Ekztazy.on_voice_state_update!Function
on_voice_state_update!(
    f::Function
    c::Client
)

Adds a handler for the VOICE_STATE_UPDATE gateway event. The f parameter's signature should be:

    (ctx::Context) -> Any 
source
Ekztazy.on_guild_member_add!Function
on_guild_member_add!(
    f::Function
    c::Client
)

Adds a handler for the GUILD_MEMBER_ADD gateway event. The f parameter's signature should be:

    (ctx::Context) -> Any 
source
Ekztazy.on_guild_ban_remove!Function
on_guild_ban_remove!(
    f::Function
    c::Client
)

Adds a handler for the GUILD_BAN_REMOVE gateway event. The f parameter's signature should be:

    (ctx::Context) -> Any 
source
Ekztazy.on_guild_role_update!Function
on_guild_role_update!(
    f::Function
    c::Client
)

Adds a handler for the GUILD_ROLE_UPDATE gateway event. The f parameter's signature should be:

    (ctx::Context) -> Any 
source
Ekztazy.on_guild_role_create!Function
on_guild_role_create!(
    f::Function
    c::Client
)

Adds a handler for the GUILD_ROLE_CREATE gateway event. The f parameter's signature should be:

    (ctx::Context) -> Any 
source
Ekztazy.on_voice_server_update!Function
on_voice_server_update!(
    f::Function
    c::Client
)

Adds a handler for the VOICE_SERVER_UPDATE gateway event. The f parameter's signature should be:

    (ctx::Context) -> Any 
source
Ekztazy.on_guild_ban_add!Function
on_guild_ban_add!(
    f::Function
    c::Client
)

Adds a handler for the GUILD_BAN_ADD gateway event. The f parameter's signature should be:

    (ctx::Context) -> Any 
source
Ekztazy.on_message_reaction_remove_all!Function
on_message_reaction_remove_all!(
    f::Function
    c::Client
)

Adds a handler for the MESSAGE_REACTION_REMOVE_ALL gateway event. The f parameter's signature should be:

    (ctx::Context) -> Any 
source
Ekztazy.on_channel_pins_update!Function
on_channel_pins_update!(
    f::Function
    c::Client
)

Adds a handler for the CHANNEL_PINS_UPDATE gateway event. The f parameter's signature should be:

    (ctx::Context) -> Any 
source
Ekztazy.on_resumed!Function
on_resumed!(
    f::Function
    c::Client
)

Adds a handler for the RESUMED gateway event. The f parameter's signature should be:

    (ctx::Context) -> Any 
source
Ekztazy.on_guild_update!Function
on_guild_update!(
    f::Function
    c::Client
)

Adds a handler for the GUILD_UPDATE gateway event. The f parameter's signature should be:

    (ctx::Context) -> Any 
source
Ekztazy.on_message_delete!Function
on_message_delete!(
    f::Function
    c::Client
)

Adds a handler for the MESSAGE_DELETE gateway event. The f parameter's signature should be:

    (ctx::Context) -> Any 
source
Ekztazy.on_webhooks_update!Function
on_webhooks_update!(
    f::Function
    c::Client
)

Adds a handler for the WEBHOOKS_UPDATE gateway event. The f parameter's signature should be:

    (ctx::Context) -> Any 
source
Ekztazy.on_channel_update!Function
on_channel_update!(
    f::Function
    c::Client
)

Adds a handler for the CHANNEL_UPDATE gateway event. The f parameter's signature should be:

    (ctx::Context) -> Any 
source
Ekztazy.on_message_reaction_remove!Function
on_message_reaction_remove!(
    f::Function
    c::Client
)

Adds a handler for the MESSAGE_REACTION_REMOVE gateway event. The f parameter's signature should be:

    (ctx::Context) -> Any 
source