use serde_json;
use chrono::{DateTime, Utc};
use error::HelpScoutError;
use client::Client;
use envelope::{Collection, Item};
use api::person::Person;
use api::mailboxes::MailboxRef;
#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum ConversationType {
Email,
Chat,
Phone,
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum ConversationStatus {
Active,
Pending,
Closed,
Spam,
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum ConversationSourceType {
Email,
Web,
Notification,
#[serde(rename = "emailfwd")]
EmailForward,
Api,
Chat,
Workflows,
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum ConversationSourceVia {
Customer,
User,
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum ConversationThreadType {
LineItem,
Note,
Message,
Chat,
Customer,
ForwardParent,
ForwardChild,
Phone,
}
impl Default for ConversationThreadType {
fn default() -> ConversationThreadType { ConversationThreadType::Customer }
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum ConversationThreadStatus {
NoChange,
Active,
Pending,
Closed,
Spam,
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub enum ConversationActionType {
MovedFromMailbox,
Merged,
Imported,
Workflow,
ImportedExternal,
ChangedTicketCustomer,
DeletedTicket,
RestoreTicket,
OriginalCreator,
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum ConversationThreadState {
Published,
Draft,
UnderReview,
Hidden,
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Conversation {
pub id: i32,
#[serde(rename = "type")]
pub conversation_type: ConversationType,
pub folder_id: i32,
pub is_draft: bool,
pub number: i32,
pub owner: Option<Person>,
pub mailbox: MailboxRef,
pub customer: Person,
pub thread_count: i32,
pub status: ConversationStatus,
pub subject: String,
pub preview: String,
pub created_by: Person,
pub created_at: DateTime<Utc>,
pub modified_at: Option<DateTime<Utc>>,
pub user_modified_at: Option<DateTime<Utc>>,
pub closed_at: Option<DateTime<Utc>>,
pub closed_by: Option<Person>,
pub source: ConversationSource,
pub cc: Option<Vec<String>>,
pub bcc: Option<Vec<String>>,
pub tags: Vec<String>,
pub threads: Option<Vec<ConversationThread>>,
}
#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct NewConversation {
#[serde(rename = "type")]
pub conversation_type: Option<ConversationType>,
pub customer: Person,
pub subject: String,
pub mailbox: MailboxRef,
pub tags: Option<Vec<String>>,
pub created_at: Option<DateTime<Utc>>,
pub threads: Vec<NewConversationThread>,
}
impl NewConversation {
pub fn new(customer: Person, subject: String, mailbox: MailboxRef, threads: Vec<NewConversationThread>) -> NewConversation {
NewConversation {
conversation_type: None,
customer: customer,
subject: subject,
mailbox: mailbox,
tags: None,
created_at: None,
threads: threads,
}
}
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Attachment {
pub id: i32,
pub hash: String,
pub mime_type: String,
pub filename: String,
pub size: String,
pub width: String,
pub height: String,
pub url: String,
}
#[derive(Debug, Deserialize)]
pub struct AttachmentData {
pub id: i32,
pub data: String,
}
#[derive(Debug, Deserialize)]
pub struct ConversationSource {
#[serde(rename = "type")]
pub conversation_source_type: ConversationSourceType,
pub via: ConversationSourceVia,
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ConversationThread {
pub id: i32,
#[serde(rename = "type")]
pub conversation_thread_type: ConversationThreadType,
pub assigned_to: Option<Person>,
pub status: ConversationThreadStatus,
pub created_at: DateTime<Utc>,
pub updated_at: Option<DateTime<Utc>>,
pub created_by: Option<Person>,
pub source: Option<ConversationSource>,
pub action_type: Option<ConversationActionType>,
pub action_source_id: Option<i32>,
pub from_mailbox: Option<MailboxRef>,
pub state: Option<ConversationThreadState>,
pub customer: Option<Person>,
pub body: Option<String>,
pub to: Option<Vec<String>>,
pub cc: Option<Vec<String>>,
pub bcc: Option<Vec<String>>,
pub attachments: Option<Vec<Attachment>>,
pub saved_reply_id: Option<i32>,
pub created_by_customer: bool,
}
#[derive(Debug, Default, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct NewConversationThread {
pub created_by: Person,
pub conversation_thread_type: ConversationThreadType,
pub body: String,
pub assigned_to: Option<Person>,
pub status: Option<ConversationThreadStatus>,
pub created_at: Option<DateTime<Utc>>,
pub cc: Option<Vec<String>>,
pub bcc: Option<Vec<String>>,
pub attachments: Option<Vec<Attachment>>,
}
impl NewConversationThread {
pub fn new(conversation_thread_type: ConversationThreadType, created_by: Person, body: String) -> NewConversationThread {
NewConversationThread {
conversation_thread_type: conversation_thread_type,
created_by: created_by,
body: body,
.. NewConversationThread::default()
}
}
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct CustomField {
pub field_id: i32,
pub name: String,
pub value: String,
pub field_type: String,
pub label: String,
}
pub fn list(client: &Client, mailbox_id: i32) -> Result<Collection<Conversation>, HelpScoutError> {
let res = client.get(&format!("mailboxes/{}/conversations.json", mailbox_id), ())?;
let conversations = serde_json::from_value(res.clone())?;
Ok(conversations)
}
pub fn get(client: &Client, id: i32) -> Result<Item<Conversation>, HelpScoutError> {
let res = client.get(&format!("conversations/{}.json", id), ())?;
let conversation = serde_json::from_value(res.clone())?;
Ok(conversation)
}
pub fn create(client: &Client, conversation: &NewConversation, imported: Option<bool>, auto_reply: Option<bool>, reload: Option<bool>) -> Result<(), HelpScoutError> {
let body = serde_json::to_value(conversation)?;
let res = client.post("conversations.json", (), Some(body.to_string()))?;
Ok(())
}
pub fn delete(client: &Client, id: i32) -> Result<Item<Conversation>, HelpScoutError> {
let res = client.get(&format!("conversations/{}.json", id), ())?;
let conversation = serde_json::from_value(res.clone())?;
Ok(conversation)
}
pub fn get_attachment_data(client: &Client, id: i32) -> Result<Item<AttachmentData>, HelpScoutError> {
let res = client.get(&format!("attachments/{}/data.json", id), ())?;
let attachment_data = serde_json::from_value(res.clone())?;
Ok(attachment_data)
}