mirror of
https://github.com/kristoferssolo/tg-relay-rs.git
synced 2025-12-20 11:04:41 +00:00
feat(twitter): add handler
This commit is contained in:
parent
0b6012e383
commit
40ae0b7371
@ -30,10 +30,11 @@ tracing-subscriber = { version = "0.3", features = ["registry", "env-filter"] }
|
||||
url = "2.5"
|
||||
|
||||
[features]
|
||||
default = ["instagram", "youtube", "tiktok"]
|
||||
default = ["instagram", "tiktok", "twitter", "youtube"]
|
||||
instagram = []
|
||||
youtube = []
|
||||
tiktok = []
|
||||
twitter = []
|
||||
youtube = []
|
||||
|
||||
[lints.clippy]
|
||||
pedantic = "warn"
|
||||
|
||||
@ -104,7 +104,7 @@ async fn run_command_in_tempdir(cmd: &str, args: &[&str]) -> Result<DownloadResu
|
||||
})
|
||||
}
|
||||
|
||||
/// Download an Instagram shortcode using instaloader (wrapper).
|
||||
/// Download a Instagram URL with yt-dlp.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
@ -128,6 +128,11 @@ pub async fn download_instagram(url: &str) -> Result<DownloadResult> {
|
||||
run_command_in_tempdir("yt-dlp", &args_ref).await
|
||||
}
|
||||
|
||||
/// Download a Tiktok URL with yt-dlp.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// - Propagates `run_command_in_tempdir` errors.
|
||||
#[cfg(feature = "tiktok")]
|
||||
pub async fn download_tiktok(url: &str) -> Result<DownloadResult> {
|
||||
let base_args = ["--extractor-args", "tiktok:"];
|
||||
@ -147,6 +152,17 @@ pub async fn download_tiktok(url: &str) -> Result<DownloadResult> {
|
||||
run_command_in_tempdir("yt-dlp", &args_ref).await
|
||||
}
|
||||
|
||||
/// Download a Twitter URL with yt-dlp.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// - Propagates `run_command_in_tempdir` errors.
|
||||
#[cfg(feature = "twitter")]
|
||||
pub async fn download_twitter(url: &str) -> Result<DownloadResult> {
|
||||
let args = ["--extractor-args", "twitter:", url];
|
||||
run_command_in_tempdir("yt-dlp", &args).await
|
||||
}
|
||||
|
||||
/// Download a URL with yt-dlp.
|
||||
///
|
||||
/// # Errors
|
||||
|
||||
@ -2,6 +2,8 @@
|
||||
mod instagram;
|
||||
#[cfg(feature = "tiktok")]
|
||||
mod tiktok;
|
||||
#[cfg(feature = "twitter")]
|
||||
mod twitter;
|
||||
#[cfg(feature = "youtube")]
|
||||
mod youtube;
|
||||
|
||||
@ -12,6 +14,8 @@ use teloxide::{Bot, types::ChatId};
|
||||
pub use instagram::InstagramHandler;
|
||||
#[cfg(feature = "tiktok")]
|
||||
pub use tiktok::TiktokHandler;
|
||||
#[cfg(feature = "twitter")]
|
||||
pub use twitter::TwitterHandler;
|
||||
#[cfg(feature = "youtube")]
|
||||
pub use youtube::YouTubeShortsHandler;
|
||||
|
||||
|
||||
56
src/handlers/twitter.rs
Normal file
56
src/handlers/twitter.rs
Normal file
@ -0,0 +1,56 @@
|
||||
use crate::{
|
||||
download::{download_twitter, process_download_result},
|
||||
error::Result,
|
||||
};
|
||||
use regex::Regex;
|
||||
use std::sync::OnceLock;
|
||||
use teloxide::{Bot, types::ChatId};
|
||||
use tracing::info;
|
||||
|
||||
use crate::handlers::SocialHandler;
|
||||
|
||||
static SHORTCODE_RE: OnceLock<Regex> = OnceLock::new();
|
||||
|
||||
fn shortcode_regex() -> &'static Regex {
|
||||
SHORTCODE_RE.get_or_init(|| {
|
||||
Regex::new(
|
||||
r"https?://(?:www\.)?twitter\.com/([A-Za-z0-9_]+(?:/[A-Za-z0-9_]+)?)/status/(\d{1,20})",
|
||||
)
|
||||
.expect("filed to compile regex")
|
||||
})
|
||||
}
|
||||
|
||||
/// Handler for Tiktok
|
||||
#[derive(Clone, Default)]
|
||||
pub struct TwitterHandler;
|
||||
|
||||
impl TwitterHandler {
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub const fn new() -> Self {
|
||||
Self
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl SocialHandler for TwitterHandler {
|
||||
fn name(&self) -> &'static str {
|
||||
"twitter"
|
||||
}
|
||||
|
||||
fn try_extract(&self, text: &str) -> Option<String> {
|
||||
shortcode_regex()
|
||||
.captures(text)
|
||||
.and_then(|c| c.get(0).map(|m| m.as_str().to_owned()))
|
||||
}
|
||||
|
||||
async fn handle(&self, bot: &Bot, chat_id: ChatId, url: String) -> Result<()> {
|
||||
info!(handler = %self.name(), url = %url, "handling twitter url");
|
||||
let dr = download_twitter(&url).await?;
|
||||
process_download_result(bot, chat_id, dr).await
|
||||
}
|
||||
|
||||
fn box_clone(&self) -> Box<dyn SocialHandler> {
|
||||
Box::new(self.clone())
|
||||
}
|
||||
}
|
||||
@ -34,6 +34,8 @@ async fn main() -> color_eyre::Result<()> {
|
||||
Arc::new(tg_relay_rs::handlers::YouTubeShortsHandler),
|
||||
#[cfg(feature = "tiktok")]
|
||||
Arc::new(tg_relay_rs::handlers::TiktokHandler),
|
||||
#[cfg(feature = "twitter")]
|
||||
Arc::new(tg_relay_rs::handlers::TwitterHandler),
|
||||
];
|
||||
|
||||
teloxide::repl(bot.clone(), move |bot: Bot, msg: Message| {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user