front-api 0.0.2

A fully generated & opinionated API client for the Front API.
Documentation
//! A fully generated & opinionated API client for the Front API.
//!
//! [![docs.rs](https://docs.rs/front-api/badge.svg)](https://docs.rs/front-api)
//!
//! ## API Details
//!
//!
//!
//!
//!
//! ### Contact
//!
//!
//! | name | email |
//! |----|----|
//! | Front Platform | api@frontapp.com |
//!
//!
//!
//! ## Client Details
//!
//!
//!
//! The documentation for the crate is generated
//! along with the code to make this library easy to use.
//!
//!
//! To install the library, add the following to your `Cargo.toml` file.
//!
//! ```toml
//! [dependencies]
//! front-api = "0.0.2"
//! ```
//!
//! ## Basic example
//!
//! Typical use will require intializing a `Client`. This requires
//! a user agent string and set of credentials.
//!
//! ```rust,no_run
//! use front_api::Client;
//!
//! let client = Client::new(String::from("api-key"));
//! ```
//!
//! Alternatively, the library can search for most of the variables required for
//! the client in the environment:
//!
//! - `FRONT_API_TOKEN`
//!
//! And then you can create a client from the environment.
//!
//! ```rust,no_run
//! use front_api::Client;
//!
//! let client = Client::new_from_env();
//! ```
#![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"),);

/// Entrypoint for interacting with the API client.
#[derive(Clone, Debug)]
pub struct Client {
    token: String,
    base_url: String,

    client: reqwest_middleware::ClientWithMiddleware,
}

impl Client {
    /// Create a new Client struct. It takes a type that can convert into
    /// an &str (`String` or `Vec<u8>` for example). As long as the function is
    /// given a valid API key your requests will work.
    #[tracing::instrument]
    pub fn new<T>(token: T) -> Self
    where
        T: ToString + std::fmt::Debug,
    {
        // Retry up to 3 times with increasing intervals between attempts.
        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)
                    // Trace HTTP requests. See the tracing crate to make use of these traces.
                    .with(reqwest_tracing::TracingMiddleware::default())
                    // Retry failed requests.
                    .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),
        }
    }

    /// Set the base URL for the client to something other than the default: <https://api2.frontapp.com>.
    #[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();
    }

    /// Create a new Client struct from the environment variable: `FRONT_API_TOKEN`.
    #[tracing::instrument]
    pub fn new_from_env() -> Self {
        let token = env::var("FRONT_API_TOKEN").expect("must set FRONT_API_TOKEN");

        Client::new(token)
    }

    /// Create a raw request to our API.
    #[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);

        // Add in our authentication.
        req = req.bearer_auth(&self.token);

        // Set the default headers.
        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)
    }

    /// Return a reference to an interface that provides access to Accounts operations.
    pub fn accounts(&self) -> accounts::Accounts {
        accounts::Accounts::new(self.clone())
    }

    /// Return a reference to an interface that provides access to Events operations.
    pub fn events(&self) -> events::Events {
        events::Events::new(self.clone())
    }

    /// Return a reference to an interface that provides access to Analytics operations.
    pub fn analytics(&self) -> analytics::Analytics {
        analytics::Analytics::new(self.clone())
    }

    /// Return a reference to an interface that provides access to Attachments operations.
    pub fn attachments(&self) -> attachments::Attachments {
        attachments::Attachments::new(self.clone())
    }

    /// Return a reference to an interface that provides access to Token Identity operations.
    pub fn token_identity(&self) -> token_identity::TokenIdentity {
        token_identity::TokenIdentity::new(self.clone())
    }

    /// Return a reference to an interface that provides access to Message Template Folders operations.
    pub fn message_template_folders(&self) -> message_template_folders::MessageTemplateFolders {
        message_template_folders::MessageTemplateFolders::new(self.clone())
    }

    /// Return a reference to an interface that provides access to Message Templates operations.
    pub fn message_templates(&self) -> message_templates::MessageTemplates {
        message_templates::MessageTemplates::new(self.clone())
    }

    /// Return a reference to an interface that provides access to Contact Groups operations.
    pub fn contact_groups(&self) -> contact_groups::ContactGroups {
        contact_groups::ContactGroups::new(self.clone())
    }

    /// Return a reference to an interface that provides access to Contacts operations.
    pub fn contacts(&self) -> contacts::Contacts {
        contacts::Contacts::new(self.clone())
    }

    /// Return a reference to an interface that provides access to Contact Handles operations.
    pub fn contact_handles(&self) -> contact_handles::ContactHandles {
        contact_handles::ContactHandles::new(self.clone())
    }

    /// Return a reference to an interface that provides access to Contact Notes operations.
    pub fn contact_notes(&self) -> contact_notes::ContactNotes {
        contact_notes::ContactNotes::new(self.clone())
    }

    /// Return a reference to an interface that provides access to Channels operations.
    pub fn channels(&self) -> channels::Channels {
        channels::Channels::new(self.clone())
    }

    /// Return a reference to an interface that provides access to Inboxes operations.
    pub fn inboxes(&self) -> inboxes::Inboxes {
        inboxes::Inboxes::new(self.clone())
    }

    /// Return a reference to an interface that provides access to Comments operations.
    pub fn comments(&self) -> comments::Comments {
        comments::Comments::new(self.clone())
    }

    /// Return a reference to an interface that provides access to Conversations operations.
    pub fn conversations(&self) -> conversations::Conversations {
        conversations::Conversations::new(self.clone())
    }

    /// Return a reference to an interface that provides access to Messages operations.
    pub fn messages(&self) -> messages::Messages {
        messages::Messages::new(self.clone())
    }

    /// Return a reference to an interface that provides access to Custom Fields operations.
    pub fn custom_fields(&self) -> custom_fields::CustomFields {
        custom_fields::CustomFields::new(self.clone())
    }

    /// Return a reference to an interface that provides access to Drafts operations.
    pub fn drafts(&self) -> drafts::Drafts {
        drafts::Drafts::new(self.clone())
    }

    /// Return a reference to an interface that provides access to Rules operations.
    pub fn rules(&self) -> rules::Rules {
        rules::Rules::new(self.clone())
    }

    /// Return a reference to an interface that provides access to Shifts operations.
    pub fn shifts(&self) -> shifts::Shifts {
        shifts::Shifts::new(self.clone())
    }

    /// Return a reference to an interface that provides access to Signatures operations.
    pub fn signatures(&self) -> signatures::Signatures {
        signatures::Signatures::new(self.clone())
    }

    /// Return a reference to an interface that provides access to Tags operations.
    pub fn tags(&self) -> tags::Tags {
        tags::Tags::new(self.clone())
    }

    /// Return a reference to an interface that provides access to Teams operations.
    pub fn teams(&self) -> teams::Teams {
        teams::Teams::new(self.clone())
    }

    /// Return a reference to an interface that provides access to Teammates operations.
    pub fn teammates(&self) -> teammates::Teammates {
        teammates::Teammates::new(self.clone())
    }

    /// Return a reference to an interface that provides access to Links operations.
    pub fn links(&self) -> links::Links {
        links::Links::new(self.clone())
    }
}