/*
* Zernio API
*
* API reference for Zernio. Authenticate with a Bearer API key. Base URL: https://zernio.com/api Versioning and deprecation: all endpoints are versioned in the URL path (current version: /v1). Breaking changes only ship in a new path version; existing versions keep working. Deprecated operations are marked 'deprecated: true' in this spec and announced in the changelog (https://zernio.com/changelog) before removal. Errors: every 4xx/5xx response is application/json with a machine-readable 'code' and a human-readable 'error' message (see the ErrorResponse schema). Request ids: responses carry an X-Request-Id header with the id we log the request under. Quote it when reporting a problem. A valid x-request-id you send is reused as that id.
*
* The version of the OpenAPI document: 1.104.0
* Contact: support@zernio.com
* Generated by: https://openapi-generator.tech
*/
use crate::models;
use serde::{Deserialize, Serialize};
/// CallRecord : One call on a number you own, either channel. `channel` tells you which lane it took: `whatsapp` (WhatsApp Business Calling) or `pstn` (a regular phone call). List endpoints omit `transcript`; use `lastTranscriptSnippet` for a preview and the detail endpoint for the full transcript.
#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)]
pub struct CallRecord {
#[serde(rename = "_id", skip_serializing_if = "Option::is_none")]
pub _id: Option<String>,
/// Owning account. The unified /v1/calls/{id} detail + recording endpoints work for any channel; the channel-specific endpoints remain for account-scoped access.
#[serde(rename = "accountId", skip_serializing_if = "Option::is_none")]
pub account_id: Option<String>,
/// Inbox conversation with the counterparty, when one exists.
#[serde(
rename = "conversationId",
default,
with = "::serde_with::rust::double_option",
skip_serializing_if = "Option::is_none"
)]
pub conversation_id: Option<Option<String>>,
/// CRM Contact for the counterparty, when resolved.
#[serde(
rename = "contactId",
default,
with = "::serde_with::rust::double_option",
skip_serializing_if = "Option::is_none"
)]
pub contact_id: Option<Option<String>>,
#[serde(rename = "channel", skip_serializing_if = "Option::is_none")]
pub channel: Option<Channel>,
#[serde(rename = "direction", skip_serializing_if = "Option::is_none")]
pub direction: Option<Direction>,
/// Caller number (E.164).
#[serde(rename = "from", skip_serializing_if = "Option::is_none")]
pub from: Option<String>,
/// Callee number (E.164).
#[serde(rename = "to", skip_serializing_if = "Option::is_none")]
pub to: Option<String>,
/// Destination the call was routed to (tel:/sip:/wss:), snapshotted at routing time.
#[serde(
rename = "forwardTo",
default,
with = "::serde_with::rust::double_option",
skip_serializing_if = "Option::is_none"
)]
pub forward_to: Option<Option<String>>,
/// Outbound PSTN only. Message spoken to the callee on answer, before the bridge.
#[serde(
rename = "greeting",
default,
with = "::serde_with::rust::double_option",
skip_serializing_if = "Option::is_none"
)]
pub greeting: Option<Option<String>>,
#[serde(rename = "status", skip_serializing_if = "Option::is_none")]
pub status: Option<Status>,
/// True when an inbound call went to voicemail.
#[serde(rename = "isVoicemail", skip_serializing_if = "Option::is_none")]
pub is_voicemail: Option<bool>,
/// Outbound answering-machine detection was requested for this call.
#[serde(rename = "amd", skip_serializing_if = "Option::is_none")]
pub amd: Option<bool>,
/// With `amd`, whether a machine (vs a human) answered.
#[serde(
rename = "answeredMachine",
default,
with = "::serde_with::rust::double_option",
skip_serializing_if = "Option::is_none"
)]
pub answered_machine: Option<Option<bool>>,
/// Caller ID presented on the forwarded leg.
#[serde(rename = "forwardCallerId", skip_serializing_if = "Option::is_none")]
pub forward_caller_id: Option<ForwardCallerId>,
/// Effective flag for THIS call (number default + per-call override, resolved at create time).
#[serde(rename = "recordingEnabled", skip_serializing_if = "Option::is_none")]
pub recording_enabled: Option<bool>,
#[serde(
rename = "transcriptionEnabled",
skip_serializing_if = "Option::is_none"
)]
pub transcription_enabled: Option<bool>,
#[serde(
rename = "transcriptionLanguage",
skip_serializing_if = "Option::is_none"
)]
pub transcription_language: Option<TranscriptionLanguage>,
#[serde(rename = "startedAt", skip_serializing_if = "Option::is_none")]
pub started_at: Option<String>,
#[serde(
rename = "answeredAt",
default,
with = "::serde_with::rust::double_option",
skip_serializing_if = "Option::is_none"
)]
pub answered_at: Option<Option<String>>,
#[serde(
rename = "endedAt",
default,
with = "::serde_with::rust::double_option",
skip_serializing_if = "Option::is_none"
)]
pub ended_at: Option<Option<String>>,
/// When the call was blind-transferred (POST /v1/voice/calls/{id}/transfer).
#[serde(
rename = "transferredAt",
default,
with = "::serde_with::rust::double_option",
skip_serializing_if = "Option::is_none"
)]
pub transferred_at: Option<Option<String>>,
#[serde(rename = "durationSeconds", skip_serializing_if = "Option::is_none")]
pub duration_seconds: Option<i32>,
#[serde(rename = "endReason", skip_serializing_if = "Option::is_none")]
pub end_reason: Option<EndReason>,
/// Raw carrier hangup cause behind endReason (e.g. normal_clearing, not_found, time_limit). The actual motive when endReason is a coarse bucket.
#[serde(
rename = "hangupCause",
default,
with = "::serde_with::rust::double_option",
skip_serializing_if = "Option::is_none"
)]
pub hangup_cause: Option<Option<String>>,
/// SIP response code that ended the call, when SIP-signalled (e.g. '403', '488'). The real failure reason for SIP legs.
#[serde(
rename = "sipHangupCause",
default,
with = "::serde_with::rust::double_option",
skip_serializing_if = "Option::is_none"
)]
pub sip_hangup_cause: Option<Option<String>>,
/// Per-call failure log (dial failed, bridge failed, recording error).
#[serde(rename = "callErrors", skip_serializing_if = "Option::is_none")]
pub call_errors: Option<Vec<models::CallRecordCallErrorsInner>>,
/// May be expired. Resolve a fresh playable URL via GET /v1/calls/{id}/recording (any channel).
#[serde(
rename = "recordingUrl",
default,
with = "::serde_with::rust::double_option",
skip_serializing_if = "Option::is_none"
)]
pub recording_url: Option<Option<String>>,
/// Most recent transcript segment, for list previews.
#[serde(
rename = "lastTranscriptSnippet",
default,
with = "::serde_with::rust::double_option",
skip_serializing_if = "Option::is_none"
)]
pub last_transcript_snippet: Option<Option<String>>,
/// Full transcript segments (detail endpoint only; omitted from lists).
#[serde(rename = "transcript", skip_serializing_if = "Option::is_none")]
pub transcript: Option<Vec<models::CallRecordTranscriptInner>>,
#[serde(rename = "billing", skip_serializing_if = "Option::is_none")]
pub billing: Option<Box<models::CallRecordBilling>>,
#[serde(rename = "createdAt", skip_serializing_if = "Option::is_none")]
pub created_at: Option<String>,
#[serde(rename = "updatedAt", skip_serializing_if = "Option::is_none")]
pub updated_at: Option<String>,
}
impl CallRecord {
/// One call on a number you own, either channel. `channel` tells you which lane it took: `whatsapp` (WhatsApp Business Calling) or `pstn` (a regular phone call). List endpoints omit `transcript`; use `lastTranscriptSnippet` for a preview and the detail endpoint for the full transcript.
pub fn new() -> CallRecord {
CallRecord {
_id: None,
account_id: None,
conversation_id: None,
contact_id: None,
channel: None,
direction: None,
from: None,
to: None,
forward_to: None,
greeting: None,
status: None,
is_voicemail: None,
amd: None,
answered_machine: None,
forward_caller_id: None,
recording_enabled: None,
transcription_enabled: None,
transcription_language: None,
started_at: None,
answered_at: None,
ended_at: None,
transferred_at: None,
duration_seconds: None,
end_reason: None,
hangup_cause: None,
sip_hangup_cause: None,
call_errors: None,
recording_url: None,
last_transcript_snippet: None,
transcript: None,
billing: None,
created_at: None,
updated_at: None,
}
}
}
///
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
pub enum Channel {
#[serde(rename = "whatsapp")]
Whatsapp,
#[serde(rename = "pstn")]
Pstn,
}
impl Default for Channel {
fn default() -> Channel {
Self::Whatsapp
}
}
///
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
pub enum Direction {
#[serde(rename = "inbound")]
Inbound,
#[serde(rename = "outbound")]
Outbound,
}
impl Default for Direction {
fn default() -> Direction {
Self::Inbound
}
}
///
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
pub enum Status {
#[serde(rename = "ringing")]
Ringing,
#[serde(rename = "answered")]
Answered,
#[serde(rename = "ended")]
Ended,
#[serde(rename = "failed")]
Failed,
}
impl Default for Status {
fn default() -> Status {
Self::Ringing
}
}
/// Caller ID presented on the forwarded leg.
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
pub enum ForwardCallerId {
#[serde(rename = "business")]
Business,
#[serde(rename = "caller")]
Caller,
}
impl Default for ForwardCallerId {
fn default() -> ForwardCallerId {
Self::Business
}
}
///
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
pub enum TranscriptionLanguage {
#[serde(rename = "auto")]
Auto,
#[serde(rename = "en")]
En,
#[serde(rename = "es")]
Es,
}
impl Default for TranscriptionLanguage {
fn default() -> TranscriptionLanguage {
Self::Auto
}
}
///
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
pub enum EndReason {
#[serde(rename = "hangup")]
Hangup,
#[serde(rename = "no_answer")]
NoAnswer,
#[serde(rename = "rejected")]
Rejected,
#[serde(rename = "error")]
Error,
}
impl Default for EndReason {
fn default() -> EndReason {
Self::Hangup
}
}