use mailkite::{AttachmentUpload, Client, Error};
use serde_json::{json, Value};
fn main() {
let cases_path = std::env::var("MK_CASES").expect("MK_CASES not set");
let base_url =
std::env::var("MK_BASE_URL").unwrap_or_else(|_| "https://api.mailkite.dev".to_string());
let api_key = std::env::var("MK_API_KEY").unwrap_or_default();
let raw = std::fs::read_to_string(&cases_path).expect("read MK_CASES");
let file: Value = serde_json::from_str(&raw).expect("parse MK_CASES");
let empty: Vec<Value> = Vec::new();
let cases = file
.get("cases")
.and_then(|v| v.as_array())
.unwrap_or(&empty);
let mk = Client::new_with_base_url(api_key, base_url);
for case in cases {
let name = case.get("name").and_then(|v| v.as_str()).unwrap_or("");
let method = case.get("method").and_then(|v| v.as_str()).unwrap_or("");
let args = case
.get("args")
.cloned()
.unwrap_or_else(|| Value::Object(Default::default()));
let mut out = serde_json::Map::new();
out.insert("name".into(), json!(name));
match dispatch(&mk, method, &args) {
Ok(result) => {
out.insert("result".into(), result);
}
Err(e) => {
out.insert(
"error".into(),
json!({ "status": e.status, "message": e.message }),
);
}
}
println!("{}", serde_json::to_string(&Value::Object(out)).unwrap());
}
}
fn str_of<'a>(a: &'a Value, k: &str) -> &'a str {
a.get(k).and_then(|v| v.as_str()).unwrap_or("")
}
fn i64_of(a: &Value, k: &str) -> Option<i64> {
a.get(k).and_then(|v| v.as_i64())
}
fn dispatch(mk: &Client, method: &str, a: &Value) -> Result<Value, Error> {
let id = str_of(a, "id");
match method {
"send" => mk.send(a.clone()),
"uploadAttachment" => {
let up = AttachmentUpload {
url: a.get("url").and_then(|v| v.as_str()).map(String::from),
content: a.get("content").and_then(|v| v.as_str()).map(String::from),
filename: a.get("filename").and_then(|v| v.as_str()).map(String::from),
content_type: a.get("contentType").and_then(|v| v.as_str()).map(String::from),
path: a.get("path").and_then(|v| v.as_str()).map(String::from),
retention_days: i64_of(a, "retentionDays"),
bytes: a
.get("bytes")
.and_then(|v| v.as_str())
.map(|s| s.as_bytes().to_vec()),
};
mk.upload_attachment(up)
}
"agent" => mk.agent(a.clone()),
"route" => mk.route(a.clone()),
"listTemplates" => mk.list_templates(),
"listBaseTemplates" => mk.list_base_templates(),
"getTemplate" => mk.get_template(id),
"createTemplate" => mk.create_template(a.clone()),
"listDomains" => mk.list_domains(),
"createDomain" => mk.create_domain(a.clone()),
"getDomain" => mk.get_domain(id),
"deleteDomain" => mk.delete_domain(id),
"verifyDomain" => mk.verify_domain(id),
"setWebhook" => mk.set_webhook(id, json!({ "url": a.get("url") })),
"deleteWebhook" => mk.delete_webhook(id),
"testWebhook" => mk.test_webhook(id),
"checkDomainAvailability" => mk.check_domain_availability(str_of(a, "domain")),
"registerDomain" => mk.register_domain(a.clone()),
"semanticSearch" => mk.semantic_search(str_of(a, "query")),
"listRoutes" => mk.list_routes(),
"createRoute" => mk.create_route(a.clone()),
"deleteRoute" => mk.delete_route(id),
"listMessages" => mk.list_messages(
i64_of(a, "before"),
i64_of(a, "limit"),
a.get("search").and_then(|v| v.as_str()),
),
"getMessage" => mk.get_message(id),
"retryDelivery" => mk.retry_delivery(id),
"verifyWebhook" => Ok(Value::Bool(mailkite::verify_webhook_with_tolerance(
str_of(a, "signature"),
str_of(a, "payload"),
str_of(a, "secret"),
i64_of(a, "toleranceMs").unwrap_or(0),
))),
"replyOk" => Ok(json!(mailkite::reply_ok())),
"replySpam" => Ok(json!(mailkite::reply_spam())),
"replyDrop" => Ok(json!(mailkite::reply_drop())),
"replyBlockSender" => Ok(json!(mailkite::reply_block_sender())),
"listLists" => mk.list_lists(),
"createList" => mk.create_list(a.clone()),
"getList" => mk.get_list(id),
"updateList" => mk.update_list(id, json!({ "name": a.get("name") })),
"deleteList" => mk.delete_list(id),
"listListContacts" => mk.list_list_contacts(
id,
i64_of(a, "before"),
i64_of(a, "limit"),
a.get("search").and_then(|v| v.as_str()),
),
"addListContacts" => mk.add_list_contacts(id, json!({ "contactIds": a.get("contactIds") })),
"removeListContact" => mk.remove_list_contact(id, str_of(a, "contactId")),
"listBroadcasts" => mk.list_broadcasts(),
"createBroadcast" => mk.create_broadcast(a.clone()),
"getBroadcast" => mk.get_broadcast(id),
"updateBroadcast" => mk.update_broadcast(id, json!({ "subject": a.get("subject") })),
"deleteBroadcast" => mk.delete_broadcast(id),
"sendBroadcast" => {
let body = match a.get("scheduledAt") {
Some(v) => json!({ "scheduledAt": v }),
None => Value::Null,
};
mk.send_broadcast(id, body)
}
"decrypt" => {
mailkite::decrypt(str_of(a, "envelope"), str_of(a, "privateKey")).map(Value::String)
}
"encryptRoundtrip" => {
let envelope = mailkite::encrypt(str_of(a, "plaintext"), str_of(a, "publicKey"))?;
mailkite::decrypt(&envelope, str_of(a, "privateKey")).map(Value::String)
}
_ => Err(Error {
status: 0,
message: format!("unknown method {}", method),
body: None,
}),
}
}