Current section
Files
Jump to
Current section
Files
src/discord_gleam@ws@event_loop.erl
-module(discord_gleam@ws@event_loop).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export([main/2]).
-export_type([msg/0, state/0]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
-type msg() :: close | {time_updated, binary()}.
-type state() :: {state, boolean(), integer()}.
-file("src/discord_gleam/ws/event_loop.gleam", 27).
?DOC(" Start the event loop, with a set of event handlers.\n").
-spec main(
discord_gleam@types@bot:bot(),
list(fun((discord_gleam@types@bot:bot(), discord_gleam@event_handler:packet()) -> nil))
) -> nil.
main(Bot, Event_handlers) ->
logging:log(debug, <<"Requesting gateway"/utf8>>),
Req = begin
_pipe = gleam@http@request:new(),
_pipe@1 = gleam@http@request:set_host(
_pipe,
<<"gateway.discord.gg"/utf8>>
),
_pipe@2 = gleam@http@request:set_scheme(_pipe@1, https),
_pipe@3 = gleam@http@request:set_path(
_pipe@2,
<<"/?v=10&encoding=json"/utf8>>
),
_pipe@4 = gleam@http@request:set_header(
_pipe@3,
<<"User-Agent"/utf8>>,
<<"DiscordBot (https://github.com/cyteon/discord_gleam, 0.2.3)"/utf8>>
),
_pipe@5 = gleam@http@request:set_header(
_pipe@4,
<<"Host"/utf8>>,
<<"gateway.discord.gg"/utf8>>
),
_pipe@6 = gleam@http@request:set_header(
_pipe@5,
<<"Connection"/utf8>>,
<<"Upgrade"/utf8>>
),
_pipe@7 = gleam@http@request:set_header(
_pipe@6,
<<"Upgrade"/utf8>>,
<<"websocket"/utf8>>
),
gleam@http@request:set_header(
_pipe@7,
<<"Sec-WebSocket-Version"/utf8>>,
<<"13"/utf8>>
)
end,
logging:log(debug, <<"Creating builder"/utf8>>),
Initial_state = {state, false, 0},
Builder = begin
_pipe@8 = stratus:websocket(
Req,
fun() ->
logging:log(debug, <<"Builder init"/utf8>>),
{Initial_state, none}
end,
fun(Msg, State, Conn) -> case Msg of
{text, Msg@1} ->
logging:log(debug, Msg@1),
case erlang:element(2, State) of
false ->
Identify = discord_gleam@ws@packets@identify:create_packet(
erlang:element(2, Bot),
erlang:element(4, Bot)
),
_ = stratus:send_text_message(Conn, Identify),
New_state = {state, true, 0},
Heartbeat = discord_gleam@ws@packets@hello:string_to_data(
Msg@1
),
gleam@erlang@process:start(
fun() ->
repeatedly_ffi:call(
Heartbeat,
nil,
fun(_, _) ->
Packet = <<<<"{\"op\": 1, \"d\": null, \"s\": "/utf8,
(erlang:integer_to_binary(
erlang:element(
3,
State
)
))/binary>>/binary,
"}"/utf8>>,
logging:log(
debug,
<<"Sending heartbeat: "/utf8,
Packet/binary>>
),
stratus:send_text_message(
Conn,
Packet
)
end
)
end,
false
),
gleam@otp@actor:continue(New_state);
true ->
Generic_packet = discord_gleam@ws@packets@generic:string_to_data(
Msg@1
),
New_state@1 = {state,
true,
erlang:element(3, Generic_packet)},
discord_gleam@event_handler:handle_event(
Bot,
Msg@1,
Event_handlers
),
gleam@otp@actor:continue(New_state@1)
end;
{user, Msg@2} ->
logging:log(debug, Msg@2),
gleam@otp@actor:continue(State);
{binary, _} ->
logging:log(debug, <<"Binary message"/utf8>>),
gleam@otp@actor:continue(State)
end end
),
stratus:on_close(
_pipe@8,
fun(_) ->
logging:log(
error,
<<"oh nyo, discord closed websocket :c"/utf8>>
)
end
)
end,
_assert_subject = stratus:initialize(Builder),
{ok, Subj} = case _assert_subject of
{ok, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
value => _assert_fail,
module => <<"discord_gleam/ws/event_loop"/utf8>>,
function => <<"main"/utf8>>,
line => 117})
end,
_pipe@9 = gleam_erlang_ffi:new_selector(),
_pipe@10 = gleam@erlang@process:selecting_process_down(
_pipe@9,
gleam@erlang@process:monitor_process(
gleam@erlang@process:subject_owner(Subj)
),
fun gleam@function:identity/1
),
gleam_erlang_ffi:select(_pipe@10),
gleam_erlang_ffi:sleep(10000),
logging:log(info, <<"websocket go bye bye"/utf8>>).