-module(telega@update). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). -export([decode/1]). -export_type([update/0, command/0]). -type update() :: {text_update, integer(), binary(), telega@model:message()} | {command_update, integer(), command(), telega@model:message()} | {callback_query_update, integer(), telega@model:callback_query()} | {unknown_update, telega@model:update()}. -type command() :: {command, binary(), binary(), gleam@option:option(binary())}. -spec try_decode_to_callback_query( telega@model:update(), fun(() -> {ok, update()} | {error, binary()}) ) -> {ok, update()} | {error, binary()}. try_decode_to_callback_query(Raw_update, On_none) -> case erlang:element(5, Raw_update) of {some, Callback_query} -> {ok, {callback_query_update, erlang:element(2, erlang:element(3, Callback_query)), Callback_query}}; none -> On_none() end. -spec is_command_update(binary(), telega@model:update()) -> boolean(). is_command_update(Text, Raw_update) -> gleam@bool:guard( not gleam@string:starts_with(Text, <<"/"/utf8>>), false, fun() -> case erlang:element(3, Raw_update) of {some, Message} -> case erlang:element(19, Message) of {some, Entities} -> Is_command_entity = fun(Entity) -> ((erlang:element(2, Entity) =:= <<"bot_command"/utf8>>) andalso (erlang:element(3, Entity) =:= 0)) andalso (erlang:element(4, Entity) =:= gleam@string:length( Text )) end, gleam@list:any(Entities, Is_command_entity); none -> false end; none -> false end end ). -spec extract_command(binary()) -> command(). extract_command(Text) -> case gleam@string:split(Text, <<" "/utf8>>) of [Command | Payload] -> {command, Text, gleam@string:drop_left(Command, 1), begin _pipe = Payload, _pipe@1 = gleam@string:join(_pipe, <<" "/utf8>>), {some, _pipe@1} end}; [] -> {command, Text, <<""/utf8>>, none} end. -spec try_to_decode_message_or_command( telega@model:update(), fun(() -> {ok, update()} | {error, binary()}) ) -> {ok, update()} | {error, binary()}. try_to_decode_message_or_command(Raw_update, On_none) -> case erlang:element(3, Raw_update) of {some, Message} -> case erlang:element(18, Message) of {some, Text} -> case is_command_update(Text, Raw_update) of true -> {ok, {command_update, erlang:element( 2, erlang:element(8, Message) ), extract_command(Text), Message}}; false -> {ok, {text_update, erlang:element( 2, erlang:element(8, Message) ), Text, Message}} end; none -> On_none() end; none -> On_none() end. -spec decode(gleam@dynamic:dynamic_()) -> {ok, update()} | {error, binary()}. decode(Json) -> gleam@result:'try'( begin _pipe = telega@model:decode_update(Json), gleam@result:map_error( _pipe, fun(E) -> <<"Cannot decode update: "/utf8, (gleam@string:inspect(E))/binary>> end ) end, fun(Raw_update) -> try_decode_to_callback_query( Raw_update, fun() -> try_to_decode_message_or_command( Raw_update, fun() -> {ok, {unknown_update, Raw_update}} end ) end ) end ).