feat: simplify douyin room-adding (close #196)

This commit is contained in:
Xinrea
2025-10-26 22:03:04 +08:00
parent 64dec36773
commit 1f666d402d
3 changed files with 53 additions and 25 deletions

View File

@@ -3,6 +3,7 @@ use crate::errors::RecorderError;
use crate::utils::user_agent_generator;
use deno_core::JsRuntime;
use deno_core::RuntimeOptions;
use regex::Regex;
use reqwest::Client;
use uuid::Uuid;
@@ -332,6 +333,34 @@ pub async fn get_user_info(
})
}
pub async fn get_room_owner_sec_uid(
client: &Client,
room_id: i64,
) -> Result<String, RecorderError> {
let url = format!("https://live.douyin.com/{room_id}");
let mut headers = generate_user_agent_header();
headers.insert("Referer", "https://live.douyin.com/".parse().unwrap());
let resp = client.get(url).headers(headers).send().await?;
let status = resp.status();
let text = resp.text().await?;
if !status.is_success() {
return Err(RecorderError::ApiError {
error: format!("Failed to get room owner sec uid: {status} {text}"),
});
}
// match to get sec_uid from text like \"sec_uid\":\"MS4wLjABAAAAdFmmud36bynPjXOvoMjatb42856_zryHsGmlkpIECDA\"
let sec_uid = Regex::new(r#"\\"sec_uid\\":\\"(.*?)\\""#)
.unwrap()
.captures(&text)
.and_then(|c| c.get(1))
.ok_or_else(|| RecorderError::ApiError {
error: "Failed to find sec_uid in room page".to_string(),
})?
.as_str()
.to_string();
Ok(sec_uid)
}
/// Download file from url to path
pub async fn download_file(client: &Client, url: &str, path: &Path) -> Result<(), RecorderError> {
if !path.parent().unwrap().exists() {
@@ -344,3 +373,18 @@ pub async fn download_file(client: &Client, url: &str, path: &Path) -> Result<()
tokio::io::copy(&mut content, &mut file).await?;
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn test_get_room_owner_sec_uid() {
let client = Client::new();
let sec_uid = get_room_owner_sec_uid(&client, 200525029536).await.unwrap();
assert_eq!(
sec_uid,
"MS4wLjABAAAAdFmmud36bynPjXOvoMjatb42856_zryHsGmlkpIECDA"
);
}
}

View File

@@ -14,6 +14,7 @@ use crate::webhook::events;
use recorder::account::Account;
use recorder::danmu::DanmuEntry;
use recorder::platforms::bilibili;
use recorder::platforms::douyin;
use recorder::platforms::PlatformType;
use recorder::RecorderInfo;
@@ -33,7 +34,7 @@ pub async fn add_recorder(
state: state_type!(),
platform: String,
room_id: i64,
extra: String,
mut extra: String,
) -> Result<RecorderRow, String> {
log::info!("Add recorder: {platform} {room_id}");
let platform = PlatformType::from_str(&platform).unwrap();
@@ -47,6 +48,12 @@ pub async fn add_recorder(
}
}
PlatformType::Douyin => {
let client = reqwest::Client::new();
let sec_uid = douyin::api::get_room_owner_sec_uid(&client, room_id)
.await
.map_err(|e| e.to_string())?;
extra = sec_uid;
if let Ok(account) = state.db.get_account_by_platform("douyin").await {
Ok(account.to_account())
} else {