garudust_platforms/
telegram.rs1use std::pin::Pin;
2use std::sync::Arc;
3
4use async_trait::async_trait;
5use futures::Stream;
6use garudust_core::{
7 error::PlatformError,
8 platform::{MessageHandler, PlatformAdapter},
9 types::{ChannelId, InboundMessage, OutboundMessage},
10};
11use teloxide::prelude::*;
12
13pub struct TelegramAdapter {
14 bot: Bot,
15}
16
17impl TelegramAdapter {
18 pub fn new(token: String) -> Self {
19 Self {
20 bot: Bot::new(token),
21 }
22 }
23}
24
25#[async_trait]
26impl PlatformAdapter for TelegramAdapter {
27 fn name(&self) -> &'static str {
28 "telegram"
29 }
30
31 async fn start(&self, handler: Arc<dyn MessageHandler>) -> Result<(), PlatformError> {
32 let bot = self.bot.clone();
33 tokio::spawn(async move {
34 teloxide::repl(bot, move |_bot: Bot, msg: Message| {
35 let handler = handler.clone();
36 async move {
37 if let Some(text) = msg.text() {
38 let is_group = msg.chat.is_group() || msg.chat.is_supergroup();
39 let inbound = InboundMessage {
40 channel: ChannelId {
41 platform: "telegram".into(),
42 chat_id: msg.chat.id.to_string(),
43 thread_id: None,
44 },
45 user_id: msg
46 .from
47 .as_ref()
48 .map(|u| u.id.to_string())
49 .unwrap_or_default(),
50 user_name: msg
51 .from
52 .as_ref()
53 .and_then(|u| u.username.clone())
54 .unwrap_or_default(),
55 text: text.to_string(),
56 session_key: format!("telegram:{}", msg.chat.id),
57 is_group,
58 bot_mentioned: None,
59 };
60 let _ = handler.handle(inbound).await;
61 }
62 respond(())
63 }
64 })
65 .await;
66 });
67 Ok(())
68 }
69
70 async fn send_message(
71 &self,
72 channel: &ChannelId,
73 message: OutboundMessage,
74 ) -> Result<(), PlatformError> {
75 let chat_id: i64 = channel
76 .chat_id
77 .parse()
78 .map_err(|_| PlatformError::Send("invalid chat_id".into()))?;
79 self.bot
80 .send_message(ChatId(chat_id), &message.text)
81 .await
82 .map_err(|e| PlatformError::Send(e.to_string()))?;
83 Ok(())
84 }
85
86 async fn send_stream(
87 &self,
88 channel: &ChannelId,
89 mut stream: Pin<Box<dyn Stream<Item = String> + Send>>,
90 ) -> Result<(), PlatformError> {
91 use futures::StreamExt;
92 let mut buf = String::new();
93 while let Some(chunk) = stream.next().await {
94 buf.push_str(&chunk);
95 }
96 self.send_message(channel, OutboundMessage::text(buf)).await
97 }
98}