Helpers

Ekztazy.has_permissionFunction
has_permission(perms::Integer, perm::Permission) -> Bool

Determine whether a bitwise OR of permissions contains one Permission.

Examples

julia> has_permission(0x0420, PERM_VIEW_CHANNEL)
true

julia> has_permission(0x0420, PERM_ADMINISTRATOR)
false

julia> has_permission(0x0008, PERM_MANAGE_ROLES)
true
source
Ekztazy.filter_rangesFunction
filter_ranges(u::Vector{UnitRange{Int}})

Filter a list of ranges, discarding ranges included in other ranges from the list.

Example

julia> Ekztazy.filter_ranges([1:5, 3:8, 1:20, 2:16, 10:70, 25:60, 5:35, 50:90, 10:70])
4-element Vector{UnitRange{Int64}}:
 1:20
 5:35
 50:90
 10:70
source
Ekztazy.split_messageFunction
split_message(text::AbstractString; chunk_limit::UInt=2000,
              extrastyles::Vector{Regex}=Vector{Regex}(),
              forcesplit::Bool = true) -> Vector{String}

Split a message into chunks with at most chunk_limit length, preserving formatting.

The chunk_limit has as default the 2000 character limit of Discord's messages, but can be changed to any nonnegative integer.

Formatting is specified by STYLES) and can be aggregated with the extrastyles argument.

Discord limits messages to 2000, so the code forces split if format breaking cannot be avoided. If desired, however, this behavior can be lifter by setting forcesplit to false.

Examples

julia> split_message("foo")
1-element Vector{String}:
 "foo"

julia> split_message(repeat('.', 1995) * "**hello, world**")[2]
"**hello, world**"

julia> split_message("**hello**, *world*", chunk_limit=10)
2-element Vector{String}:
 "**hello**,"
 "*world*"

julia> split_message("**hello**, _*beautiful* world_", chunk_limit=15)
┌ Warning: message was forced-split to fit the desired chunk length limit 15
└ @ Main REPL[66]:28
3-element Vector{String}:
 "**hello**,"
 "_*beautiful* wo"
 "rld_"

julia> split_message("**hello**, _*beautiful* world_", chunk_limit=15, forcesplit=false)
┌ Warning: message could not be split into chunks smaller than the length limit 15
└ @ Main REPL[66]:32
2-element Vector{String}:
 "**hello**,"
 "_*beautiful* world_"

julia> split_message("**hello**\n=====\n", chunk_limit=12)
2-element Vector{String}:
 "**hello**\n=="
 "==="
  
julia> split_message("**hello**\n≡≡≡≡≡\n", chunk_limit=12, extrastyles = [r"\n≡+\n"])
2-element Vector{String}:
 "**hello**"
 "≡≡≡≡≡"
source
Ekztazy.plaintextFunction
plaintext(m::Message) -> String
plaintext(c::Client, m::Message) -> String

Get the Message contents with any User mentions replaced with their plaintext. If a Client is provided, DiscordChannels Role are also replaced. However, only channels and roles stored in state are replaced; no API requests are made.

source
Ekztazy.set_gameFunction
set_game(
    c::Client,
    game::AbstractString;
    type::Int=AT.GAME,
    since::Nullable{Int}=c.presence["since"],
    status::Union{PresenceStatus, AbstractString}=c.presence["status"],
    afk::Bool=c.presence["afk"],
    kwargs...,
) -> Bool

Shortcut for update_status to set the Client's Activity. Any additional keywords are passed into the activity section.

source
Ekztazy.optFunction

Deprecated, use Option instead

source
opt(ctx::Context)

Helper function that is equivalent to calling extops(ctx.interaction.data.options)

source
Ekztazy.OptionFunction
Option(; kwargs...) -> ApplicationCommandOption

Helper function that creates an ApplicationCommandOption`

source
Ekztazy.extopsFunction
extops(ops::Vector)

Creates a Dict of option name -> option value for the given vector of ApplicationCommandOption. If the option is of Subcommand type, creates a dict for all its subcommands.

source

Return an empty Dict if the list of options used is missing.

source
Ekztazy.ismeFunction
isme(c::Client, ctx::Context) -> Bool

Returns whether the context is a Message Context sent by the bot user.

source
Ekztazy.add_handler!Function
add_handler!(c::Client, handler::Handler)

Adds a handler to the client.

source
add_handler!(c::Client, handler::Handler)

Bulk adds handlers to the client.

source
Ekztazy.@fetchMacro
@fetch [functions...] block

Wrap all calls to the specified CRUD functions (create, retrieve, update, and delete) with fetch inside a block. If no functions are specified, all CRUD functions are wrapped.

Examples

Wrapping all CRUD functions:

@fetch begin
    guild_resp = create(c, Guild; name="foo")
    guild_resp.ok || error("Request for new guild failed")
    channel_resp = retrieve(c, DiscordChannel, guild_resp.val)
end

Wrapping only calls to retrieve:

@fetch retrieve begin
    resp = retrieve(c, DiscordChannel, 123)
    future = create(c, Message, resp.val; content="foo")  # Behaves normally.
end
source
Ekztazy.@deferred_fetchMacro
@deferred_fetch [functions...] block

Identical to @fetch, but Futures are not fetched until the end of the block. This is more efficient, but only works when there are no data dependencies in the block.

Examples

This will work:

@deferred_fetch begin
    guild_resp = create(c, Guild; name="foo")
    channel_resp = retrieve(c, DiscordChannel, 123)
end

This will not, because the second call is dependent on the first value:

@deferred_fetch begin
    guild_resp = create(c, Guild; name="foo")
    channels_resp = retrieve(c, DiscordChannel, guild_resp.val)
end
source