#![allow(missing_docs)]
#![allow(clippy::needless_lifetimes)]
#![cfg_attr(docsrs, feature(doc_cfg))]
#[doc(hidden)]
pub mod accounts;
pub mod analytics;
pub mod attachments;
pub mod channels;
pub mod comments;
pub mod contact_groups;
pub mod contact_handles;
pub mod contact_notes;
pub mod contacts;
pub mod conversations;
pub mod custom_fields;
pub mod drafts;
pub mod events;
pub mod inboxes;
pub mod links;
pub mod message_template_folders;
pub mod message_templates;
pub mod messages;
pub mod rules;
pub mod shifts;
pub mod signatures;
pub mod tags;
pub mod teammates;
pub mod teams;
#[cfg(test)]
mod tests;
pub mod token_identity;
pub mod types;
use std::env;
static APP_USER_AGENT: &str = concat!(env!("CARGO_PKG_NAME"), ".rs/", env!("CARGO_PKG_VERSION"),);
#[derive(Clone, Debug)]
pub struct Client {
token: String,
base_url: String,
client: reqwest_middleware::ClientWithMiddleware,
}
impl Client {
#[tracing::instrument]
pub fn new<T>(token: T) -> Self
where
T: ToString + std::fmt::Debug,
{
let retry_policy =
reqwest_retry::policies::ExponentialBackoff::builder().build_with_max_retries(3);
let client = reqwest::Client::builder()
.user_agent(APP_USER_AGENT)
.build();
match client {
Ok(c) => {
let client = reqwest_middleware::ClientBuilder::new(c)
.with(reqwest_tracing::TracingMiddleware::default())
.with(reqwest_conditional_middleware::ConditionalMiddleware::new(
reqwest_retry::RetryTransientMiddleware::new_with_policy(retry_policy),
|req: &reqwest::Request| req.try_clone().is_some(),
))
.build();
Client {
token: token.to_string(),
base_url: "https://api2.frontapp.com".to_string(),
client,
}
}
Err(e) => panic!("creating reqwest client failed: {:?}", e),
}
}
#[tracing::instrument]
pub fn set_base_url<H>(&mut self, base_url: H)
where
H: Into<String> + std::fmt::Display + std::fmt::Debug,
{
self.base_url = base_url.to_string().trim_end_matches('/').to_string();
}
#[tracing::instrument]
pub fn new_from_env() -> Self {
let token = env::var("FRONT_API_TOKEN").expect("must set FRONT_API_TOKEN");
Client::new(token)
}
#[tracing::instrument]
pub async fn request_raw(
&self,
method: reqwest::Method,
uri: &str,
body: Option<reqwest::Body>,
) -> anyhow::Result<reqwest_middleware::RequestBuilder> {
let u = if uri.starts_with("https://") || uri.starts_with("http://") {
uri.to_string()
} else {
format!("{}/{}", self.base_url, uri.trim_start_matches('/'))
};
let mut req = self.client.request(method, &u);
req = req.bearer_auth(&self.token);
req = req.header(
reqwest::header::ACCEPT,
reqwest::header::HeaderValue::from_static("application/json"),
);
req = req.header(
reqwest::header::CONTENT_TYPE,
reqwest::header::HeaderValue::from_static("application/json"),
);
if let Some(body) = body {
req = req.body(body);
}
Ok(req)
}
pub fn accounts(&self) -> accounts::Accounts {
accounts::Accounts::new(self.clone())
}
pub fn events(&self) -> events::Events {
events::Events::new(self.clone())
}
pub fn analytics(&self) -> analytics::Analytics {
analytics::Analytics::new(self.clone())
}
pub fn attachments(&self) -> attachments::Attachments {
attachments::Attachments::new(self.clone())
}
pub fn token_identity(&self) -> token_identity::TokenIdentity {
token_identity::TokenIdentity::new(self.clone())
}
pub fn message_template_folders(&self) -> message_template_folders::MessageTemplateFolders {
message_template_folders::MessageTemplateFolders::new(self.clone())
}
pub fn message_templates(&self) -> message_templates::MessageTemplates {
message_templates::MessageTemplates::new(self.clone())
}
pub fn contact_groups(&self) -> contact_groups::ContactGroups {
contact_groups::ContactGroups::new(self.clone())
}
pub fn contacts(&self) -> contacts::Contacts {
contacts::Contacts::new(self.clone())
}
pub fn contact_handles(&self) -> contact_handles::ContactHandles {
contact_handles::ContactHandles::new(self.clone())
}
pub fn contact_notes(&self) -> contact_notes::ContactNotes {
contact_notes::ContactNotes::new(self.clone())
}
pub fn channels(&self) -> channels::Channels {
channels::Channels::new(self.clone())
}
pub fn inboxes(&self) -> inboxes::Inboxes {
inboxes::Inboxes::new(self.clone())
}
pub fn comments(&self) -> comments::Comments {
comments::Comments::new(self.clone())
}
pub fn conversations(&self) -> conversations::Conversations {
conversations::Conversations::new(self.clone())
}
pub fn messages(&self) -> messages::Messages {
messages::Messages::new(self.clone())
}
pub fn custom_fields(&self) -> custom_fields::CustomFields {
custom_fields::CustomFields::new(self.clone())
}
pub fn drafts(&self) -> drafts::Drafts {
drafts::Drafts::new(self.clone())
}
pub fn rules(&self) -> rules::Rules {
rules::Rules::new(self.clone())
}
pub fn shifts(&self) -> shifts::Shifts {
shifts::Shifts::new(self.clone())
}
pub fn signatures(&self) -> signatures::Signatures {
signatures::Signatures::new(self.clone())
}
pub fn tags(&self) -> tags::Tags {
tags::Tags::new(self.clone())
}
pub fn teams(&self) -> teams::Teams {
teams::Teams::new(self.clone())
}
pub fn teammates(&self) -> teammates::Teammates {
teammates::Teammates::new(self.clone())
}
pub fn links(&self) -> links::Links {
links::Links::new(self.clone())
}
}