Helpers
Ekztazy.STYLES
— ConstantRegex expressions for split_message
to not break Discord formatting.
Ekztazy.Permission
— TypeBitwise permission flags. More details here.
Ekztazy.has_permission
— Functionhas_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
Ekztazy.permissions_in
— Functionpermissions_in(m::Member, g::Guild, ch::DiscordChannel) -> Int64
Compute a Member
's Permission
s in a DiscordChannel
.
Ekztazy.reply
— Functionreply(
c::Client
context;
kwargs...
)
Replies to a Context
, an Interaction
or a Message
.
Ekztazy.filter_ranges
— Functionfilter_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
Ekztazy.split_message
— Functionsplit_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**"
"≡≡≡≡≡"
Ekztazy.plaintext
— Functionplaintext(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, DiscordChannel
s Role
are also replaced. However, only channels and roles stored in state are replaced; no API requests are made.
Ekztazy.upload_file
— Functionupload_file(c::Client, ch::DiscordChannel, path::AbstractString; kwargs...) -> Message
Send a Message
with a file Attachment
. Any keywords are passed on to create_message
.
Ekztazy.set_game
— Functionset_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.
Ekztazy.opt
— FunctionDeprecated, use Option
instead
opt(ctx::Context)
Helper function that is equivalent to calling extops(ctx.interaction.data.options)
Ekztazy.Option
— FunctionOption(; kwargs...) -> ApplicationCommandOption
Helper function that creates an ApplicationCommandOption`
Ekztazy.extops
— Functionextops(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.
Return an empty Dict
if the list of options used is missing.
Ekztazy.isme
— Functionisme(c::Client, ctx::Context) -> Bool
Returns whether the context is a Message Context sent by the bot user.
Ekztazy.method_args
— Functionmethod_args(m::Method) -> Vector{Tuple{Symbol, Type}}
Ekztazy.add_handler!
— Functionadd_handler!(c::Client, handler::Handler)
Adds a handler to the client.
add_handler!(c::Client, handler::Handler)
Bulk adds handlers to the client.
Ekztazy.Options
— FunctionOptions(args...) -> Vector{ApplicationCommandOption}
Calls Option
on each Vector in the args.
Ekztazy.mention
— Functionmention(
o::DiscordObject
)
Generates the plaintext mention for a User
, a Member
, a DiscordChannel
, a Role
, or a Context
Ekztazy.@fetch
— Macro@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
Ekztazy.@fetchval
— MacroEkztazy.@deferred_fetch
— Macro@deferred_fetch [functions...] block
Identical to @fetch
, but Future
s are not fetch
ed 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
Ekztazy.@deferred_fetchval
— Macro@deferred_fetchval [functions...] block
Identical to @deferred_fetch
, but Future
s have fetchval
called on them instead of fetch
.