telegram_bot_api_rs 0.1.1

Telegram Bot Api Rust Library
Documentation
pub mod payload;
pub mod types;
pub mod webhook;

use serde::{Deserialize, Serialize};
use tokio::sync::broadcast::Receiver;
use types::{AllowedUpdateType, Update, UpdateData};

use crate::bot::Bot;

#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct GetUpdatesResponse {
    ok: bool,
    #[serde(default)]
    result: Vec<Update>,
    error_code: Option<i64>,
    description: Option<String>,
}

#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct GetUpdateConfig {
    pub limit: u8,
    pub timeout: u16,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub offset: Option<i64>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub allowed_updates: Option<Vec<AllowedUpdateType>>,
}

impl Default for GetUpdateConfig {
    fn default() -> Self {
        Self {
            limit: 100,
            timeout: 60,
            offset: None,
            allowed_updates: None,
        }
    }
}

impl Bot {
    pub fn subscribe_updates(&self) -> Receiver<UpdateData> {
        self.sender.subscribe()
    }

    pub fn start_get_updates(&self, mut config: GetUpdateConfig) {
        let url = self.format_url("getUpdates");
        let client = self.client.clone();
        let mut last_update_id: Option<i64> = None;
        let sender = self.sender.clone();

        tokio::spawn(async move {
            loop {
                if let Some(id) = last_update_id {
                    config.offset = Some(id + 1);
                }

                let response = client.post(&url).json(&config).send().await;

                match response {
                    Ok(response) => match response.json::<GetUpdatesResponse>().await {
                        Ok(response) => match response.ok {
                            true => {
                                for update in response.result {
                                    if let Err(e) = sender.send(update.data) {
                                        tracing::error!(
                                            "Failed to send update to subscriber: {}",
                                            e
                                        );
                                    }
                                    last_update_id = Some(update.update_id);
                                }
                            }
                            false => {
                                tracing::error!(
                                    "Failed to get updates, Code: {}, Description: {}",
                                    response.error_code.unwrap_or(0),
                                    response.description.unwrap_or("No description".to_string())
                                );
                            }
                        },
                        Err(e) => {
                            tracing::error!("Failed to parse getUpdates response: {}", e);
                            continue;
                        }
                    },
                    Err(e) => {
                        tracing::error!("Failed to get updates: {}", e);
                        continue;
                    }
                }
            }
        });
    }
}