diff --git a/src/telega/api.gleam b/src/telega/api.gleam index ea7d9a3..7fb13ff 100644 --- a/src/telega/api.gleam +++ b/src/telega/api.gleam @@ -15,7 +15,7 @@ import gleam/string import telega/log import telega/model.{ type AnswerCallbackQueryParameters, type BotCommand, type BotCommandParameters, - type EditMessageTextParameters, type EditMessageTextResult, + type EditMessageTextParameters, type EditMessageTextResult, type File, type ForwardMessageParameters, type Message as ModelMessage, type SendDiceParameters, type SendMessageParameters, type User, type WebhookInfo, @@ -325,6 +325,15 @@ fn build_url(config: TelegramApiConfig, path: String) -> String { config.tg_api_url <> config.token <> "/" <> path } +pub fn get_file( + config config: TelegramApiConfig, + file_id file_id: String, +) -> Result(File, String) { + new_get_request(config, path: "getFile", query: Some([#("file_id", file_id)])) + |> fetch(config) + |> map_resonse(model.decode_file) +} + fn new_post_request( config config: TelegramApiConfig, path path: String, diff --git a/src/telega/model.gleam b/src/telega/model.gleam index 4949baa..17db22d 100644 --- a/src/telega/model.gleam +++ b/src/telega/model.gleam @@ -2146,6 +2146,36 @@ pub fn encode_set_webhook_parameters(params: SetWebhookParameters) -> Json { ]) } +// File -------------------------------------------------------------------------------------------------------------- + +/// https://core.telegram.org/bots/api#file +pub type File { + /// This object represents a file ready to be downloaded. The file can be downloaded via the link `https://api.telegram.org/file/bot/`. It is guaranteed that the link will be valid for at least 1 hour. When the link expires, a new one can be requested by calling [getFile](https://core.telegram.org/bots/api#getfile). + /// + /// **Official reference:** [File](https://core.telegram.org/bots/api#file) + File( + /// Unique identifier for this file + file_id: String, + /// _Optional_. Unique identifier for this file, which is supposed to be the same over time and for different bots. Can't be used to download or reuse the file + file_unique_id: Option(String), + /// _Optional_. File size, if known + file_size: Option(Int), + /// _Optional_. File path. Use `https://api.telegram.org/file/bot/` to get the file + file_path: Option(String), + ) +} + +pub fn decode_file(json: Dynamic) -> Result(File, dynamic.DecodeErrors) { + json + |> dynamic.decode4( + File, + dynamic.field("file_id", dynamic.string), + dynamic.optional_field("file_unique_id", dynamic.string), + dynamic.optional_field("file_size", dynamic.int), + dynamic.optional_field("file_path", dynamic.string), + ) +} + // Common ------------------------------------------------------------------------------------------------------------ pub type IntOrString { diff --git a/src/telega/reply.gleam b/src/telega/reply.gleam index f28b883..a744b89 100644 --- a/src/telega/reply.gleam +++ b/src/telega/reply.gleam @@ -1,4 +1,5 @@ import gleam/option.{type Option} +import gleam/result import telega/api import telega/bot.{type Context} import telega/model.{ @@ -90,3 +91,23 @@ pub fn answer_callback_query( ) -> Result(Bool, String) { api.answer_callback_query(ctx.config.api, parameters) } + +/// Get download link for the file. +pub fn with_file_link( + ctx ctx: Context(session), + file_id file_id: String, +) -> Result(String, String) { + use file <- result.try(api.get_file(ctx.config.api, file_id)) + use file_path <- result.try(option.to_result( + file.file_path, + "File path is missing", + )) + + Ok( + ctx.config.api.tg_api_url + <> "/file/bot" + <> ctx.config.secret_token + <> "/" + <> file_path, + ) +}