Annotation For src/telegram.rs
Logged in as anonymous

Origin for each line in src/telegram.rs from check-in f5ed284f8c:

f5ed284f8c 2025-06-21    1: use crate::utils::{
f5ed284f8c 2025-06-21    2: 	Attachment,
f5ed284f8c 2025-06-21    3: 	RE_SPECIAL,
f5ed284f8c 2025-06-21    4: };
f5ed284f8c 2025-06-21    5: 
f5ed284f8c 2025-06-21    6: use std::{
f5ed284f8c 2025-06-21    7: 	borrow::Cow,
f5ed284f8c 2025-06-21    8: 	collections::HashMap,
f5ed284f8c 2025-06-21    9: 	fmt::Debug,
f5ed284f8c 2025-06-21   10: };
f5ed284f8c 2025-06-21   11: 
f5ed284f8c 2025-06-21   12: use anyhow::{
f5ed284f8c 2025-06-21   13: 	Context,
f5ed284f8c 2025-06-21   14: 	Result,
f5ed284f8c 2025-06-21   15: };
f5ed284f8c 2025-06-21   16: use tgbot::{
f5ed284f8c 2025-06-21   17: 	api::Client,
f5ed284f8c 2025-06-21   18: 	types::{
f5ed284f8c 2025-06-21   19: 		ChatPeerId,
f5ed284f8c 2025-06-21   20: 		InputFile,
f5ed284f8c 2025-06-21   21: 		InputFileReader,
f5ed284f8c 2025-06-21   22: 		InputMediaDocument,
f5ed284f8c 2025-06-21   23: 		MediaGroup,
f5ed284f8c 2025-06-21   24: 		MediaGroupItem,
f5ed284f8c 2025-06-21   25: 		Message,
f5ed284f8c 2025-06-21   26: 		ParseMode::MarkdownV2,
f5ed284f8c 2025-06-21   27: 		SendMediaGroup,
f5ed284f8c 2025-06-21   28: 		SendMessage,
f5ed284f8c 2025-06-21   29: 		SendDocument,
f5ed284f8c 2025-06-21   30: 	},
f5ed284f8c 2025-06-21   31: };
f5ed284f8c 2025-06-21   32: 
f5ed284f8c 2025-06-21   33: /// Encodes special HTML entities to prevent them interfering with Telegram HTML
f5ed284f8c 2025-06-21   34: pub fn encode (text: &str) -> Cow<'_, str> {
f5ed284f8c 2025-06-21   35: 	RE_SPECIAL.replace_all(text, "\\$1")
f5ed284f8c 2025-06-21   36: }
f5ed284f8c 2025-06-21   37: 
f5ed284f8c 2025-06-21   38: #[derive(Debug)]
f5ed284f8c 2025-06-21   39: pub struct TelegramTransport {
f5ed284f8c 2025-06-21   40: 	tg: Client,
f5ed284f8c 2025-06-21   41: 	recipients: HashMap<String, ChatPeerId>,
f5ed284f8c 2025-06-21   42: 	pub default: ChatPeerId,
f5ed284f8c 2025-06-21   43: }
f5ed284f8c 2025-06-21   44: 
f5ed284f8c 2025-06-21   45: impl TelegramTransport {
f5ed284f8c 2025-06-21   46: 
f5ed284f8c 2025-06-21   47: 	pub fn new (api_key: String, recipients: HashMap<String, i64>, default: i64) -> Result<TelegramTransport> {
f5ed284f8c 2025-06-21   48: 		let tg = Client::new(api_key)
f5ed284f8c 2025-06-21   49: 			.context("Failed to create API.\n")?;
f5ed284f8c 2025-06-21   50: 		let recipients = recipients.into_iter()
f5ed284f8c 2025-06-21   51: 			.map(|(a, b)| (a, ChatPeerId::from(b))).collect();
f5ed284f8c 2025-06-21   52: 		let default = ChatPeerId::from(default);
f5ed284f8c 2025-06-21   53: 
f5ed284f8c 2025-06-21   54: 		Ok(TelegramTransport {
f5ed284f8c 2025-06-21   55: 			tg,
f5ed284f8c 2025-06-21   56: 			recipients,
f5ed284f8c 2025-06-21   57: 			default,
f5ed284f8c 2025-06-21   58: 		})
f5ed284f8c 2025-06-21   59: 	}
f5ed284f8c 2025-06-21   60: 
f5ed284f8c 2025-06-21   61: 	/// Send message to default user, used for debug/log/info purposes
f5ed284f8c 2025-06-21   62: 	pub async fn debug (&self, msg: &str) -> Result<Message> {
f5ed284f8c 2025-06-21   63: 		self.send(&self.default, encode(msg)).await
f5ed284f8c 2025-06-21   64: 	}
f5ed284f8c 2025-06-21   65: 
f5ed284f8c 2025-06-21   66: 	/// Get recipient by address
f5ed284f8c 2025-06-21   67: 	pub fn get (&self, name: &str) -> Result<&ChatPeerId> {
f5ed284f8c 2025-06-21   68: 		self.recipients.get(name)
f5ed284f8c 2025-06-21   69: 			.with_context(|| format!("Recipient \"{name}\" not found in configuration"))
f5ed284f8c 2025-06-21   70: 	}
f5ed284f8c 2025-06-21   71: 
f5ed284f8c 2025-06-21   72: 	/// Send message to specified user
f5ed284f8c 2025-06-21   73: 	pub async fn send <S> (&self, to: &ChatPeerId, msg: S) -> Result<Message>
f5ed284f8c 2025-06-21   74: 	where S: Into<String> + Debug{
f5ed284f8c 2025-06-21   75: 		Ok(self.tg.execute(
f5ed284f8c 2025-06-21   76: 			SendMessage::new(*to, msg)
f5ed284f8c 2025-06-21   77: 			.with_parse_mode(MarkdownV2)
f5ed284f8c 2025-06-21   78: 		).await?)
f5ed284f8c 2025-06-21   79: 	}
f5ed284f8c 2025-06-21   80: 
f5ed284f8c 2025-06-21   81: 	/// Send media to specified user
f5ed284f8c 2025-06-21   82: 	pub async fn sendgroup (&self, to: &ChatPeerId, media: Vec<Attachment>, msg: &str) -> Result<()> {
f5ed284f8c 2025-06-21   83: 		if media.len() > 1 {
f5ed284f8c 2025-06-21   84: 			let mut attach = vec![];
f5ed284f8c 2025-06-21   85: 			let mut pos = media.len();
f5ed284f8c 2025-06-21   86: 			for file in media {
f5ed284f8c 2025-06-21   87: 				let mut caption = InputMediaDocument::default();
f5ed284f8c 2025-06-21   88: 				if pos == 1 {
f5ed284f8c 2025-06-21   89: 					caption = caption.with_caption(msg)
f5ed284f8c 2025-06-21   90: 						.with_caption_parse_mode(MarkdownV2);
f5ed284f8c 2025-06-21   91: 				}
f5ed284f8c 2025-06-21   92: 				pos -= 1;
f5ed284f8c 2025-06-21   93: 				attach.push(
f5ed284f8c 2025-06-21   94: 					MediaGroupItem::for_document(
f5ed284f8c 2025-06-21   95: 						InputFile::from(
f5ed284f8c 2025-06-21   96: 							InputFileReader::from(file.data)
f5ed284f8c 2025-06-21   97: 								.with_file_name(file.name)
f5ed284f8c 2025-06-21   98: 						),
f5ed284f8c 2025-06-21   99: 						caption
f5ed284f8c 2025-06-21  100: 					)
f5ed284f8c 2025-06-21  101: 				);
f5ed284f8c 2025-06-21  102: 			}
f5ed284f8c 2025-06-21  103: 			self.tg.execute(SendMediaGroup::new(*to, MediaGroup::new(attach)?)).await?;
f5ed284f8c 2025-06-21  104: 		} else {
f5ed284f8c 2025-06-21  105: 			self.tg.execute(
f5ed284f8c 2025-06-21  106: 				SendDocument::new(
f5ed284f8c 2025-06-21  107: 					*to,
f5ed284f8c 2025-06-21  108: 					InputFileReader::from(media[0].data.clone())
f5ed284f8c 2025-06-21  109: 					.with_file_name(media[0].name.clone())
f5ed284f8c 2025-06-21  110: 				).with_caption(msg)
f5ed284f8c 2025-06-21  111: 				.with_caption_parse_mode(MarkdownV2)
f5ed284f8c 2025-06-21  112: 			).await?;
f5ed284f8c 2025-06-21  113: 		}
f5ed284f8c 2025-06-21  114: 		Ok(())
f5ed284f8c 2025-06-21  115: 	}
f5ed284f8c 2025-06-21  116: }