-module(telega@inline_mode). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/telega/inline_mode.gleam"). -export([new/0, result/2, article_described/5, article/4, photo_captioned/5, photo/4, video/5, document/5, location/5, with_cache_time/2, personal/1, with_next_offset/2, maybe_next_offset/2, with_button/2, results/1, answer/3, paginate/3]). -export_type([inline_query_answer/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. ?MODULEDOC( " Builder for answering inline queries, in the spirit of `keyboard`.\n" "\n" " Covers the most common `InlineQueryResult` variants (article, photo,\n" " video, document, location); anything else can be added with `result`\n" " using the raw types from `telega/model/types`.\n" "\n" " ```gleam\n" " fn handle_inline_query(ctx, query: types.InlineQuery) {\n" " let #(page, next_offset) = inline_mode.paginate(items, offset: query.offset, page_size: 10)\n" "\n" " let assert Ok(_) =\n" " list.index_fold(page, inline_mode.new(), fn(builder, item, index) {\n" " inline_mode.article(builder, id: int.to_string(index), title: item, text: item)\n" " })\n" " |> inline_mode.with_cache_time(300)\n" " |> inline_mode.maybe_next_offset(next_offset)\n" " |> inline_mode.answer(ctx, query.id)\n" "\n" " Ok(ctx)\n" " }\n" " ```\n" ). -opaque inline_query_answer() :: {inline_query_answer, list(telega@model@types:inline_query_result()), gleam@option:option(integer()), gleam@option:option(boolean()), gleam@option:option(binary()), gleam@option:option(telega@model@types:inline_query_results_button())}. -file("src/telega/inline_mode.gleam", 54). ?DOC(" Create an empty inline query answer.\n"). -spec new() -> inline_query_answer(). new() -> {inline_query_answer, [], none, none, none, none}. -file("src/telega/inline_mode.gleam", 232). ?DOC(" Escape hatch: add any `InlineQueryResult` built from `telega/model/types`.\n"). -spec result(inline_query_answer(), telega@model@types:inline_query_result()) -> inline_query_answer(). result(Builder, Result) -> {inline_query_answer, [Result | erlang:element(2, Builder)], erlang:element(3, Builder), erlang:element(4, Builder), erlang:element(5, Builder), erlang:element(6, Builder)}. -file("src/telega/inline_mode.gleam", 75). ?DOC(" Same as `article` with a short description shown under the title.\n"). -spec article_described( inline_query_answer(), binary(), binary(), binary(), gleam@option:option(binary()) ) -> inline_query_answer(). article_described(Builder, Id, Title, Text, Description) -> _pipe = {inline_query_result_article, <<"article"/utf8>>, Id, Title, {input_text_message_content_input_message_content, {input_text_message_content, Text, none, none, none}}, none, none, Description, none, none, none}, _pipe@1 = {inline_query_result_article_inline_query_result, _pipe}, result(Builder, _pipe@1). -file("src/telega/inline_mode.gleam", 65). ?DOC(" Add an article result: shows `title` in the result list, sends `text` when chosen.\n"). -spec article(inline_query_answer(), binary(), binary(), binary()) -> inline_query_answer(). article(Builder, Id, Title, Text) -> article_described(Builder, Id, Title, Text, none). -file("src/telega/inline_mode.gleam", 116). ?DOC(" Same as `photo` with a caption sent along with the photo.\n"). -spec photo_captioned( inline_query_answer(), binary(), binary(), binary(), gleam@option:option(binary()) ) -> inline_query_answer(). photo_captioned(Builder, Id, Url, Thumbnail_url, Caption) -> _pipe = {inline_query_result_photo, <<"photo"/utf8>>, Id, Url, Thumbnail_url, none, none, none, none, Caption, none, none, none, none, none}, _pipe@1 = {inline_query_result_photo_inline_query_result, _pipe}, result(Builder, _pipe@1). -file("src/telega/inline_mode.gleam", 106). ?DOC(" Add a photo result. `url` must point to a JPEG up to 5MB.\n"). -spec photo(inline_query_answer(), binary(), binary(), binary()) -> inline_query_answer(). photo(Builder, Id, Url, Thumbnail_url) -> photo_captioned(Builder, Id, Url, Thumbnail_url, none). -file("src/telega/inline_mode.gleam", 146). ?DOC( " Add an MP4 video result. For embedded players (`text/html`) build\n" " `InlineQueryResultVideo` manually and add it with `result` — Telegram\n" " requires `input_message_content` for those.\n" ). -spec video(inline_query_answer(), binary(), binary(), binary(), binary()) -> inline_query_answer(). video(Builder, Id, Url, Thumbnail_url, Title) -> _pipe = {inline_query_result_video, <<"video"/utf8>>, Id, Url, <<"video/mp4"/utf8>>, Thumbnail_url, Title, none, none, none, none, none, none, none, none, none, none}, _pipe@1 = {inline_query_result_video_inline_query_result, _pipe}, result(Builder, _pipe@1). -file("src/telega/inline_mode.gleam", 176). ?DOC(" Add a document result. `mime_type` must be `\"application/pdf\"` or `\"application/zip\"`.\n"). -spec document(inline_query_answer(), binary(), binary(), binary(), binary()) -> inline_query_answer(). document(Builder, Id, Title, Url, Mime_type) -> _pipe = {inline_query_result_document, <<"document"/utf8>>, Id, Title, none, none, none, Url, Mime_type, none, none, none, none, none, none}, _pipe@1 = {inline_query_result_document_inline_query_result, _pipe}, result(Builder, _pipe@1). -file("src/telega/inline_mode.gleam", 204). ?DOC(" Add a location result.\n"). -spec location(inline_query_answer(), binary(), float(), float(), binary()) -> inline_query_answer(). location(Builder, Id, Latitude, Longitude, Title) -> _pipe = {inline_query_result_location, <<"location"/utf8>>, Id, Latitude, Longitude, Title, none, none, none, none, none, none, none, none, none}, _pipe@1 = {inline_query_result_location_inline_query_result, _pipe}, result(Builder, _pipe@1). -file("src/telega/inline_mode.gleam", 240). ?DOC(" Maximum time in seconds the result may be cached on Telegram servers (default 300).\n"). -spec with_cache_time(inline_query_answer(), integer()) -> inline_query_answer(). with_cache_time(Builder, Seconds) -> {inline_query_answer, erlang:element(2, Builder), {some, Seconds}, erlang:element(4, Builder), erlang:element(5, Builder), erlang:element(6, Builder)}. -file("src/telega/inline_mode.gleam", 248). ?DOC(" Cache results only for the user that sent the query.\n"). -spec personal(inline_query_answer()) -> inline_query_answer(). personal(Builder) -> {inline_query_answer, erlang:element(2, Builder), erlang:element(3, Builder), {some, true}, erlang:element(5, Builder), erlang:element(6, Builder)}. -file("src/telega/inline_mode.gleam", 253). ?DOC(" Offset the client sends in the next query to fetch more results.\n"). -spec with_next_offset(inline_query_answer(), binary()) -> inline_query_answer(). with_next_offset(Builder, Offset) -> {inline_query_answer, erlang:element(2, Builder), erlang:element(3, Builder), erlang:element(4, Builder), {some, Offset}, erlang:element(6, Builder)}. -file("src/telega/inline_mode.gleam", 261). ?DOC(" Set the next offset when there are more pages — pairs with `paginate`.\n"). -spec maybe_next_offset(inline_query_answer(), gleam@option:option(binary())) -> inline_query_answer(). maybe_next_offset(Builder, Offset) -> case Offset of {some, Offset@1} -> with_next_offset(Builder, Offset@1); none -> Builder end. -file("src/telega/inline_mode.gleam", 272). ?DOC(" Button shown above the inline results.\n"). -spec with_button( inline_query_answer(), telega@model@types:inline_query_results_button() ) -> inline_query_answer(). with_button(Builder, Button) -> {inline_query_answer, erlang:element(2, Builder), erlang:element(3, Builder), erlang:element(4, Builder), erlang:element(5, Builder), {some, Button}}. -file("src/telega/inline_mode.gleam", 280). ?DOC(" Added results in the order they were added.\n"). -spec results(inline_query_answer()) -> list(telega@model@types:inline_query_result()). results(Builder) -> lists:reverse(erlang:element(2, Builder)). -file("src/telega/inline_mode.gleam", 286). ?DOC( " Send the accumulated results as the answer to an inline query.\n" " No more than 50 results per query are allowed.\n" ). -spec answer( inline_query_answer(), telega@bot:context(any(), any(), any()), binary() ) -> {ok, boolean()} | {error, telega@error:telega_error()}. answer(Builder, Ctx, Query_id) -> telega@api:answer_inline_query( erlang:element(5, erlang:element(4, Ctx)), {answer_inline_query_parameters, Query_id, results(Builder), erlang:element(3, Builder), erlang:element(4, Builder), erlang:element(5, Builder), erlang:element(6, Builder)} ). -file("src/telega/inline_mode.gleam", 307). ?DOC( " Slice `items` for the page requested by `offset` (the raw\n" " `InlineQuery.offset` string, empty on the first query) and compute the\n" " offset of the next page, `None` when this page is the last one.\n" ). -spec paginate(list(BBDB), binary(), integer()) -> {list(BBDB), gleam@option:option(binary())}. paginate(Items, Offset, Page_size) -> Start = case gleam_stdlib:parse_int(Offset) of {ok, Parsed} when Parsed >= 0 -> Parsed; _ -> 0 end, Rest = gleam@list:drop(Items, Start), Page = gleam@list:take(Rest, Page_size), Next_offset = case erlang:length(Rest) > Page_size of true -> {some, erlang:integer_to_binary(Start + Page_size)}; false -> none end, {Page, Next_offset}.