-module(telega@message). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). -export([decode/1]). -export_type([chat/0, user/0, message_entity/0, inline_keyboard_button/0, inline_keyboard_markup/0, raw_message/0, update/0, message_kind/0, message/0]). -type chat() :: {chat, integer(), gleam@option:option(binary()), gleam@option:option(binary()), gleam@option:option(binary()), gleam@option:option(boolean())}. -type user() :: {user, integer(), boolean(), binary(), binary(), gleam@option:option(binary()), gleam@option:option(binary()), gleam@option:option(boolean()), gleam@option:option(boolean())}. -type message_entity() :: {message_entity, binary(), integer(), integer(), gleam@option:option(binary()), gleam@option:option(user()), gleam@option:option(binary()), gleam@option:option(binary())}. -type inline_keyboard_button() :: {inline_keyboard_button, binary(), gleam@option:option(binary()), gleam@option:option(binary())}. -type inline_keyboard_markup() :: {inline_keyboard_markup, list(list(inline_keyboard_button()))}. -type raw_message() :: {raw_message, integer(), gleam@option:option(integer()), gleam@option:option(user()), gleam@option:option(chat()), gleam@option:option(integer()), integer(), chat(), gleam@option:option(boolean()), gleam@option:option(boolean()), gleam@option:option(raw_message()), gleam@option:option(user()), gleam@option:option(integer()), gleam@option:option(boolean()), gleam@option:option(binary()), gleam@option:option(binary()), gleam@option:option(binary()), gleam@option:option(list(message_entity())), gleam@option:option(binary()), gleam@option:option(list(message_entity())), gleam@option:option(boolean()), gleam@option:option(list(user())), gleam@option:option(user()), gleam@option:option(binary()), gleam@option:option(boolean()), gleam@option:option(boolean()), gleam@option:option(boolean()), gleam@option:option(boolean()), gleam@option:option(integer()), gleam@option:option(integer()), gleam@option:option(binary()), gleam@option:option(inline_keyboard_markup())}. -type update() :: {update, raw_message(), integer()}. -type message_kind() :: common_message | command_message | text_message. -type message() :: {message, message_kind(), raw_message()}. -spec is_command_message(binary(), raw_message()) -> boolean(). is_command_message(Text, Raw_message) -> gleam@bool:guard( not gleam@string:starts_with(Text, <<"/"/utf8>>), false, fun() -> case erlang:element(18, Raw_message) of none -> false; {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) end end ). -spec raw_message_to_message(raw_message()) -> message(). raw_message_to_message(Raw_message) -> case erlang:element(17, Raw_message) of none -> {message, common_message, Raw_message}; {some, Text} -> case is_command_message(Text, Raw_message) of true -> {message, command_message, Raw_message}; false -> {message, text_message, Raw_message} end end. -spec user_decoder() -> fun((gleam@dynamic:dynamic_()) -> {ok, user()} | {error, list(gleam@dynamic:decode_error())}). user_decoder() -> gleam@dynamic:decode8( fun(Field@0, Field@1, Field@2, Field@3, Field@4, Field@5, Field@6, Field@7) -> {user, Field@0, Field@1, Field@2, Field@3, Field@4, Field@5, Field@6, Field@7} end, gleam@dynamic:field(<<"id"/utf8>>, fun gleam@dynamic:int/1), gleam@dynamic:field(<<"is_bot"/utf8>>, fun gleam@dynamic:bool/1), gleam@dynamic:field(<<"first_name"/utf8>>, fun gleam@dynamic:string/1), gleam@dynamic:field(<<"last_name"/utf8>>, fun gleam@dynamic:string/1), gleam@dynamic:optional_field( <<"username"/utf8>>, fun gleam@dynamic:string/1 ), gleam@dynamic:optional_field( <<"language_code"/utf8>>, fun gleam@dynamic:string/1 ), gleam@dynamic:optional_field( <<"is_premium"/utf8>>, fun gleam@dynamic:bool/1 ), gleam@dynamic:optional_field( <<"added_to_attachment_menu"/utf8>>, fun gleam@dynamic:bool/1 ) ). -spec chat_decoder() -> fun((gleam@dynamic:dynamic_()) -> {ok, chat()} | {error, list(gleam@dynamic:decode_error())}). chat_decoder() -> gleam@dynamic:decode5( fun(Field@0, Field@1, Field@2, Field@3, Field@4) -> {chat, Field@0, Field@1, Field@2, Field@3, Field@4} end, gleam@dynamic:field(<<"id"/utf8>>, fun gleam@dynamic:int/1), gleam@dynamic:optional_field( <<"username"/utf8>>, fun gleam@dynamic:string/1 ), gleam@dynamic:optional_field( <<"first_name"/utf8>>, fun gleam@dynamic:string/1 ), gleam@dynamic:optional_field( <<"last_name"/utf8>>, fun gleam@dynamic:string/1 ), gleam@dynamic:optional_field( <<"is_forum"/utf8>>, fun gleam@dynamic:bool/1 ) ). -spec message_entity_decoder() -> fun((gleam@dynamic:dynamic_()) -> {ok, message_entity()} | {error, list(gleam@dynamic:decode_error())}). message_entity_decoder() -> gleam@dynamic:decode7( fun(Field@0, Field@1, Field@2, Field@3, Field@4, Field@5, Field@6) -> {message_entity, Field@0, Field@1, Field@2, Field@3, Field@4, Field@5, Field@6} end, gleam@dynamic:field(<<"type"/utf8>>, fun gleam@dynamic:string/1), gleam@dynamic:field(<<"offset"/utf8>>, fun gleam@dynamic:int/1), gleam@dynamic:field(<<"length"/utf8>>, fun gleam@dynamic:int/1), gleam@dynamic:optional_field(<<"url"/utf8>>, fun gleam@dynamic:string/1), gleam@dynamic:optional_field(<<"user"/utf8>>, user_decoder()), gleam@dynamic:optional_field( <<"language"/utf8>>, fun gleam@dynamic:string/1 ), gleam@dynamic:optional_field( <<"custom_emoji_id"/utf8>>, fun gleam@dynamic:string/1 ) ). -spec inline_keyboard_button_decoder() -> fun((gleam@dynamic:dynamic_()) -> {ok, inline_keyboard_button()} | {error, list(gleam@dynamic:decode_error())}). inline_keyboard_button_decoder() -> gleam@dynamic:decode3( fun(Field@0, Field@1, Field@2) -> {inline_keyboard_button, Field@0, Field@1, Field@2} end, gleam@dynamic:field(<<"text"/utf8>>, fun gleam@dynamic:string/1), gleam@dynamic:optional_field(<<"url"/utf8>>, fun gleam@dynamic:string/1), gleam@dynamic:optional_field( <<"callback_data"/utf8>>, fun gleam@dynamic:string/1 ) ). -spec inline_keyboard_markup_decoder() -> fun((gleam@dynamic:dynamic_()) -> {ok, inline_keyboard_markup()} | {error, list(gleam@dynamic:decode_error())}). inline_keyboard_markup_decoder() -> gleam@dynamic:decode1( fun(Field@0) -> {inline_keyboard_markup, Field@0} end, gleam@dynamic:field( <<"inline_keyboard"/utf8>>, gleam@dynamic:list( gleam@dynamic:list(inline_keyboard_button_decoder()) ) ) ). -spec all_errors({ok, any()} | {error, list(gleam@dynamic:decode_error())}) -> list(gleam@dynamic:decode_error()). all_errors(Result) -> case Result of {ok, _} -> []; {error, Errors} -> Errors end. -spec decode_raw_message(gleam@dynamic:dynamic_()) -> {ok, raw_message()} | {error, list(gleam@dynamic:decode_error())}. decode_raw_message(Raw_message) -> Decode_user = user_decoder(), Decode_chat = chat_decoder(), Decode_message_entity = message_entity_decoder(), Decode_inline_keyboard_markup = inline_keyboard_markup_decoder(), Decode_message_id = gleam@dynamic:field( <<"message_id"/utf8>>, fun gleam@dynamic:int/1 ), Decode_message_thread_id = gleam@dynamic:optional_field( <<"message_thread_id"/utf8>>, fun gleam@dynamic:int/1 ), Decode_from = gleam@dynamic:optional_field(<<"from"/utf8>>, Decode_user), Decode_sender_chat = gleam@dynamic:optional_field( <<"sender_chat"/utf8>>, Decode_chat ), Decode_sender_boost_count = gleam@dynamic:optional_field( <<"sender_boost_count"/utf8>>, fun gleam@dynamic:int/1 ), Decode_date = gleam@dynamic:field(<<"date"/utf8>>, fun gleam@dynamic:int/1), Decode_chat@1 = gleam@dynamic:field(<<"chat"/utf8>>, Decode_chat), Decode_is_topic_message = gleam@dynamic:optional_field( <<"is_topic_message"/utf8>>, fun gleam@dynamic:bool/1 ), Decode_is_automatic_forward = gleam@dynamic:optional_field( <<"is_automatic_forward"/utf8>>, fun gleam@dynamic:bool/1 ), Decode_reply_to_message = gleam@dynamic:optional_field( <<"reply_to_message"/utf8>>, fun decode_raw_message/1 ), Decode_via_bot = gleam@dynamic:optional_field( <<"via_bot"/utf8>>, Decode_user ), Decode_edit_date = gleam@dynamic:optional_field( <<"edit_date"/utf8>>, fun gleam@dynamic:int/1 ), Decode_has_protected_content = gleam@dynamic:optional_field( <<"has_protected_content"/utf8>>, fun gleam@dynamic:bool/1 ), Decode_media_group_id = gleam@dynamic:optional_field( <<"media_group_id"/utf8>>, fun gleam@dynamic:string/1 ), Decode_author_signature = gleam@dynamic:optional_field( <<"author_signature"/utf8>>, fun gleam@dynamic:string/1 ), Decode_text = gleam@dynamic:optional_field( <<"text"/utf8>>, fun gleam@dynamic:string/1 ), Decode_entities = gleam@dynamic:optional_field( <<"entities"/utf8>>, gleam@dynamic:list(Decode_message_entity) ), Decode_caption = gleam@dynamic:optional_field( <<"caption"/utf8>>, fun gleam@dynamic:string/1 ), Decode_caption_entities = gleam@dynamic:optional_field( <<"caption_entities"/utf8>>, gleam@dynamic:list(Decode_message_entity) ), Decode_has_media_spoiler = gleam@dynamic:optional_field( <<"has_media_spoiler"/utf8>>, fun gleam@dynamic:bool/1 ), Decode_new_chat_members = gleam@dynamic:optional_field( <<"new_chat_members"/utf8>>, gleam@dynamic:list(Decode_user) ), Decode_left_chat_member = gleam@dynamic:optional_field( <<"left_chat_member"/utf8>>, Decode_user ), Decode_new_chat_title = gleam@dynamic:optional_field( <<"new_chat_title"/utf8>>, fun gleam@dynamic:string/1 ), Decode_delete_chat_photo = gleam@dynamic:optional_field( <<"delete_chat_photo"/utf8>>, fun gleam@dynamic:bool/1 ), Decode_group_chat_created = gleam@dynamic:optional_field( <<"group_chat_created"/utf8>>, fun gleam@dynamic:bool/1 ), Decode_supergroup_chat_created = gleam@dynamic:optional_field( <<"supergroup_chat_created"/utf8>>, fun gleam@dynamic:bool/1 ), Decode_channel_chat_created = gleam@dynamic:optional_field( <<"channel_chat_created"/utf8>>, fun gleam@dynamic:bool/1 ), Decode_migrate_to_chat_id = gleam@dynamic:optional_field( <<"migrate_to_chat_id"/utf8>>, fun gleam@dynamic:int/1 ), Decode_migrate_from_chat_id = gleam@dynamic:optional_field( <<"migrate_from_chat_id"/utf8>>, fun gleam@dynamic:int/1 ), Decode_connected_website = gleam@dynamic:optional_field( <<"connected_website"/utf8>>, fun gleam@dynamic:string/1 ), Decode_inline_keyboard_markup@1 = gleam@dynamic:optional_field( <<"reply_markup"/utf8>>, Decode_inline_keyboard_markup ), case {Decode_message_id(Raw_message), Decode_message_thread_id(Raw_message), Decode_from(Raw_message), Decode_sender_chat(Raw_message), Decode_sender_boost_count(Raw_message), Decode_date(Raw_message), Decode_chat@1(Raw_message), Decode_is_topic_message(Raw_message), Decode_is_automatic_forward(Raw_message), Decode_reply_to_message(Raw_message), Decode_via_bot(Raw_message), Decode_edit_date(Raw_message), Decode_has_protected_content(Raw_message), Decode_media_group_id(Raw_message), Decode_author_signature(Raw_message), Decode_text(Raw_message), Decode_entities(Raw_message), Decode_caption(Raw_message), Decode_caption_entities(Raw_message), Decode_has_media_spoiler(Raw_message), Decode_new_chat_members(Raw_message), Decode_left_chat_member(Raw_message), Decode_new_chat_title(Raw_message), Decode_delete_chat_photo(Raw_message), Decode_group_chat_created(Raw_message), Decode_supergroup_chat_created(Raw_message), Decode_channel_chat_created(Raw_message), Decode_migrate_to_chat_id(Raw_message), Decode_migrate_from_chat_id(Raw_message), Decode_connected_website(Raw_message), Decode_inline_keyboard_markup@1(Raw_message)} of {{ok, Message_id}, {ok, Message_thread_id}, {ok, From}, {ok, Sender_chat}, {ok, Sender_boost_count}, {ok, Date}, {ok, Chat}, {ok, Is_topic_message}, {ok, Is_automatic_forward}, {ok, Reply_to_message}, {ok, Via_bot}, {ok, Edit_date}, {ok, Has_protected_content}, {ok, Media_group_id}, {ok, Author_signature}, {ok, Text}, {ok, Entities}, {ok, Caption}, {ok, Caption_entities}, {ok, Has_media_spoiler}, {ok, New_chat_members}, {ok, Left_chat_member}, {ok, New_chat_title}, {ok, Delete_chat_photo}, {ok, Group_chat_created}, {ok, Supergroup_chat_created}, {ok, Channel_chat_created}, {ok, Migrate_to_chat_id}, {ok, Migrate_from_chat_id}, {ok, Connected_website}, {ok, Inline_keyboard_markup}} -> {ok, {raw_message, Message_id, Message_thread_id, From, Sender_chat, Sender_boost_count, Date, Chat, Is_topic_message, Is_automatic_forward, Reply_to_message, Via_bot, Edit_date, Has_protected_content, Media_group_id, Author_signature, Text, Entities, Caption, Caption_entities, Has_media_spoiler, New_chat_members, Left_chat_member, New_chat_title, Delete_chat_photo, Group_chat_created, Supergroup_chat_created, Channel_chat_created, Migrate_to_chat_id, Migrate_from_chat_id, Connected_website, Inline_keyboard_markup}}; {Message_id@1, Message_thread_id@1, From@1, Sender_chat@1, Sender_boost_count@1, Date@1, Chat@1, Is_topic_message@1, Is_automatic_forward@1, Reply_to_message@1, Via_bot@1, Edit_date@1, Has_protected_content@1, Media_group_id@1, Author_signature@1, Text@1, Entities@1, Caption@1, Caption_entities@1, Has_media_spoiler@1, New_chat_members@1, Left_chat_member@1, New_chat_title@1, Delete_chat_photo@1, Group_chat_created@1, Supergroup_chat_created@1, Channel_chat_created@1, Migrate_to_chat_id@1, Migrate_from_chat_id@1, Connected_website@1, Inline_keyboard_markup@1} -> {error, gleam@list:concat( [all_errors(Message_id@1), all_errors(Message_thread_id@1), all_errors(From@1), all_errors(Sender_chat@1), all_errors(Sender_boost_count@1), all_errors(Date@1), all_errors(Chat@1), all_errors(Is_topic_message@1), all_errors(Is_automatic_forward@1), all_errors(Reply_to_message@1), all_errors(Via_bot@1), all_errors(Edit_date@1), all_errors(Has_protected_content@1), all_errors(Media_group_id@1), all_errors(Author_signature@1), all_errors(Text@1), all_errors(Entities@1), all_errors(Caption@1), all_errors(Caption_entities@1), all_errors(Has_media_spoiler@1), all_errors(New_chat_members@1), all_errors(Left_chat_member@1), all_errors(New_chat_title@1), all_errors(Delete_chat_photo@1), all_errors(Group_chat_created@1), all_errors(Supergroup_chat_created@1), all_errors(Channel_chat_created@1), all_errors(Migrate_to_chat_id@1), all_errors(Migrate_from_chat_id@1), all_errors(Connected_website@1), all_errors(Inline_keyboard_markup@1)] )} end. -spec update_decoder() -> fun((gleam@dynamic:dynamic_()) -> {ok, update()} | {error, list(gleam@dynamic:decode_error())}). update_decoder() -> gleam@dynamic:decode2( fun(Field@0, Field@1) -> {update, Field@0, Field@1} end, gleam@dynamic:field(<<"message"/utf8>>, fun decode_raw_message/1), gleam@dynamic:field(<<"update_id"/utf8>>, fun gleam@dynamic:int/1) ). -spec decode(gleam@dynamic:dynamic_()) -> {ok, message()} | {error, list(gleam@dynamic:decode_error())}. decode(Json) -> Decode = update_decoder(), gleam@result:'try'( Decode(Json), fun(Raw_message_update) -> {ok, raw_message_to_message(erlang:element(2, Raw_message_update))} end ).