use crate::{Result, TrendsError};
use reqwest::header::SET_COOKIE;
use tracing::info;
#[derive(Clone)]
pub struct SessionCookies {
pub cookie_header: String,
}
impl std::fmt::Debug for SessionCookies {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let cookie_count = self
.cookie_header
.split(';')
.filter(|part| !part.trim().is_empty())
.count();
f.debug_struct("SessionCookies")
.field("cookie_header", &"<redacted>")
.field("cookie_count", &cookie_count)
.finish()
}
}
pub async fn bootstrap_session() -> Result<SessionCookies> {
info!("Fetching session cookies natively from Google Trends");
let client = reqwest::Client::builder()
.user_agent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/121.0.0.0 Safari/537.36")
.build()?;
let resp = client
.get("https://trends.google.com/?geo=US")
.send()
.await?;
resp.error_for_status_ref()?;
let mut cookies = Vec::new();
for cookie in resp.headers().get_all(SET_COOKIE) {
if let Ok(cookie_str) = cookie.to_str() {
if let Some(cookie_pair) = cookie_str.split(';').next() {
cookies.push(cookie_pair.to_string());
}
}
}
if cookies.is_empty() {
return Err(TrendsError::Session(
"Failed to acquire any cookies from Google Trends natively. Are you IP blocked?"
.to_string(),
));
}
Ok(SessionCookies {
cookie_header: cookies.join("; "),
})
}