Current section

Files

Jump to
discord_gleam src discord_gleam.erl
Raw

src/discord_gleam.erl

-module(discord_gleam).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/discord_gleam.gleam").
-export([continue/1, with_selector/2, stop/0, stop_abnormal/1, simple/2, new/3, with_name/2, start/1, send_message/3, create_dm_channel/2, send_direct_message/3, reply/4, kick_member/4, ban_member/4, delete_message/4, edit_message/4, wipe_global_commands/1, wipe_guild_commands/2, register_global_commands/2, register_guild_commands/3, request_guild_members/5, update_presence/2]).
-export_type([next/2, mode/2, handler_message/1]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
?MODULEDOC(
" The primary module of discord_gleam. \\\n"
" This module contains high-level functions to interact with the Discord API. \\\n"
" But you can always implement stuff yourself using the low-level functions from the rest of the library.\n"
).
-opaque next(OMN, OMO) :: {continue,
OMN,
gleam@option:option(gleam@erlang@process:selector(OMO))} |
stop |
{stop_abnormal, binary()}.
-opaque mode(OMP, OMQ) :: {simple,
discord_gleam@bot:bot(),
list(fun((discord_gleam@bot:bot(), discord_gleam@event_handler:packet()) -> nil)),
next(OMP, OMQ),
OMP} |
{normal,
discord_gleam@bot:bot(),
gleam@erlang@process:name(OMQ),
fun((gleam@erlang@process:selector(OMQ)) -> {OMP,
gleam@erlang@process:selector(OMQ)}),
fun((discord_gleam@bot:bot(), OMP, handler_message(OMQ)) -> next(OMP, OMQ))}.
-type handler_message(OMR) :: {packet, discord_gleam@event_handler:packet()} |
{user, OMR}.
-file("src/discord_gleam.gleam", 42).
?DOC(
" Continue processing with the updated state. Use `with_selector` to add a\n"
" selector for custom user messages.\n"
).
-spec continue(OMS) -> next(OMS, any()).
continue(State) ->
{continue, State, none}.
-file("src/discord_gleam.gleam", 47).
?DOC(" Add a selector for custom user messages.\n").
-spec with_selector(next(OMW, OMX), gleam@erlang@process:selector(OMX)) -> next(OMW, OMX).
with_selector(State, Selector) ->
case State of
{continue, User_state, _} ->
{continue, User_state, {some, Selector}};
_ ->
State
end.
-file("src/discord_gleam.gleam", 58).
?DOC(" Stop the event loop\n").
-spec stop() -> next(any(), any()).
stop() ->
stop.
-file("src/discord_gleam.gleam", 63).
?DOC(" Stop the event loop with an abnormal reason\n").
-spec stop_abnormal(binary()) -> next(any(), any()).
stop_abnormal(Reason) ->
{stop_abnormal, Reason}.
-file("src/discord_gleam.gleam", 100).
?DOC(" Create a simple mode with multiple handlers\n").
-spec simple(
discord_gleam@bot:bot(),
list(fun((discord_gleam@bot:bot(), discord_gleam@event_handler:packet()) -> nil))
) -> mode(nil, nil).
simple(Bot, Handlers) ->
{simple, Bot, Handlers, {continue, nil, none}, nil}.
-file("src/discord_gleam.gleam", 113).
?DOC(
" Create a normal mode with a single handler\n"
"\n"
" `on_init` function is called once discord websocket connection is\n"
" initialized. It must return a tuple with initial state and selector for\n"
" custom messages. If there is no custom messages, user can pass the same\n"
" selector from the argument\n"
).
-spec new(
discord_gleam@bot:bot(),
fun((gleam@erlang@process:selector(ONO)) -> {ONQ,
gleam@erlang@process:selector(ONO)}),
fun((discord_gleam@bot:bot(), ONQ, handler_message(ONO)) -> next(ONQ, ONO))
) -> mode(ONQ, ONO).
new(Bot, On_init, Handler) ->
{normal,
Bot,
gleam_erlang_ffi:new_name(<<"normal_mode_user_message_subject"/utf8>>),
On_init,
Handler}.
-file("src/discord_gleam.gleam", 130).
?DOC(
" Set process name for the event loop. Allows to use named subjects for custom\n"
" user messages in normal mode.\n"
).
-spec with_name(mode(ONX, ONY), gleam@erlang@process:name(ONY)) -> mode(ONX, ONY).
with_name(Mode, Name) ->
case Mode of
{normal, _, _, _, _} ->
{normal,
erlang:element(2, Mode),
Name,
erlang:element(4, Mode),
erlang:element(5, Mode)};
{simple, _, _, _, _} ->
Mode
end.
-file("src/discord_gleam.gleam", 213).
-spec to_internal_next(next(OOV, OOW)) -> discord_gleam@event_handler:next(OOV, OOW).
to_internal_next(Next) ->
case Next of
{continue, User_state, Opt} ->
{continue, User_state, Opt};
stop ->
stop;
{stop_abnormal, Reason} ->
{stop_abnormal, Reason}
end.
-file("src/discord_gleam.gleam", 204).
-spec internal_to_handler_message(
discord_gleam@event_handler:handler_message(OOS)
) -> handler_message(OOS).
internal_to_handler_message(Msg) ->
case Msg of
{discord_packet, Packet} ->
{packet, Packet};
{user, Msg@1} ->
{user, Msg@1}
end.
-file("src/discord_gleam.gleam", 187).
-spec to_internal_mode(mode(OOM, OON)) -> discord_gleam@event_handler:mode(OOM, OON).
to_internal_mode(Mode) ->
case Mode of
{simple, Bot, Handlers, Next, Nil_state} ->
{simple, Bot, Handlers, to_internal_next(Next), Nil_state};
{normal, Bot@1, Name, On_init, Handler} ->
Handler@1 = fun(Bot@2, User_state, Msg) ->
_pipe = Handler(
Bot@2,
User_state,
internal_to_handler_message(Msg)
),
to_internal_next(_pipe)
end,
{normal, Bot@1, Name, On_init, Handler@1}
end.
-file("src/discord_gleam.gleam", 170).
?DOC(
" Start the event loop with a current mode.\n"
"\n"
" Example:\n"
" ```gleam\n"
" import discord_gleam/discord/intents\n"
" import discord_gleam/event_handler\n"
" import discord_gleam/bot\n"
" import gleam/erlang/process\n"
"\n"
" fn main() {\n"
" let bot = bot.new(\"TOKEN\", \"CLIENT_ID\")\n"
"\n"
" let assert Ok(_) =\n"
" discord_gleam.simple(bot, [handler])\n"
" |> discord_gleam.start()\n"
"\n"
" process.sleep_forever()\n"
" }\n"
"\n"
" fn handler(bot: bot.Bot, packet: event_handler.Packet) {\n"
" case packet {\n"
" event_handler.ReadyPacket(ready) -> {\n"
" logging.log(logging.Info, \"Logged in as \" <> ready.d.user.username)\n"
" }\n"
"\n"
" _ -> Nil\n"
" }\n"
" }\n"
" ```\n"
).
-spec start(mode(any(), any())) -> {ok,
gleam@otp@actor:started(gleam@erlang@process:subject(discord_gleam@ws@event_loop:event_loop_message()))} |
{error, gleam@otp@actor:start_error()}.
start(Mode) ->
State = booklet_ffi:make(discord_gleam@ws@gateway_state:new()),
discord_gleam@ws@event_loop:start_event_loop(
to_internal_mode(Mode),
<<"gateway.discord.gg"/utf8>>,
false,
<<""/utf8>>,
State
).
-file("src/discord_gleam.gleam", 239).
?DOC(
" Send a message to a channel.\n"
"\n"
" Example:\n"
" ```gleam\n"
" import discord_gleam\n"
"\n"
" fn main() {\n"
" ...\n"
"\n"
" let msg = discord_gleam.send_message(\n"
" bot,\n"
" \"CHANNEL_ID\",\n"
" \"Hello world!\",\n"
" [] // embeds\n"
" )\n"
" }\n"
).
-spec send_message(
discord_gleam@bot:bot(),
discord_gleam@discord@snowflake:snowflake(discord_gleam@discord@snowflake:channel()),
discord_gleam@types@message:message()
) -> {ok, discord_gleam@types@message_send_response:message_send_response()} |
{error, discord_gleam@internal@error:discord_error()}.
send_message(Bot, Channel_id, Message) ->
discord_gleam@http@channels:send_message(
erlang:element(2, Bot),
Channel_id,
Message
).
-file("src/discord_gleam.gleam", 249).
?DOC(
" Create a DM channel with a user. \\\n"
" Returns a channel object, or a DiscordError if it fails.\n"
).
-spec create_dm_channel(
discord_gleam@bot:bot(),
discord_gleam@discord@snowflake:snowflake(discord_gleam@discord@snowflake:user())
) -> {ok, discord_gleam@types@channel:channel()} |
{error, discord_gleam@internal@error:discord_error()}.
create_dm_channel(Bot, User_id) ->
discord_gleam@http@users:create_dm_channel(erlang:element(2, Bot), User_id).
-file("src/discord_gleam.gleam", 261).
?DOC(
" Send a direct message to a user. \\\n"
" Same use as `send_message`, but use user_id instead of channel_id. \\\n"
" `discord_gleam.send_direct_message(bot, \"USER_ID\", \"Hello world!\", [])`\n"
"\n"
" Note: This will return a DiscordError if the DM channel cant be made\n"
).
-spec send_direct_message(
discord_gleam@bot:bot(),
discord_gleam@discord@snowflake:snowflake(discord_gleam@discord@snowflake:user()),
discord_gleam@types@message:message()
) -> {ok, discord_gleam@types@message_send_response:message_send_response()} |
{error, discord_gleam@internal@error:discord_error()}.
send_direct_message(Bot, User_id, Message) ->
discord_gleam@http@users:send_direct_message(
erlang:element(2, Bot),
User_id,
Message
).
-file("src/discord_gleam.gleam", 282).
?DOC(
" Reply to a message in a channel.\n"
"\n"
" Example:\n"
"\n"
" ```gleam\n"
" import discord_gleam\n"
"\n"
" fn main() {\n"
" ...\n"
"\n"
" discord_gleam.reply(bot, \"CHANNEL_ID\", \"MESSAGE_ID\", \"Hello world!\", [])\n"
" }\n"
" ```\n"
).
-spec reply(
discord_gleam@bot:bot(),
discord_gleam@discord@snowflake:snowflake(discord_gleam@discord@snowflake:channel()),
discord_gleam@discord@snowflake:snowflake(discord_gleam@discord@snowflake:message()),
discord_gleam@types@message:message()
) -> {ok, discord_gleam@types@message_send_response:message_send_response()} |
{error, discord_gleam@internal@error:discord_error()}.
reply(Bot, Channel_id, Message_id, Message) ->
Msg = {reply, Message_id, Message},
discord_gleam@http@channels:reply(erlang:element(2, Bot), Channel_id, Msg).
-file("src/discord_gleam.gleam", 308).
?DOC(
" Kicks an member from an server. \\\n"
" The reason will be what is shown in the audit log.\n"
"\n"
" Example:\n"
"\n"
" ```gleam\n"
" import discord_gleam\n"
"\n"
" fn main() {\n"
" ...\n"
"\n"
" discord_gleam.kick_member(bot, \"GUILD_ID\", \"USER_ID\", \"REASON\")\n"
" }\n"
"\n"
" For an full example, see the `examples/kick.gleam` file.\n"
).
-spec kick_member(
discord_gleam@bot:bot(),
discord_gleam@discord@snowflake:snowflake(discord_gleam@discord@snowflake:guild()),
discord_gleam@discord@snowflake:snowflake(discord_gleam@discord@snowflake:user()),
binary()
) -> {ok, nil} | {error, discord_gleam@internal@error:discord_error()}.
kick_member(Bot, Guild_id, User_id, Reason) ->
discord_gleam@http@guilds:kick_member(
erlang:element(2, Bot),
Guild_id,
User_id,
Reason
).
-file("src/discord_gleam.gleam", 317).
-spec ban_member(
discord_gleam@bot:bot(),
discord_gleam@discord@snowflake:snowflake(discord_gleam@discord@snowflake:guild()),
discord_gleam@discord@snowflake:snowflake(discord_gleam@discord@snowflake:user()),
binary()
) -> {ok, nil} | {error, discord_gleam@internal@error:discord_error()}.
ban_member(Bot, Guild_id, User_id, Reason) ->
discord_gleam@http@guilds:ban_member(
erlang:element(2, Bot),
Guild_id,
User_id,
Reason
).
-file("src/discord_gleam.gleam", 345).
?DOC(
" Deletes an message from a channel. \\\n"
" The reason will be what is shown in the audit log.\n"
"\n"
" Example:\n"
" ```gleam\n"
" import discord_gleam\n"
"\n"
" fn main() {\n"
" ...\n"
"\n"
" discord_gleam.delete_message(\n"
" bot,\n"
" \"CHANNEL_ID\",\n"
" \"MESSAGE_ID\",\n"
" \"REASON\",\n"
" )\n"
" }\n"
"\n"
" For an full example, see the `examples/delete_message.gleam` file.\n"
).
-spec delete_message(
discord_gleam@bot:bot(),
discord_gleam@discord@snowflake:snowflake(discord_gleam@discord@snowflake:channel()),
discord_gleam@discord@snowflake:snowflake(discord_gleam@discord@snowflake:message()),
binary()
) -> {ok, nil} | {error, discord_gleam@internal@error:discord_error()}.
delete_message(Bot, Channel_id, Message_id, Reason) ->
discord_gleam@http@channels:delete_message(
erlang:element(2, Bot),
Channel_id,
Message_id,
Reason
).
-file("src/discord_gleam.gleam", 356).
?DOC(
" Edits an existing message in a channel. \\\n"
" The message must have been sent by the bot itself.\n"
).
-spec edit_message(
discord_gleam@bot:bot(),
discord_gleam@discord@snowflake:snowflake(discord_gleam@discord@snowflake:channel()),
discord_gleam@discord@snowflake:snowflake(discord_gleam@discord@snowflake:message()),
discord_gleam@types@message:message()
) -> {ok, nil} | {error, discord_gleam@internal@error:discord_error()}.
edit_message(Bot, Channel_id, Message_id, Message) ->
discord_gleam@http@channels:edit_message(
erlang:element(2, Bot),
Channel_id,
Message_id,
Message
).
-file("src/discord_gleam.gleam", 367).
?DOC(
" Wipes all the global slash commands for the bot. \\\n"
" Restarting your client might be required to see the changes.\n"
).
-spec wipe_global_commands(discord_gleam@bot:bot()) -> {ok, nil} |
{error, discord_gleam@internal@error:discord_error()}.
wipe_global_commands(Bot) ->
discord_gleam@http@applications:wipe_global_commands(
erlang:element(2, Bot),
erlang:element(3, Bot)
).
-file("src/discord_gleam.gleam", 373).
?DOC(
" Wipes all the guild slash commands for the bot. \\\n"
" Restarting your client might be required to see the changes.\n"
).
-spec wipe_guild_commands(
discord_gleam@bot:bot(),
discord_gleam@discord@snowflake:snowflake(discord_gleam@discord@snowflake:guild())
) -> {ok, nil} | {error, discord_gleam@internal@error:discord_error()}.
wipe_guild_commands(Bot, Guild_id) ->
discord_gleam@http@applications:wipe_guild_commands(
erlang:element(2, Bot),
erlang:element(3, Bot),
Guild_id
).
-file("src/discord_gleam.gleam", 382).
?DOC(
" Registers a global slash command. \\\n"
" Restarting your client might be required to see the changes.\n"
).
-spec register_global_commands(
discord_gleam@bot:bot(),
list(discord_gleam@types@slash_command:slash_command())
) -> {ok, nil} |
{error,
{discord_gleam@types@slash_command:slash_command(),
discord_gleam@internal@error:discord_error()}}.
register_global_commands(Bot, Commands) ->
gleam@list:try_each(
Commands,
fun(Command) ->
case discord_gleam@http@applications:register_global_command(
erlang:element(2, Bot),
erlang:element(3, Bot),
Command
) of
{ok, _} ->
{ok, nil};
{error, Err} ->
{error, {Command, Err}}
end
end
).
-file("src/discord_gleam.gleam", 398).
?DOC(
" Registers a guild-specific slash command. \\\n"
" Restarting your client might be required to see the changes.\n"
).
-spec register_guild_commands(
discord_gleam@bot:bot(),
discord_gleam@discord@snowflake:snowflake(discord_gleam@discord@snowflake:guild()),
list(discord_gleam@types@slash_command:slash_command())
) -> {ok, nil} |
{error,
{discord_gleam@types@slash_command:slash_command(),
discord_gleam@internal@error:discord_error()}}.
register_guild_commands(Bot, Guild_id, Commands) ->
gleam@list:try_each(
Commands,
fun(Command) ->
case discord_gleam@http@applications:register_guild_command(
erlang:element(2, Bot),
erlang:element(3, Bot),
Guild_id,
Command
) of
{ok, _} ->
{ok, nil};
{error, Err} ->
{error, {Command, Err}}
end
end
).
-file("src/discord_gleam.gleam", 424).
?DOC(
" Used to request all members of a guild. The server will send\n"
" GUILD_MEMBERS_CHUNK events in response with up to 1000 members per chunk\n"
" until all members that match the request have been sent.\n"
"\n"
" Nonce can only be up to 32 bytes. If you send an invalid nonce it will be\n"
" ignored and the reply member_chunk(s) will not have a nonce set.\n"
).
-spec request_guild_members(
discord_gleam@bot:bot(),
discord_gleam@discord@snowflake:snowflake(discord_gleam@discord@snowflake:guild()),
discord_gleam@ws@commands@request_guild_members:request_guild_members_option(),
gleam@option:option(boolean()),
gleam@option:option(binary())
) -> nil.
request_guild_members(Bot, Guild_id, Option, Presences, Nonce) ->
discord_gleam@ws@commands@request_guild_members:request_guild_members(
Bot,
Guild_id,
Option,
Presences,
Nonce
).
-file("src/discord_gleam.gleam", 442).
?DOC(
" Used to update the bot's activity/presence\n"
" Use with the bot passed from a handler, the normal bot object will not have the necessary websocket data to send the packet\n"
).
-spec update_presence(
discord_gleam@bot:bot(),
discord_gleam@ws@commands@update_presence:presence()
) -> nil.
update_presence(Bot, Presence) ->
discord_gleam@ws@commands@update_presence:update_presence(Bot, Presence).