Files
rustmailer/src/modules/cache/vendor/gmail/tests.rs
T
rustmailer f9857fe9ae feat(api): Introduce unified tag-messages interface for mail tagging
Introduces a new `/tag-messages` API endpoint that provides a consistent, unified capability for setting tags (Labels/Categories/Keywords) across different mailer types.
2025-11-21 12:58:58 +08:00

431 lines
16 KiB
Rust

// Copyright © 2025 rustmailer.com
// Licensed under RustMailer License Agreement v1.0
// Unauthorized copying, modification, or distribution is prohibited.
use ahash::AHashMap;
use mail_send::{
mail_builder::{headers::address::Address, MessageBuilder},
smtp::message::IntoMessage,
};
use poem_grpc::{ClientConfig, CompressionEncoding};
use reqwest::header::{AUTHORIZATION, CONTENT_TYPE};
use serde_json::{json, Value};
use std::{borrow::Cow, time::Duration};
use crate::{
base64_encode,
modules::{
cache::{
imap::migration::EmailEnvelopeV3,
vendor::gmail::{
model::{
history::HistoryList,
messages::{FullMessage, MessageList, MessageMeta, PartBody},
},
sync::envelope::GmailEnvelope,
},
},
common::{rustls::RustMailerTls, Addr},
context::Initialize,
grpc::service::rustmailer_grpc::{GetOAuth2TokensRequest, OAuth2ServiceClient},
},
rustmailer_version,
};
async fn access_token() -> String {
RustMailerTls::initialize().await.unwrap();
let cfg = ClientConfig::builder()
.uri("http://localhost:16630")
.build()
.unwrap();
let mut grpc_client = OAuth2ServiceClient::new(cfg);
grpc_client.set_accept_compressed([CompressionEncoding::GZIP]);
grpc_client.set_send_compressed(CompressionEncoding::GZIP);
let request = GetOAuth2TokensRequest {
account_id: 658031352292246,
};
let mut request = poem_grpc::Request::new(request);
request.metadata_mut().insert(
AUTHORIZATION,
format!("Bearer {}", "2mY4irNCahQXeSarHYje1P1W"),
);
let result = grpc_client.get_o_auth2_tokens(request).await.unwrap();
result.access_token.clone().unwrap()
}
#[tokio::test]
async fn test1() {
let access_token = access_token().await;
let url = "https://gmail.googleapis.com/gmail/v1/users/me/labels/Label_6886728075529239043";
let url =
"https://gmail.googleapis.com/gmail/v1/users/me/messages/198e590baf688394?format=full";
let url =
"https://gmail.googleapis.com/gmail/v1/users/me/messages?labelIds=INBOX&maxResults=10";
let url = "https://gmail.googleapis.com/gmail/v1/users/me/labels/Label_6886728075529239043";
let url = "https://gmail.googleapis.com/gmail/v1/users/me/labels";
let url = "https://gmail.googleapis.com/gmail/v1/users/me/messages?labelIds=SENT&maxResults=20";
let url = "https://gmail.googleapis.com/gmail/v1/users/me/labels";
let url =
"https://gmail.googleapis.com/gmail/v1/users/me/messages/19961e858d35c4e6?format=full";
let mut builder = reqwest::ClientBuilder::new()
.user_agent(rustmailer_version!())
.timeout(Duration::from_secs(10))
.connect_timeout(Duration::from_secs(10));
let proxy_obj = reqwest::Proxy::all("socks5://127.0.0.1:22308").unwrap();
builder = builder
.redirect(reqwest::redirect::Policy::none())
.proxy(proxy_obj);
let client = builder.build().unwrap();
let res = client
.get(url)
.header(AUTHORIZATION, format!("Bearer {}", access_token))
.header(CONTENT_TYPE, "application/json")
.send()
.await
.unwrap();
if res.status().is_success() {
let body: Value = res.json().await.unwrap();
let pretty = serde_json::to_string_pretty(&body).unwrap();
println!("Response = {}", pretty);
} else {
eprintln!("Error: {} - {:?}", res.status(), res.text().await.unwrap());
}
}
#[tokio::test]
async fn test11() {
let access_token = access_token().await;
let url = "https://gmail.googleapis.com/gmail/v1/users/me/labels/Label_6886728075529239043";
let url =
"https://gmail.googleapis.com/gmail/v1/users/me/messages/198e590baf688394?format=full";
let url =
"https://gmail.googleapis.com/gmail/v1/users/me/messages?labelIds=INBOX&maxResults=10";
let url = "https://gmail.googleapis.com/gmail/v1/users/me/labels/Label_6886728075529239043";
let url = "https://gmail.googleapis.com/gmail/v1/users/me/labels";
let url = "https://gmail.googleapis.com/gmail/v1/users/me/messages?labelIds=SENT&maxResults=20";
let url =
"https://gmail.googleapis.com/gmail/v1/users/me/messages/1980d79e5bb7c585/attachments/ANGjdJ-eQccvPmRcUJhAEUrokYpWYnvrhpW1pq0nB75AsZ-WUXO_Yvxp8Y8WaYCW1WF0JwFYT3hFxnx2g2H1CAlAeUKa5BIJqjA-DVnT-kIACeVvq5gWnLrZJ6ux9_DW7OeApbTaLG1iVR0KU-rK986vfRJKK4g1JTqXDfQUU4D23B6qciJTkLHFTMcJ-HaO1FQ6Gj3LB-InOYz2oeSeuqJbEjTJetmIXsoPKy2b5Fzg1Eu3H1PwjqFC1WbLFwM8iAPLccrPe6SxqgpI1suPRkhRiqxvr5PyIohyFATp150Mnt7ec4TBInksFpihpTxK0cMfdti4gYv3eoGe2eDtgu5dcRBcSHJicWKN0VXLcCiqLgUo4mm4m6dy6-eU3v1BybESPZWuGMLEBjQWt4T6";
let mut builder = reqwest::ClientBuilder::new()
.user_agent(rustmailer_version!())
.timeout(Duration::from_secs(10))
.connect_timeout(Duration::from_secs(10));
let proxy_obj = reqwest::Proxy::all("socks5://127.0.0.1:22308").unwrap();
builder = builder
.redirect(reqwest::redirect::Policy::none())
.proxy(proxy_obj);
let client = builder.build().unwrap();
let res = client
.get(url)
.header(AUTHORIZATION, format!("Bearer {}", access_token))
.header(CONTENT_TYPE, "application/json")
.send()
.await
.unwrap();
if res.status().is_success() {
let body: Value = res.json().await.unwrap();
let pretty = serde_json::to_string_pretty(&body).unwrap();
let body: PartBody = serde_json::from_value(body).unwrap();
println!("Response = {:#?}", body);
} else {
eprintln!("Error: {} - {:?}", res.status(), res.text().await.unwrap());
}
}
#[tokio::test]
async fn test2() {
let access_token = access_token().await;
let url =
"https://gmail.googleapis.com/gmail/v1/users/me/messages?labelIds=INBOX&q=after:2025/08/28&maxResults=20";
let mut builder = reqwest::ClientBuilder::new()
.user_agent(rustmailer_version!())
.timeout(Duration::from_secs(10))
.connect_timeout(Duration::from_secs(10));
let proxy_obj = reqwest::Proxy::all("socks5://127.0.0.1:22308").unwrap();
builder = builder
.redirect(reqwest::redirect::Policy::none())
.proxy(proxy_obj);
let client = builder.build().unwrap();
let res = client
.get(url)
.header(AUTHORIZATION, format!("Bearer {}", access_token))
.header(CONTENT_TYPE, "application/json")
.send()
.await
.unwrap();
if res.status().is_success() {
let body: Value = res.json().await.unwrap();
let detail: MessageList = serde_json::from_value(body).unwrap();
println!("Response = {:#?}", detail);
} else {
eprintln!("Error: {} - {:?}", res.status(), res.text().await.unwrap());
}
}
#[tokio::test]
async fn test3() {
let access_token = access_token().await;
let url =
"https://gmail.googleapis.com/gmail/v1/users/me/messages/198f6735682a3870?format=metadata&metadataHeaders=Message-Id&metadataHeaders=From&metadataHeaders=To&metadataHeaders=Cc&metadataHeaders=Bcc&metadataHeaders=Subject&metadataHeaders=Date&metadataHeaders=Mime-Version&metadataHeaders=Reply-To&metadataHeaders=In-Reply-To&metadataHeaders=References";
let mut builder = reqwest::ClientBuilder::new()
.user_agent(rustmailer_version!())
.timeout(Duration::from_secs(10))
.connect_timeout(Duration::from_secs(10));
let proxy_obj = reqwest::Proxy::all("socks5://127.0.0.1:22308").unwrap();
builder = builder
.redirect(reqwest::redirect::Policy::none())
.proxy(proxy_obj);
let client = builder.build().unwrap();
let res = client
.get(url)
.header(AUTHORIZATION, format!("Bearer {}", access_token))
.header(CONTENT_TYPE, "application/json")
.send()
.await
.unwrap();
if res.status().is_success() {
let body: Value = res.json().await.unwrap();
let detail: MessageMeta = serde_json::from_value(body).unwrap();
let envelope: GmailEnvelope = detail.try_into().unwrap();
println!("Response = {:#?}", envelope);
let envelope: EmailEnvelopeV3 = envelope.into_v3(&AHashMap::new());
println!("Response = {:#?}", envelope);
} else {
eprintln!("Error: {} - {:?}", res.status(), res.text().await.unwrap());
}
}
#[tokio::test]
async fn test4() {
let access_token = access_token().await;
let url =
"https://gmail.googleapis.com/gmail/v1/users/me/history?startHistoryId=42032&labelId=INBOX&maxResults=20";
let mut builder = reqwest::ClientBuilder::new()
.user_agent(rustmailer_version!())
.timeout(Duration::from_secs(10))
.connect_timeout(Duration::from_secs(10));
let proxy_obj = reqwest::Proxy::all("socks5://127.0.0.1:22308").unwrap();
builder = builder
.redirect(reqwest::redirect::Policy::none())
.proxy(proxy_obj);
let client = builder.build().unwrap();
let res = client
.get(url)
.header(AUTHORIZATION, format!("Bearer {}", access_token))
.header(CONTENT_TYPE, "application/json")
.send()
.await
.unwrap();
if res.status().is_success() {
let body: Value = res.json().await.unwrap();
let json = serde_json::to_string_pretty(&body).unwrap();
println!("Response = {}", json);
let list: HistoryList = serde_json::from_value(body).unwrap();
println!("Response = {:#?}", list);
} else {
eprintln!("Error: {} - {:?}", res.status(), res.text().await.unwrap());
}
}
#[tokio::test]
async fn test5() {
let examples = [
"Quinn Eckart <jira@lifebuoy.atlassian.net>",
"justemail@example.com",
"<only@example.com>",
];
for s in examples {
let addr = Addr::parse(s);
println!("{:?}", addr);
}
}
#[tokio::test]
async fn test6() {
let access_token = access_token().await;
let url = "https://gmail.googleapis.com/gmail/v1/users/me/drafts";
let mut builder = reqwest::ClientBuilder::new()
.user_agent(rustmailer_version!())
.timeout(Duration::from_secs(10))
.connect_timeout(Duration::from_secs(10));
let proxy_obj = reqwest::Proxy::all("socks5://127.0.0.1:22308").unwrap();
builder = builder
.redirect(reqwest::redirect::Policy::none())
.proxy(proxy_obj);
let client = builder.build().unwrap();
let from = Address::new_address(
Some(Cow::Owned("rustmailer".to_string())),
Cow::Owned("rustmailer.git@gmail.com".to_string()),
);
let to = Address::new_address(
Some(Cow::Owned("noreply".to_string())),
Cow::Owned("noreply@medium.com".to_string()),
);
let subject = "Re: 👋 Welcome to Medium".to_string();
let mut builder = MessageBuilder::new()
.from(from)
.to(Address::from(to.clone()))
.subject(subject.clone());
builder = builder.in_reply_to("5JgiBu1_TSC_RIro8-xLWg@geopod-ismtpd-4".to_string());
let references = vec!["5JgiBu1_TSC_RIro8-xLWg@geopod-ismtpd-4".to_string()];
builder = builder.references(references);
builder = builder.text_body("wowwowwowwowwowwowwowwowwowwowwowwow");
let message = builder.into_message().unwrap();
let raw_encoded = base64_encode!(&message.body);
let body = json!({
"message": {
"threadId": "19720f0b9bd3822c",
"raw": raw_encoded
}
});
let res = client
.post(url)
.header(AUTHORIZATION, format!("Bearer {}", access_token))
.header(CONTENT_TYPE, "application/json")
.json(&body)
.send()
.await
.unwrap();
if res.status().is_success() {
let body: Value = res.json().await.unwrap();
let json = serde_json::to_string_pretty(&body).unwrap();
println!("Response = {}", json);
} else {
eprintln!("Error: {} - {:?}", res.status(), res.text().await.unwrap());
}
}
#[tokio::test]
async fn test7() {
let access_token = access_token().await;
let url = "https://gmail.googleapis.com/gmail/v1/users/me/labels";
let mut builder = reqwest::ClientBuilder::new()
.user_agent(rustmailer_version!())
.timeout(Duration::from_secs(10))
.connect_timeout(Duration::from_secs(10));
let proxy_obj = reqwest::Proxy::all("socks5://127.0.0.1:22308").unwrap();
builder = builder
.redirect(reqwest::redirect::Policy::none())
.proxy(proxy_obj);
let client = builder.build().unwrap();
let body = json!({
"name": "test_label_name1",
"messageListVisibility": "show",
"labelListVisibility": "labelShow",
"type": "user",
"color": {
"textColor": "#e66550",
"backgroundColor": "#fcdee8"
}
});
let res = client
.post(url)
.header(AUTHORIZATION, format!("Bearer {}", access_token))
.header(CONTENT_TYPE, "application/json")
.json(&body)
.send()
.await
.unwrap();
if res.status().is_success() {
let body: Value = res.json().await.unwrap();
let json = serde_json::to_string_pretty(&body).unwrap();
println!("Response = {}", json);
} else {
eprintln!("Error: {} - {:?}", res.status(), res.text().await.unwrap());
}
}
#[tokio::test]
async fn test8() {
let access_token = access_token().await;
let url = "https://gmail.googleapis.com/gmail/v1/users/me/labels/Label_4";
let mut builder = reqwest::ClientBuilder::new()
.user_agent(rustmailer_version!())
.timeout(Duration::from_secs(10))
.connect_timeout(Duration::from_secs(10));
let proxy_obj = reqwest::Proxy::all("socks5://127.0.0.1:22308").unwrap();
builder = builder
.redirect(reqwest::redirect::Policy::none())
.proxy(proxy_obj);
let client = builder.build().unwrap();
let res = client
.delete(url)
.header(AUTHORIZATION, format!("Bearer {}", access_token))
.header(CONTENT_TYPE, "application/json")
.send()
.await
.unwrap();
if res.status().is_success() {
// let body: Value = res.json().await.unwrap();
// let json = serde_json::to_string_pretty(&body).unwrap();
// println!("Response = {}", json);
} else {
eprintln!("Error: {} - {:?}", res.status(), res.text().await.unwrap());
}
}
#[tokio::test]
async fn test9() {
let access_token = access_token().await;
let url = format!(
"https://gmail.googleapis.com/gmail/v1/users/me/messages/19961e858d35c4e6?format=raw"
);
let mut builder = reqwest::ClientBuilder::new()
.user_agent(rustmailer_version!())
.timeout(Duration::from_secs(10))
.connect_timeout(Duration::from_secs(10));
let proxy_obj = reqwest::Proxy::all("socks5://127.0.0.1:22308").unwrap();
builder = builder
.redirect(reqwest::redirect::Policy::none())
.proxy(proxy_obj);
let client = builder.build().unwrap();
let res = client
.get(url)
.header(AUTHORIZATION, format!("Bearer {}", access_token))
.header(CONTENT_TYPE, "application/json")
.send()
.await
.unwrap();
if res.status().is_success() {
let body: Value = res.json().await.unwrap();
let json = serde_json::to_string_pretty(&body).unwrap();
println!("Response = {}", json);
let full_message: FullMessage = serde_json::from_value(body).unwrap();
println!("Response = {:#?}", full_message);
} else {
eprintln!("Error: {} - {:?}", res.status(), res.text().await.unwrap());
}
}