/*
* 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.504.0
* Contact: support@zernio.com
* Generated by: https://openapi-generator.tech
*/
use crate::models;
use serde::{Deserialize, Serialize};
#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)]
pub struct SendInboxMessageRequest {
/// Account ID
#[serde(rename = "accountId")]
pub account_id: String,
/// Message text
#[serde(rename = "message", skip_serializing_if = "Option::is_none")]
pub message: Option<String>,
/// URL of the attachment to send (image, video, audio, or file). Must be publicly accessible. For binary file uploads, use multipart/form-data instead. On WhatsApp, an image, video, or file combined with `buttons` renders as the header of one interactive reply-button message. Audio cannot be combined with buttons.
#[serde(rename = "attachmentUrl", skip_serializing_if = "Option::is_none")]
pub attachment_url: Option<String>,
/// WhatsApp only (Meta Direct Send). Sends a business-initiated UTILITY message without an approved template, e.g. outside the 24-hour customer service window. Meta matches or auto-creates a template asynchronously. - The WhatsApp Business Account must be eligible for Direct Send; otherwise the send fails, telling you to use an approved message template. - Supported only for text messages (link preview ok) and interactive messages (reply buttons, CTA URL buttons, voice-call button, header of text/image/video/document). - Cannot be combined with template, attachments, location, or contacts. - Utility messages only; marketing content is not allowed. - Accepted on the JSON body only, not on multipart requests.
#[serde(rename = "category", skip_serializing_if = "Option::is_none")]
pub category: Option<Category>,
/// WhatsApp and iMessage. Set false to send the message without a link-preview thumbnail. Ignored on other platforms. - WhatsApp: affects the first URL. - iMessage: every link renders as plain text. Defaults to true, which is how every WhatsApp text has been sent to date. Accepted on the JSON body only, not on multipart requests.
#[serde(rename = "linkPreview", skip_serializing_if = "Option::is_none")]
pub link_preview: Option<bool>,
/// Type of attachment. Defaults to file if not specified.
#[serde(rename = "attachmentType", skip_serializing_if = "Option::is_none")]
pub attachment_type: Option<AttachmentType>,
/// WhatsApp only. Display name for a document sent via attachmentUrl with attachmentType: file (e.g. \"Report.pdf\"). Maps to the recipient's file name; without it WhatsApp derives the name from the URL and shows \"Untitled\". Ignored for image/video/audio and for binary uploads (which use the uploaded file's name).
#[serde(rename = "attachmentName", skip_serializing_if = "Option::is_none")]
pub attachment_name: Option<String>,
/// WhatsApp only. When `true` on an audio attachment, the message is sent as a voice message (PTT): the recipient sees the waveform + voice-note UI instead of a basic audio attachment. Ignored for non-audio attachments. The audio file MUST be `.ogg` encoded with the OPUS codec (mono), per Meta's voice-message contract; other formats are rejected by WhatsApp.
#[serde(rename = "voiceNote", skip_serializing_if = "Option::is_none")]
pub voice_note: Option<bool>,
/// iMessage only (JSON body only). Bold title line rendered above the message text. Rejected with 400 on other platforms; ignored on voice-message sends.
#[serde(rename = "subject", skip_serializing_if = "Option::is_none")]
pub subject: Option<String>,
/// Email threads only (Google / Microsoft accounts, JSON body only). Extra recipients copied on the reply.
#[serde(rename = "cc", skip_serializing_if = "Option::is_none")]
pub cc: Option<Vec<String>>,
/// iMessage only (JSON body only). Apple screen/bubble animation played when the message arrives. Rejected with 400 on other platforms.
#[serde(rename = "effect", skip_serializing_if = "Option::is_none")]
pub effect: Option<Effect>,
/// iMessage only (JSON body only). When `true`, attaches the sender's contact card (vCard) so the recipient can save the sender. Counts as message content on its own, so `message` becomes optional.
#[serde(rename = "contactCard", skip_serializing_if = "Option::is_none")]
pub contact_card: Option<bool>,
/// iMessage only (JSON body only). Overrides the delivery channel for this one send; the provider otherwise picks it automatically. The sender must carry the matching add-on (SMS, RCS or WhatsApp), or the send fails. Not a default to set on every request. Rejected with 400 on other platforms.
#[serde(rename = "channel", skip_serializing_if = "Option::is_none")]
pub channel: Option<Channel>,
/// Instagram only (JSON body only; 400 on other platforms). Shares one of the account's own published posts in the DM, by its Instagram media id (the `id` returned by the media endpoints, not a permalink). Meta only accepts media the account owns. Sent on its own: cannot be combined with `message`, attachments, `quickReplies`, `buttons`, `template` or `sticker` (400). `messageTag: HUMAN_AGENT` is allowed. Works on accounts connected with Instagram Login and with Facebook Login.
#[serde(rename = "sharedMediaId", skip_serializing_if = "Option::is_none")]
pub shared_media_id: Option<String>,
/// Instagram only (JSON body only). Sends a sticker instead of text; `like_heart` is the heart sticker. Sent on its own: cannot be combined with `message`, attachments, `quickReplies`, `buttons`, `template` or `sharedMediaId` (400). `messageTag: HUMAN_AGENT` is allowed. Rejected with 400 on other platforms.
#[serde(rename = "sticker", skip_serializing_if = "Option::is_none")]
pub sticker: Option<Sticker>,
/// Quick reply buttons. Mutually exclusive with buttons. Max 13 items.
#[serde(rename = "quickReplies", skip_serializing_if = "Option::is_none")]
pub quick_replies: Option<Vec<models::SendInboxMessageRequestQuickRepliesInner>>,
/// Action buttons. Max 3 items. Mutually exclusive with quickReplies. **Instagram / Facebook.** Also mutually exclusive with `template`: a Meta message carries one body shape, so sending both is a 400 rather than a silent drop of the buttons. The buttons and `message` render as Meta's button_template (one bubble with the text and the buttons below it), so `message` must be 640 characters or less when buttons are attached (400 otherwise). **WhatsApp.** Buttons always render as interactive reply buttons. Only `title` and `payload` are used; `type`, `url`, and `phone` are ignored. WhatsApp has no URL/phone button in this field: use the `interactive` field with `type: cta_url` for a link button. `payload` becomes the button reply ID delivered on the `message.received` webhook when the user taps. For a simple reply-button message, provide `title` + `payload` and set `type: postback`, e.g. `{ \"type\": \"postback\", \"title\": \"Yes\", \"payload\": \"yes\" }`. Combine `buttons` with `attachmentUrl` and `attachmentType` `image`, `video`, or `file` to render one WhatsApp message with a media header, body text and reply buttons. Audio is not a supported interactive header and returns 400 when combined with buttons.
#[serde(rename = "buttons", skip_serializing_if = "Option::is_none")]
pub buttons: Option<Vec<models::SendInboxMessageRequestButtonsInner>>,
#[serde(rename = "template", skip_serializing_if = "Option::is_none")]
pub template: Option<Box<models::SendInboxMessageRequestTemplate>>,
#[serde(rename = "interactive", skip_serializing_if = "Option::is_none")]
pub interactive: Option<Box<models::SendInboxMessageRequestInteractive>>,
#[serde(rename = "replyMarkup", skip_serializing_if = "Option::is_none")]
pub reply_markup: Option<Box<models::SendInboxMessageRequestReplyMarkup>>,
/// Facebook messaging type. Required when using messageTag.
#[serde(rename = "messagingType", skip_serializing_if = "Option::is_none")]
pub messaging_type: Option<MessagingType>,
/// Facebook and Instagram. To reply after the 24h window, send HUMAN_AGENT with messagingType MESSAGE_TAG: it works up to 7 days after the person's last message, for replies typed by a person only (Meta does not allow it on automated messages). Meta retired the other tags, so they fail.
#[serde(rename = "messageTag", skip_serializing_if = "Option::is_none")]
pub message_tag: Option<MessageTag>,
/// Platform message ID to quote-reply to. - WhatsApp: the wamid. - Telegram: the Telegram message ID (message.platformMessageId on webhooks, and `id` on each entry of the list-messages endpoint). - Slack: threads the reply (thread_ts) instead of quoting. - Instagram and Facebook Messenger: no send-side quote replies. The message is sent without a quote and the successful response includes a warnings entry with code ignored_field and param replyTo. - Other platforms without send-side reply support ignore this field.
#[serde(rename = "replyTo", skip_serializing_if = "Option::is_none")]
pub reply_to: Option<String>,
#[serde(rename = "location", skip_serializing_if = "Option::is_none")]
pub location: Option<Box<models::SendInboxMessageRequestLocation>>,
/// WhatsApp-only. Send one or more contact cards.
#[serde(rename = "contacts", skip_serializing_if = "Option::is_none")]
pub contacts: Option<Vec<models::SendInboxMessageRequestContactsInner>>,
}
impl SendInboxMessageRequest {
pub fn new(account_id: String) -> SendInboxMessageRequest {
SendInboxMessageRequest {
account_id,
message: None,
attachment_url: None,
category: None,
link_preview: None,
attachment_type: None,
attachment_name: None,
voice_note: None,
subject: None,
cc: None,
effect: None,
contact_card: None,
channel: None,
shared_media_id: None,
sticker: None,
quick_replies: None,
buttons: None,
template: None,
interactive: None,
reply_markup: None,
messaging_type: None,
message_tag: None,
reply_to: None,
location: None,
contacts: None,
}
}
}
/// WhatsApp only (Meta Direct Send). Sends a business-initiated UTILITY message without an approved template, e.g. outside the 24-hour customer service window. Meta matches or auto-creates a template asynchronously. - The WhatsApp Business Account must be eligible for Direct Send; otherwise the send fails, telling you to use an approved message template. - Supported only for text messages (link preview ok) and interactive messages (reply buttons, CTA URL buttons, voice-call button, header of text/image/video/document). - Cannot be combined with template, attachments, location, or contacts. - Utility messages only; marketing content is not allowed. - Accepted on the JSON body only, not on multipart requests.
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
pub enum Category {
#[serde(rename = "utility")]
Utility,
}
impl Default for Category {
fn default() -> Category {
Self::Utility
}
}
/// Type of attachment. Defaults to file if not specified.
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
pub enum AttachmentType {
#[serde(rename = "image")]
Image,
#[serde(rename = "video")]
Video,
#[serde(rename = "audio")]
Audio,
#[serde(rename = "file")]
File,
}
impl Default for AttachmentType {
fn default() -> AttachmentType {
Self::Image
}
}
/// iMessage only (JSON body only). Apple screen/bubble animation played when the message arrives. Rejected with 400 on other platforms.
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
pub enum Effect {
#[serde(rename = "slam")]
Slam,
#[serde(rename = "loud")]
Loud,
#[serde(rename = "gentle")]
Gentle,
#[serde(rename = "invisibleInk")]
InvisibleInk,
#[serde(rename = "echo")]
Echo,
#[serde(rename = "spotlight")]
Spotlight,
#[serde(rename = "balloons")]
Balloons,
#[serde(rename = "confetti")]
Confetti,
#[serde(rename = "love")]
Love,
#[serde(rename = "lasers")]
Lasers,
#[serde(rename = "fireworks")]
Fireworks,
#[serde(rename = "shootingStar")]
ShootingStar,
#[serde(rename = "celebration")]
Celebration,
}
impl Default for Effect {
fn default() -> Effect {
Self::Slam
}
}
/// iMessage only (JSON body only). Overrides the delivery channel for this one send; the provider otherwise picks it automatically. The sender must carry the matching add-on (SMS, RCS or WhatsApp), or the send fails. Not a default to set on every request. Rejected with 400 on other platforms.
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
pub enum Channel {
#[serde(rename = "imessage")]
Imessage,
#[serde(rename = "sms")]
Sms,
#[serde(rename = "rcs")]
Rcs,
#[serde(rename = "whatsapp")]
Whatsapp,
}
impl Default for Channel {
fn default() -> Channel {
Self::Imessage
}
}
/// Instagram only (JSON body only). Sends a sticker instead of text; `like_heart` is the heart sticker. Sent on its own: cannot be combined with `message`, attachments, `quickReplies`, `buttons`, `template` or `sharedMediaId` (400). `messageTag: HUMAN_AGENT` is allowed. Rejected with 400 on other platforms.
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
pub enum Sticker {
#[serde(rename = "like_heart")]
LikeHeart,
}
impl Default for Sticker {
fn default() -> Sticker {
Self::LikeHeart
}
}
/// Facebook messaging type. Required when using messageTag.
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
pub enum MessagingType {
#[serde(rename = "RESPONSE")]
Response,
#[serde(rename = "UPDATE")]
Update,
#[serde(rename = "MESSAGE_TAG")]
MessageTag,
}
impl Default for MessagingType {
fn default() -> MessagingType {
Self::Response
}
}
/// Facebook and Instagram. To reply after the 24h window, send HUMAN_AGENT with messagingType MESSAGE_TAG: it works up to 7 days after the person's last message, for replies typed by a person only (Meta does not allow it on automated messages). Meta retired the other tags, so they fail.
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
pub enum MessageTag {
#[serde(rename = "CONFIRMED_EVENT_UPDATE")]
ConfirmedEventUpdate,
#[serde(rename = "POST_PURCHASE_UPDATE")]
PostPurchaseUpdate,
#[serde(rename = "ACCOUNT_UPDATE")]
AccountUpdate,
#[serde(rename = "HUMAN_AGENT")]
HumanAgent,
}
impl Default for MessageTag {
fn default() -> MessageTag {
Self::ConfirmedEventUpdate
}
}