Skip to main content

botkit_telegram/
action.rs

1use std::time::Duration;
2
3use botkit_core::BotError;
4use botkit_core::action::{ChatAction, ChatActionFutureBounds, ChatActionSender};
5
6use crate::client::TelegramClient;
7
8/// Telegram chat action sender
9///
10/// Sends chat actions to Telegram with appropriate action strings.
11#[derive(Clone)]
12pub struct TelegramActionSender {
13    client: TelegramClient,
14    chat_id: i64,
15    /// Forum topic to scope the action to, when the chat has topics.
16    thread_id: Option<i64>,
17}
18
19impl TelegramActionSender {
20    /// Create a new Telegram action sender
21    pub fn new(client: TelegramClient, chat_id: i64, thread_id: Option<i64>) -> Self {
22        Self {
23            client,
24            chat_id,
25            thread_id,
26        }
27    }
28
29    /// Map unified ChatAction to Telegram API action string
30    fn action_string(action: ChatAction) -> &'static str {
31        match action {
32            ChatAction::Typing => "typing",
33            ChatAction::UploadPhoto => "upload_photo",
34            ChatAction::RecordVideo => "record_video",
35            ChatAction::UploadVideo => "upload_video",
36            ChatAction::RecordVoice => "record_voice",
37            ChatAction::UploadVoice => "upload_voice",
38            ChatAction::UploadDocument => "upload_document",
39            ChatAction::ChooseSticker => "choose_sticker",
40            ChatAction::FindLocation => "find_location",
41            ChatAction::RecordVideoNote => "record_video_note",
42            ChatAction::UploadVideoNote => "upload_video_note",
43        }
44    }
45}
46
47impl ChatActionSender for TelegramActionSender {
48    fn send_action(
49        &self,
50        action: ChatAction,
51    ) -> impl ChatActionFutureBounds<Output = Result<(), BotError>> + '_ {
52        async move {
53            self.client
54                .send_chat_action(self.chat_id, Self::action_string(action), self.thread_id)
55                .await
56        }
57    }
58
59    fn action_expiry(&self) -> Duration {
60        // Telegram typing expires after 5 seconds
61        Duration::from_secs(5)
62    }
63}