mirror of
https://github.com/kristoferssolo/tg-relay-rs.git
synced 2025-12-20 11:04:41 +00:00
feat(tiktok): add tiktok handler
This commit is contained in:
parent
881d730483
commit
24bfeb4efc
@ -30,9 +30,10 @@ tracing-subscriber = { version = "0.3", features = ["registry", "env-filter"] }
|
|||||||
url = "2.5"
|
url = "2.5"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["instagram", "youtube"]
|
default = ["instagram", "youtube", "tiktok"]
|
||||||
instagram = []
|
instagram = []
|
||||||
youtube = []
|
youtube = []
|
||||||
|
tiktok = []
|
||||||
|
|
||||||
[lints.clippy]
|
[lints.clippy]
|
||||||
pedantic = "warn"
|
pedantic = "warn"
|
||||||
|
|||||||
@ -128,6 +128,25 @@ pub async fn download_instagram(url: &str) -> Result<DownloadResult> {
|
|||||||
run_command_in_tempdir("yt-dlp", &args_ref).await
|
run_command_in_tempdir("yt-dlp", &args_ref).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "tiktok")]
|
||||||
|
pub async fn download_tiktok(url: &str) -> Result<DownloadResult> {
|
||||||
|
let base_args = ["--extractor-args", "tiktok:"];
|
||||||
|
let mut args = base_args
|
||||||
|
.iter()
|
||||||
|
.map(ToString::to_string)
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
if let Ok(cookies_path) = env::var("IG_SESSION_COOKIE_PATH") {
|
||||||
|
args.extend(["--cookies".into(), cookies_path]);
|
||||||
|
}
|
||||||
|
|
||||||
|
args.push(url.into());
|
||||||
|
|
||||||
|
let args_ref = args.iter().map(String::as_ref).collect::<Vec<_>>();
|
||||||
|
|
||||||
|
run_command_in_tempdir("yt-dlp", &args_ref).await
|
||||||
|
}
|
||||||
|
|
||||||
/// Download a URL with yt-dlp.
|
/// Download a URL with yt-dlp.
|
||||||
///
|
///
|
||||||
/// # Errors
|
/// # Errors
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
#[cfg(feature = "instagram")]
|
#[cfg(feature = "instagram")]
|
||||||
mod instagram;
|
mod instagram;
|
||||||
|
#[cfg(feature = "tiktok")]
|
||||||
|
mod tiktok;
|
||||||
#[cfg(feature = "youtube")]
|
#[cfg(feature = "youtube")]
|
||||||
mod youtube;
|
mod youtube;
|
||||||
|
|
||||||
@ -8,6 +10,8 @@ use teloxide::{Bot, types::ChatId};
|
|||||||
|
|
||||||
#[cfg(feature = "instagram")]
|
#[cfg(feature = "instagram")]
|
||||||
pub use instagram::InstagramHandler;
|
pub use instagram::InstagramHandler;
|
||||||
|
#[cfg(feature = "tiktok")]
|
||||||
|
pub use tiktok::TiktokHandler;
|
||||||
#[cfg(feature = "youtube")]
|
#[cfg(feature = "youtube")]
|
||||||
pub use youtube::YouTubeShortsHandler;
|
pub use youtube::YouTubeShortsHandler;
|
||||||
|
|
||||||
|
|||||||
54
src/handlers/tiktok.rs
Normal file
54
src/handlers/tiktok.rs
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
use crate::{
|
||||||
|
download::{download_tiktok, 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\.)?(?:vm|vt|tt|tik)\.tiktok\.com/([A-Za-z0-9_-]+)[/?#]?")
|
||||||
|
.expect("filed to compile regex")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Handler for Tiktok
|
||||||
|
#[derive(Clone, Default)]
|
||||||
|
pub struct TiktokHandler;
|
||||||
|
|
||||||
|
impl TiktokHandler {
|
||||||
|
#[inline]
|
||||||
|
#[must_use]
|
||||||
|
pub const fn new() -> Self {
|
||||||
|
Self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait::async_trait]
|
||||||
|
impl SocialHandler for TiktokHandler {
|
||||||
|
fn name(&self) -> &'static str {
|
||||||
|
"tiktok"
|
||||||
|
}
|
||||||
|
|
||||||
|
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 tiktok url");
|
||||||
|
let dr = download_tiktok(&url).await?;
|
||||||
|
process_download_result(bot, chat_id, dr).await
|
||||||
|
}
|
||||||
|
|
||||||
|
fn box_clone(&self) -> Box<dyn SocialHandler> {
|
||||||
|
Box::new(self.clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -32,6 +32,8 @@ async fn main() -> color_eyre::Result<()> {
|
|||||||
Arc::new(tg_relay_rs::handlers::InstagramHandler),
|
Arc::new(tg_relay_rs::handlers::InstagramHandler),
|
||||||
#[cfg(feature = "youtube")]
|
#[cfg(feature = "youtube")]
|
||||||
Arc::new(tg_relay_rs::handlers::YouTubeShortsHandler),
|
Arc::new(tg_relay_rs::handlers::YouTubeShortsHandler),
|
||||||
|
#[cfg(feature = "tiktok")]
|
||||||
|
Arc::new(tg_relay_rs::handlers::TiktokHandler),
|
||||||
];
|
];
|
||||||
|
|
||||||
teloxide::repl(bot.clone(), move |bot: Bot, msg: Message| {
|
teloxide::repl(bot.clone(), move |bot: Bot, msg: Message| {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user