/*
* 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).
*
* The version of the OpenAPI document: 1.34.0
* Contact: support@zernio.com
* Generated by: https://openapi-generator.tech
*/
use reqwest;
use serde::{Deserialize, Serialize, de::Error as _};
use crate::{apis::ResponseContent, models};
use super::{Error, configuration, ContentType};
/// struct for typed errors of method [`on_account_ads_initial_sync_completed`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum OnAccountAdsInitialSyncCompletedError {
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`on_account_connected`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum OnAccountConnectedError {
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`on_account_disconnected`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum OnAccountDisconnectedError {
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`on_ad_status_changed`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum OnAdStatusChangedError {
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`on_analytics_synced`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum OnAnalyticsSyncedError {
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`on_call_ended`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum OnCallEndedError {
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`on_call_failed`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum OnCallFailedError {
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`on_call_permission_request`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum OnCallPermissionRequestError {
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`on_call_received`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum OnCallReceivedError {
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`on_comment_received`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum OnCommentReceivedError {
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`on_conversation_control_changed`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum OnConversationControlChangedError {
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`on_conversation_started`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum OnConversationStartedError {
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`on_lead_received`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum OnLeadReceivedError {
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`on_message_deleted`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum OnMessageDeletedError {
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`on_message_delivered`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum OnMessageDeliveredError {
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`on_message_edited`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum OnMessageEditedError {
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`on_message_failed`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum OnMessageFailedError {
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`on_message_read`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum OnMessageReadError {
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`on_message_received`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum OnMessageReceivedError {
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`on_message_sent`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum OnMessageSentError {
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`on_phone_number_stock_available`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum OnPhoneNumberStockAvailableError {
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`on_post_cancelled`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum OnPostCancelledError {
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`on_post_external_created`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum OnPostExternalCreatedError {
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`on_post_external_deleted`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum OnPostExternalDeletedError {
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`on_post_external_updated`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum OnPostExternalUpdatedError {
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`on_post_failed`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum OnPostFailedError {
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`on_post_partial`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum OnPostPartialError {
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`on_post_platform_deleted`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum OnPostPlatformDeletedError {
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`on_post_platform_failed`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum OnPostPlatformFailedError {
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`on_post_platform_published`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum OnPostPlatformPublishedError {
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`on_post_published`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum OnPostPublishedError {
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`on_post_recycled`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum OnPostRecycledError {
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`on_post_scheduled`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum OnPostScheduledError {
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`on_post_tik_tok_url_resolved`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum OnPostTikTokUrlResolvedError {
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`on_reaction_received`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum OnReactionReceivedError {
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`on_referral_received`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum OnReferralReceivedError {
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`on_review_new`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum OnReviewNewError {
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`on_review_updated`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum OnReviewUpdatedError {
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`on_verification_approved`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum OnVerificationApprovedError {
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`on_verification_failed`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum OnVerificationFailedError {
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`on_webhook_test`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum OnWebhookTestError {
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`on_whats_app_account_name_status_updated`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum OnWhatsAppAccountNameStatusUpdatedError {
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`on_whats_app_automatic_event`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum OnWhatsAppAutomaticEventError {
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`on_whats_app_number_action_required`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum OnWhatsAppNumberActionRequiredError {
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`on_whats_app_number_activated`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum OnWhatsAppNumberActivatedError {
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`on_whats_app_number_declined`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum OnWhatsAppNumberDeclinedError {
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`on_whats_app_number_kyc_submitted`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum OnWhatsAppNumberKycSubmittedError {
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`on_whats_app_number_reactivated`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum OnWhatsAppNumberReactivatedError {
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`on_whats_app_number_released`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum OnWhatsAppNumberReleasedError {
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`on_whats_app_number_suspended`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum OnWhatsAppNumberSuspendedError {
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`on_whats_app_number_verification_required`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum OnWhatsAppNumberVerificationRequiredError {
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`on_whats_app_template_category_updated`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum OnWhatsAppTemplateCategoryUpdatedError {
UnknownValue(serde_json::Value),
}
/// struct for typed errors of method [`on_whats_app_template_status_updated`]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum OnWhatsAppTemplateStatusUpdatedError {
UnknownValue(serde_json::Value),
}
/// Fired once per ads-enabled account when the initial sync (ad-account discovery + 90-day historical ad backfill) completes. The `sync` block reports whether the backfill succeeded and how many ads were synced.
pub async fn on_account_ads_initial_sync_completed(configuration: &configuration::Configuration, webhook_payload_account_ads_initial_sync_completed: models::WebhookPayloadAccountAdsInitialSyncCompleted) -> Result<(), Error<OnAccountAdsInitialSyncCompletedError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_body_webhook_payload_account_ads_initial_sync_completed = webhook_payload_account_ads_initial_sync_completed;
let uri_str = format!("{}/account.ads.initial_sync_completed", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_webhook_payload_account_ads_initial_sync_completed);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
if !status.is_client_error() && !status.is_server_error() {
Ok(())
} else {
let content = resp.text().await?;
let entity: Option<OnAccountAdsInitialSyncCompletedError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent { status, content, entity }))
}
}
/// Fired when a account is successfully connected.
pub async fn on_account_connected(configuration: &configuration::Configuration, webhook_payload_account_connected: models::WebhookPayloadAccountConnected) -> Result<(), Error<OnAccountConnectedError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_body_webhook_payload_account_connected = webhook_payload_account_connected;
let uri_str = format!("{}/account.connected", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_webhook_payload_account_connected);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
if !status.is_client_error() && !status.is_server_error() {
Ok(())
} else {
let content = resp.text().await?;
let entity: Option<OnAccountConnectedError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent { status, content, entity }))
}
}
/// Fired when a connected account becomes disconnected.
pub async fn on_account_disconnected(configuration: &configuration::Configuration, webhook_payload_account_disconnected: models::WebhookPayloadAccountDisconnected) -> Result<(), Error<OnAccountDisconnectedError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_body_webhook_payload_account_disconnected = webhook_payload_account_disconnected;
let uri_str = format!("{}/account.disconnected", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_webhook_payload_account_disconnected);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
if !status.is_client_error() && !status.is_server_error() {
Ok(())
} else {
let content = resp.text().await?;
let entity: Option<OnAccountDisconnectedError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent { status, content, entity }))
}
}
/// Fired when a campaign, ad set, or ad on a connected ad platform changes status. Currently emitted only for Meta (`metaads`). Subscribed to two Meta `ad_account` webhook fields: - `in_process_ad_objects` - the ad object finished processing and exited the `IN_PROCESS` state. `status.raw` carries Meta's `status_name` (e.g. `ACTIVE`, `PAUSED`, `ARCHIVED`, `DELETED`). - `with_issues_ad_objects` - the ad object entered the `WITH_ISSUES` state. `status.raw` is set to `WITH_ISSUES` and the `error` block is populated from Meta's `error_code` / `error_summary` / `error_message`. `adObject.level` mirrors Meta's `level` and is one of `CAMPAIGN`, `AD_SET`, or `AD`. Creative-level events are not forwarded. Branch on `status.raw` to handle each transition; use `error.code` (when present) as the stable discriminator, since `error.summary` and `error.message` are localized to the ad-account owner's Meta locale. The `error` block is optional. It's present on most `WITH_ISSUES` events but can be absent (Meta does not always include diagnostics), and is never present on any other status. Always null-check `error` before reading `error.code`. **Fan-out:** matching is keyed on `adObject.platformAdAccountId`. When multiple connected Zernio `metaads` accounts are linked to the same Meta ad account, each receives its own delivery.
pub async fn on_ad_status_changed(configuration: &configuration::Configuration, webhook_payload_ad_status_changed: models::WebhookPayloadAdStatusChanged) -> Result<(), Error<OnAdStatusChangedError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_body_webhook_payload_ad_status_changed = webhook_payload_ad_status_changed;
let uri_str = format!("{}/ad.status_changed", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_webhook_payload_ad_status_changed);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
if !status.is_client_error() && !status.is_server_error() {
Ok(())
} else {
let content = resp.text().await?;
let entity: Option<OnAdStatusChangedError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent { status, content, entity }))
}
}
/// Fired once per connected account each time its analytics sync cycle completes successfully. Poll-driven (roughly hourly per account), not real-time, and never fired for a skipped or failed cycle. A trigger, not a transport: the payload carries no metrics and no cursor. On receipt, call `GET /v1/analytics/delta` with your own last `nextCursor` to read every post whose analytics changed, across every account, in one paginated stream instead of polling analytics once per account. The feed holds back its most recent few seconds of writes, so a read issued the instant this event lands often returns an empty page for that account. Poll again with the same cursor rather than reading an empty page as \"nothing changed\". High volume (roughly one delivery per connected account per hour). Subscribe to it on a dedicated webhook endpoint: a subscription's consecutive-failure count is shared across all of its events, so an outage while this event is flowing can suppress the low-volume publishing events on the same subscription.
pub async fn on_analytics_synced(configuration: &configuration::Configuration, webhook_payload_analytics_synced: models::WebhookPayloadAnalyticsSynced) -> Result<(), Error<OnAnalyticsSyncedError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_body_webhook_payload_analytics_synced = webhook_payload_analytics_synced;
let uri_str = format!("{}/analytics.synced", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_webhook_payload_analytics_synced);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
if !status.is_client_error() && !status.is_server_error() {
Ok(())
} else {
let content = resp.text().await?;
let entity: Option<OnAnalyticsSyncedError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent { status, content, entity }))
}
}
/// Fired on call hangup with the duration and a zero-markup billing breakdown (Meta cost, Telnyx cost, recording surcharge, total). Costs are pass-through; no margin is applied.
pub async fn on_call_ended(configuration: &configuration::Configuration, webhook_payload_call_ended: models::WebhookPayloadCallEnded) -> Result<(), Error<OnCallEndedError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_body_webhook_payload_call_ended = webhook_payload_call_ended;
let uri_str = format!("{}/call.ended", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_webhook_payload_call_ended);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
if !status.is_client_error() && !status.is_server_error() {
Ok(())
} else {
let content = resp.text().await?;
let entity: Option<OnCallEndedError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent { status, content, entity }))
}
}
/// Fired when a call setup or in-progress call fails (Meta rejected the connect, Telnyx returned an error, etc.). Payload carries the upstream error code and message.
pub async fn on_call_failed(configuration: &configuration::Configuration, webhook_payload_call_failed: models::WebhookPayloadCallFailed) -> Result<(), Error<OnCallFailedError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_body_webhook_payload_call_failed = webhook_payload_call_failed;
let uri_str = format!("{}/call.failed", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_webhook_payload_call_failed);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
if !status.is_client_error() && !status.is_server_error() {
Ok(())
} else {
let content = resp.text().await?;
let entity: Option<OnCallFailedError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent { status, content, entity }))
}
}
/// Fired when a consumer replies to a `call_permission_request` interactive message (or its marketing-template variant). Carries the response (`accept` / `reject`), whether the grant is permanent, and the expiration timestamp when it is temporary.
pub async fn on_call_permission_request(configuration: &configuration::Configuration, webhook_payload_call_permission_request: models::WebhookPayloadCallPermissionRequest) -> Result<(), Error<OnCallPermissionRequestError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_body_webhook_payload_call_permission_request = webhook_payload_call_permission_request;
let uri_str = format!("{}/call.permission_request", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_webhook_payload_call_permission_request);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
if !status.is_client_error() && !status.is_server_error() {
Ok(())
} else {
let content = resp.text().await?;
let entity: Option<OnCallPermissionRequestError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent { status, content, entity }))
}
}
/// Fired when a WhatsApp Business Call connects. For inbound (UIC) calls the event fires at the moment our Telnyx trunk bridges the consumer leg to the customer's forward-to destination; for outbound (BIC) calls it fires immediately after Meta accepts the connect. Branch on `call.direction` to distinguish.
pub async fn on_call_received(configuration: &configuration::Configuration, webhook_payload_call_received: models::WebhookPayloadCallReceived) -> Result<(), Error<OnCallReceivedError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_body_webhook_payload_call_received = webhook_payload_call_received;
let uri_str = format!("{}/call.received", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_webhook_payload_call_received);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
if !status.is_client_error() && !status.is_server_error() {
Ok(())
} else {
let content = resp.text().await?;
let entity: Option<OnCallReceivedError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent { status, content, entity }))
}
}
/// Fired when a new comment is received on a tracked post. Delivered for Instagram, Facebook, Threads, YouTube, LinkedIn, Bluesky, Reddit and TikTok. X/Twitter does NOT fire this event. Instagram, Facebook and TikTok arrive in real time from the platform's own webhook; the rest are poll-driven, so delivery is not instant. TikTok needs an account connected through the TikTok for Business app.
pub async fn on_comment_received(configuration: &configuration::Configuration, webhook_payload_comment: models::WebhookPayloadComment) -> Result<(), Error<OnCommentReceivedError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_body_webhook_payload_comment = webhook_payload_comment;
let uri_str = format!("{}/comment.received", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_webhook_payload_comment);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
if !status.is_client_error() && !status.is_server_error() {
Ok(())
} else {
let content = resp.text().await?;
let entity: Option<OnCommentReceivedError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent { status, content, entity }))
}
}
/// WhatsApp only. Fired when control of a conversation moves between Meta Business Agent and your app (Meta's `messaging_handovers`), or when the agent is first seen answering a thread. While `control.owner` is `ai_agent`, inbound messages arrive on `message.received` with `metadata.standby: true` and the agent's replies on `message.sent` with `source: meta_business_agent`. Sending any message takes control back; release it with `POST /v1/inbox/conversations/{conversationId}/thread-control`.
pub async fn on_conversation_control_changed(configuration: &configuration::Configuration, webhook_payload_conversation_control_changed: models::WebhookPayloadConversationControlChanged) -> Result<(), Error<OnConversationControlChangedError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_body_webhook_payload_conversation_control_changed = webhook_payload_conversation_control_changed;
let uri_str = format!("{}/conversation.control_changed", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_webhook_payload_conversation_control_changed);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
if !status.is_client_error() && !status.is_server_error() {
Ok(())
} else {
let content = resp.text().await?;
let entity: Option<OnConversationControlChangedError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent { status, content, entity }))
}
}
/// Fired once when a new conversation begins between one of your connected accounts and a contact, in either direction. Works across every DM platform (Instagram, Messenger/Facebook, Telegram, WhatsApp, X, Reddit, Bluesky, TikTok). Naturally deduped: a given conversation only fires this event the very first time it appears.
pub async fn on_conversation_started(configuration: &configuration::Configuration, webhook_payload_conversation_started: models::WebhookPayloadConversationStarted) -> Result<(), Error<OnConversationStartedError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_body_webhook_payload_conversation_started = webhook_payload_conversation_started;
let uri_str = format!("{}/conversation.started", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_webhook_payload_conversation_started);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
if !status.is_client_error() && !status.is_server_error() {
Ok(())
} else {
let content = resp.text().await?;
let entity: Option<OnConversationStartedError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent { status, content, entity }))
}
}
/// Fired when a new lead is submitted against a Meta Lead Gen (Instant) Form and ingested via the Page `leadgen` webhook. `lead.fields` is the question-key to answer map; `lead.formId` / `lead.adId` give provenance. Requires the Ads add-on.
pub async fn on_lead_received(configuration: &configuration::Configuration, webhook_payload_lead: models::WebhookPayloadLead) -> Result<(), Error<OnLeadReceivedError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_body_webhook_payload_lead = webhook_payload_lead;
let uri_str = format!("{}/lead.received", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_webhook_payload_lead);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
if !status.is_client_error() && !status.is_server_error() {
Ok(())
} else {
let content = resp.text().await?;
let entity: Option<OnLeadReceivedError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent { status, content, entity }))
}
}
/// Fired when a sender deletes (unsends) a message. Supported on Instagram (incoming unsend) and WhatsApp in both directions: an outgoing message the business deleted (via the Cloud API, or from the WhatsApp Business app on a Coexistence number) and an incoming message the customer deleted. Read `message.direction` to tell the two apart. The payload retains the pre-delete text and attachments so API consumers can access the original content for moderation or compliance; the Zernio dashboard UI hides it.
pub async fn on_message_deleted(configuration: &configuration::Configuration, webhook_payload_message_deleted: models::WebhookPayloadMessageDeleted) -> Result<(), Error<OnMessageDeletedError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_body_webhook_payload_message_deleted = webhook_payload_message_deleted;
let uri_str = format!("{}/message.deleted", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_webhook_payload_message_deleted);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
if !status.is_client_error() && !status.is_server_error() {
Ok(())
} else {
let content = resp.text().await?;
let entity: Option<OnMessageDeletedError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent { status, content, entity }))
}
}
/// Fired when an outgoing message is delivered to the recipient. Supported on WhatsApp and Facebook Messenger.
pub async fn on_message_delivered(configuration: &configuration::Configuration, webhook_payload_message_delivery_status: models::WebhookPayloadMessageDeliveryStatus) -> Result<(), Error<OnMessageDeliveredError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_body_webhook_payload_message_delivery_status = webhook_payload_message_delivery_status;
let uri_str = format!("{}/message.delivered", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_webhook_payload_message_delivery_status);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
if !status.is_client_error() && !status.is_server_error() {
Ok(())
} else {
let content = resp.text().await?;
let entity: Option<OnMessageDeliveredError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent { status, content, entity }))
}
}
/// Fired when a sender edits a previously-sent message. Supported on Instagram, Facebook Messenger, Telegram, and WhatsApp. The payload includes the full editHistory so consumers can show prior versions.
pub async fn on_message_edited(configuration: &configuration::Configuration, webhook_payload_message_edited: models::WebhookPayloadMessageEdited) -> Result<(), Error<OnMessageEditedError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_body_webhook_payload_message_edited = webhook_payload_message_edited;
let uri_str = format!("{}/message.edited", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_webhook_payload_message_edited);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
if !status.is_client_error() && !status.is_server_error() {
Ok(())
} else {
let content = resp.text().await?;
let entity: Option<OnMessageEditedError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent { status, content, entity }))
}
}
/// Fired when an outgoing message fails to deliver. Currently only emitted for WhatsApp (other platforms don't expose per-message failure via webhook). The payload error object contains code, title, and message from the platform.
pub async fn on_message_failed(configuration: &configuration::Configuration, webhook_payload_message_delivery_status: models::WebhookPayloadMessageDeliveryStatus) -> Result<(), Error<OnMessageFailedError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_body_webhook_payload_message_delivery_status = webhook_payload_message_delivery_status;
let uri_str = format!("{}/message.failed", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_webhook_payload_message_delivery_status);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
if !status.is_client_error() && !status.is_server_error() {
Ok(())
} else {
let content = resp.text().await?;
let entity: Option<OnMessageFailedError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent { status, content, entity }))
}
}
/// Fired when an outgoing message is read by the recipient. Supported on WhatsApp, Facebook Messenger, and Instagram.
pub async fn on_message_read(configuration: &configuration::Configuration, webhook_payload_message_delivery_status: models::WebhookPayloadMessageDeliveryStatus) -> Result<(), Error<OnMessageReadError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_body_webhook_payload_message_delivery_status = webhook_payload_message_delivery_status;
let uri_str = format!("{}/message.read", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_webhook_payload_message_delivery_status);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
if !status.is_client_error() && !status.is_server_error() {
Ok(())
} else {
let content = resp.text().await?;
let entity: Option<OnMessageReadError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent { status, content, entity }))
}
}
/// Fired when a new inbox message is received.
pub async fn on_message_received(configuration: &configuration::Configuration, webhook_payload_message: models::WebhookPayloadMessage) -> Result<(), Error<OnMessageReceivedError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_body_webhook_payload_message = webhook_payload_message;
let uri_str = format!("{}/message.received", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_webhook_payload_message);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
if !status.is_client_error() && !status.is_server_error() {
Ok(())
} else {
let content = resp.text().await?;
let entity: Option<OnMessageReceivedError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent { status, content, entity }))
}
}
/// Fired when a message is sent via the API, or from the WhatsApp Business app on Coexistence numbers. Sends that carry platform-specific context deliver it under `metadata`, so a quote-reply sent through the API arrives with `metadata.quotedMessageId` and mirroring CRMs can thread it without a lookup. Which surfaces actually carry that reference is documented on `WebhookPayloadMessageSent.metadata.quotedMessageId`; a quote-reply sent from the WhatsApp Business or Instagram app is not one of them.
pub async fn on_message_sent(configuration: &configuration::Configuration, webhook_payload_message_sent: models::WebhookPayloadMessageSent) -> Result<(), Error<OnMessageSentError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_body_webhook_payload_message_sent = webhook_payload_message_sent;
let uri_str = format!("{}/message.sent", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_webhook_payload_message_sent);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
if !status.is_client_error() && !status.is_server_error() {
Ok(())
} else {
let content = resp.text().await?;
let entity: Option<OnMessageSentError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent { status, content, entity }))
}
}
/// Fired by the stock sweep (every 6h) the first time a country you watch via POST /v1/phone-numbers/stock-watches has deliverable numbers again. The watch is consumed, so the event fires once per watch; the stock counts are a snapshot and numbers are sold first come, first served. Buy with POST /v1/phone-numbers/purchase.
pub async fn on_phone_number_stock_available(configuration: &configuration::Configuration, webhook_payload_phone_number_stock_available: models::WebhookPayloadPhoneNumberStockAvailable) -> Result<(), Error<OnPhoneNumberStockAvailableError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_body_webhook_payload_phone_number_stock_available = webhook_payload_phone_number_stock_available;
let uri_str = format!("{}/phone_number.stock_available", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_webhook_payload_phone_number_stock_available);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
if !status.is_client_error() && !status.is_server_error() {
Ok(())
} else {
let content = resp.text().await?;
let entity: Option<OnPhoneNumberStockAvailableError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent { status, content, entity }))
}
}
/// Fired when a post publishing job is cancelled.
pub async fn on_post_cancelled(configuration: &configuration::Configuration, webhook_payload_post: models::WebhookPayloadPost) -> Result<(), Error<OnPostCancelledError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_body_webhook_payload_post = webhook_payload_post;
let uri_str = format!("{}/post.cancelled", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_webhook_payload_post);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
if !status.is_client_error() && !status.is_server_error() {
Ok(())
} else {
let content = resp.text().await?;
let entity: Option<OnPostCancelledError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent { status, content, entity }))
}
}
/// Fired when Zernio's background sync detects a natively-authored post (created outside Zernio, e.g. a Google Business Profile localPost made in the Google UI) for the first time. Poll-driven (~hourly), not real-time. `post.source` is always \"external\".
pub async fn on_post_external_created(configuration: &configuration::Configuration, webhook_payload_external_post: models::WebhookPayloadExternalPost) -> Result<(), Error<OnPostExternalCreatedError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_body_webhook_payload_external_post = webhook_payload_external_post;
let uri_str = format!("{}/post.external.created", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_webhook_payload_external_post);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
if !status.is_client_error() && !status.is_server_error() {
Ok(())
} else {
let content = resp.text().await?;
let entity: Option<OnPostExternalCreatedError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent { status, content, entity }))
}
}
/// Fired when a tracked native post is detected as removed from the platform. `post.deletedAt` carries the detection time. Coverage is bounded to the most recent posts the platform listing returns. Detection is a diff against the posts a prior sync already indexed, so an account for which no post has ever been indexed can never emit this event, no matter how the subscription is configured.
pub async fn on_post_external_deleted(configuration: &configuration::Configuration, webhook_payload_external_post: models::WebhookPayloadExternalPost) -> Result<(), Error<OnPostExternalDeletedError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_body_webhook_payload_external_post = webhook_payload_external_post;
let uri_str = format!("{}/post.external.deleted", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_webhook_payload_external_post);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
if !status.is_client_error() && !status.is_server_error() {
Ok(())
} else {
let content = resp.text().await?;
let entity: Option<OnPostExternalDeletedError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent { status, content, entity }))
}
}
/// Fired when a tracked native post's text or media changed on the platform. Detected by comparing text/media structure and, where available, the platform's own edit timestamp; a media-URL-only refresh does not fire this.
pub async fn on_post_external_updated(configuration: &configuration::Configuration, webhook_payload_external_post: models::WebhookPayloadExternalPost) -> Result<(), Error<OnPostExternalUpdatedError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_body_webhook_payload_external_post = webhook_payload_external_post;
let uri_str = format!("{}/post.external.updated", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_webhook_payload_external_post);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
if !status.is_client_error() && !status.is_server_error() {
Ok(())
} else {
let content = resp.text().await?;
let entity: Option<OnPostExternalUpdatedError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent { status, content, entity }))
}
}
/// Fired when a post fails to publish on all target platforms.
pub async fn on_post_failed(configuration: &configuration::Configuration, webhook_payload_post: models::WebhookPayloadPost) -> Result<(), Error<OnPostFailedError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_body_webhook_payload_post = webhook_payload_post;
let uri_str = format!("{}/post.failed", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_webhook_payload_post);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
if !status.is_client_error() && !status.is_server_error() {
Ok(())
} else {
let content = resp.text().await?;
let entity: Option<OnPostFailedError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent { status, content, entity }))
}
}
/// Fired when a post publishes on some platforms and fails on others.
pub async fn on_post_partial(configuration: &configuration::Configuration, webhook_payload_post: models::WebhookPayloadPost) -> Result<(), Error<OnPostPartialError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_body_webhook_payload_post = webhook_payload_post;
let uri_str = format!("{}/post.partial", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_webhook_payload_post);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
if !status.is_client_error() && !status.is_server_error() {
Ok(())
} else {
let content = resp.text().await?;
let entity: Option<OnPostPartialError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent { status, content, entity }))
}
}
/// Fired when Zernio's background sync detects that a platform target published through Zernio was later deleted on the platform (e.g. the user deleted the Instagram post natively). Detection is poll-driven (~hourly), not real-time, and fires once per platform target. `platform.deletedAt` carries the detection time. Detection is listing-based: a false positive self-heals in Zernio's data when the post reappears, but the event is not retracted. Coverage is bounded to the posts the platform listing returns. Detection is a diff against the posts a prior sync already indexed, so an account for which no post has ever been indexed can never emit this event, no matter how the subscription is configured.
pub async fn on_post_platform_deleted(configuration: &configuration::Configuration, webhook_payload_post_platform: models::WebhookPayloadPostPlatform) -> Result<(), Error<OnPostPlatformDeletedError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_body_webhook_payload_post_platform = webhook_payload_post_platform;
let uri_str = format!("{}/post.platform.deleted", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_webhook_payload_post_platform);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
if !status.is_client_error() && !status.is_server_error() {
Ok(())
} else {
let content = resp.text().await?;
let entity: Option<OnPostPlatformDeletedError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent { status, content, entity }))
}
}
/// Fired once per platform target inside a post as that platform fails permanently. Temporary/retryable failures do NOT fire this event, only permanent ones do, so retry loops stay quiet. The envelope event (`post.failed` / `post.partial`) fires separately AFTER all platforms have terminated. Can also fire a second time for a target that already emitted `post.platform.published`, if background reconciliation later discovers the publish never actually completed.
pub async fn on_post_platform_failed(configuration: &configuration::Configuration, webhook_payload_post_platform: models::WebhookPayloadPostPlatform) -> Result<(), Error<OnPostPlatformFailedError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_body_webhook_payload_post_platform = webhook_payload_post_platform;
let uri_str = format!("{}/post.platform.failed", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_webhook_payload_post_platform);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
if !status.is_client_error() && !status.is_server_error() {
Ok(())
} else {
let content = resp.text().await?;
let entity: Option<OnPostPlatformFailedError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent { status, content, entity }))
}
}
/// Fired once per platform target inside a post as that platform finishes publishing successfully. Does NOT wait for the post-level rollup, so consumers building incremental UIs get notified immediately, even when other platforms on the same post are still processing. The envelope event (`post.published` / `post.partial`) fires separately AFTER all platforms have terminated. A target that later fails background reconciliation (e.g. a Facebook video Meta accepted but never actually published) emits `post.platform.failed` for the same target afterward.
pub async fn on_post_platform_published(configuration: &configuration::Configuration, webhook_payload_post_platform: models::WebhookPayloadPostPlatform) -> Result<(), Error<OnPostPlatformPublishedError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_body_webhook_payload_post_platform = webhook_payload_post_platform;
let uri_str = format!("{}/post.platform.published", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_webhook_payload_post_platform);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
if !status.is_client_error() && !status.is_server_error() {
Ok(())
} else {
let content = resp.text().await?;
let entity: Option<OnPostPlatformPublishedError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent { status, content, entity }))
}
}
/// Fired when a post is successfully published.
pub async fn on_post_published(configuration: &configuration::Configuration, webhook_payload_post: models::WebhookPayloadPost) -> Result<(), Error<OnPostPublishedError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_body_webhook_payload_post = webhook_payload_post;
let uri_str = format!("{}/post.published", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_webhook_payload_post);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
if !status.is_client_error() && !status.is_server_error() {
Ok(())
} else {
let content = resp.text().await?;
let entity: Option<OnPostPublishedError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent { status, content, entity }))
}
}
/// Fired when a post is recycled (cloned and re-scheduled for publishing). The new clone also fires a post.scheduled event.
pub async fn on_post_recycled(configuration: &configuration::Configuration, webhook_payload_post: models::WebhookPayloadPost) -> Result<(), Error<OnPostRecycledError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_body_webhook_payload_post = webhook_payload_post;
let uri_str = format!("{}/post.recycled", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_webhook_payload_post);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
if !status.is_client_error() && !status.is_server_error() {
Ok(())
} else {
let content = resp.text().await?;
let entity: Option<OnPostRecycledError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent { status, content, entity }))
}
}
/// Fired whenever a post enters the scheduled state: created with a schedule, added to a queue, a draft promoted to scheduled or queued, a failed or partial post retried, or a recycled clone created. Not fired when an already-scheduled post is edited or rescheduled.
pub async fn on_post_scheduled(configuration: &configuration::Configuration, webhook_payload_post: models::WebhookPayloadPost) -> Result<(), Error<OnPostScheduledError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_body_webhook_payload_post = webhook_payload_post;
let uri_str = format!("{}/post.scheduled", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_webhook_payload_post);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
if !status.is_client_error() && !status.is_server_error() {
Ok(())
} else {
let content = resp.text().await?;
let entity: Option<OnPostScheduledError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent { status, content, entity }))
}
}
/// Fired when an already-published TikTok platform entry gets its public URL backfilled. TikTok exposes the numeric video id asynchronously (often minutes after PUBLISH_COMPLETE), so the terminal events can carry an empty `publishedUrl` for TikTok. This event delivers `platform.publishedUrl` and the resolved `platform.platformPostId` once available. At most once per platform target; never fires for drafts or private posts (no public URL exists). Payload shape is identical to `post.platform.published`.
pub async fn on_post_tik_tok_url_resolved(configuration: &configuration::Configuration, webhook_payload_post_platform: models::WebhookPayloadPostPlatform) -> Result<(), Error<OnPostTikTokUrlResolvedError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_body_webhook_payload_post_platform = webhook_payload_post_platform;
let uri_str = format!("{}/post.tiktok.url_resolved", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_webhook_payload_post_platform);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
if !status.is_client_error() && !status.is_server_error() {
Ok(())
} else {
let content = resp.text().await?;
let entity: Option<OnPostTikTokUrlResolvedError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent { status, content, entity }))
}
}
/// Fired when a participant adds or removes an emoji reaction on a message. Supported on WhatsApp, Telegram, Slack, Instagram and Facebook Messenger. Distinct from message.received so a reaction (e.g. a thumbs-up) is not mistaken for an inbound message. The `reaction.action` field is `added` or `removed`. On WhatsApp and Meta removals the platform does not report which emoji was removed, so `reaction.emoji` may be an empty string. Instagram and Facebook accounts connected before reactions shipped only emit this event after their webhook subscription is refreshed; reconnect the account if reactions never arrive. Requires the Inbox add-on.
pub async fn on_reaction_received(configuration: &configuration::Configuration, webhook_payload_reaction: models::WebhookPayloadReaction) -> Result<(), Error<OnReactionReceivedError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_body_webhook_payload_reaction = webhook_payload_reaction;
let uri_str = format!("{}/reaction.received", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_webhook_payload_reaction);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
if !status.is_client_error() && !status.is_server_error() {
Ok(())
} else {
let content = resp.text().await?;
let entity: Option<OnReactionReceivedError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent { status, content, entity }))
}
}
/// Fired when someone opens an EXISTING Instagram or Messenger thread through an attributable entry point - an ig.me / m.me link with a `ref` parameter, or (Messenger) a returning Click-to-Message ad click - which Meta delivers as a standalone referral with no message attached. A referral that rides an inbound message (first message of a thread, icebreaker taps, returning ad clicks on Instagram) arrives on `message.received` under `metadata.referral` instead; the two never fire for the same click. The first referral captured on a conversation is also persisted on it (see `metadata` on `GET /v1/inbox/conversations`). Requires the Inbox add-on.
pub async fn on_referral_received(configuration: &configuration::Configuration, webhook_payload_referral: models::WebhookPayloadReferral) -> Result<(), Error<OnReferralReceivedError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_body_webhook_payload_referral = webhook_payload_referral;
let uri_str = format!("{}/referral.received", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_webhook_payload_referral);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
if !status.is_client_error() && !status.is_server_error() {
Ok(())
} else {
let content = resp.text().await?;
let entity: Option<OnReferralReceivedError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent { status, content, entity }))
}
}
/// Fired when a new review is posted on a connected account. Currently supported for Google Business Profile (real-time via Pub/Sub). Requires the Inbox add-on.
pub async fn on_review_new(configuration: &configuration::Configuration, webhook_payload_review_new: models::WebhookPayloadReviewNew) -> Result<(), Error<OnReviewNewError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_body_webhook_payload_review_new = webhook_payload_review_new;
let uri_str = format!("{}/review.new", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_webhook_payload_review_new);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
if !status.is_client_error() && !status.is_server_error() {
Ok(())
} else {
let content = resp.text().await?;
let entity: Option<OnReviewNewError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent { status, content, entity }))
}
}
/// Fired when a Google Business Profile reviewer edits their review text or rating, or when a reply is posted through POST /v1/inbox/reviews/{reviewId}/reply. A reply written directly in Google's own interface does NOT fire this event, because Google emits no notification for it. Payload shape matches review.new. Requires the Inbox add-on.
pub async fn on_review_updated(configuration: &configuration::Configuration, webhook_payload_review_updated: models::WebhookPayloadReviewUpdated) -> Result<(), Error<OnReviewUpdatedError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_body_webhook_payload_review_updated = webhook_payload_review_updated;
let uri_str = format!("{}/review.updated", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_webhook_payload_review_updated);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
if !status.is_client_error() && !status.is_server_error() {
Ok(())
} else {
let content = resp.text().await?;
let entity: Option<OnReviewUpdatedError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent { status, content, entity }))
}
}
/// Fired when a managed-OTP verification is approved (the user submitted the correct code to POST /v1/verify/verifications/{verificationId}/check).
pub async fn on_verification_approved(configuration: &configuration::Configuration, on_verification_approved_request: models::OnVerificationApprovedRequest) -> Result<(), Error<OnVerificationApprovedError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_body_on_verification_approved_request = on_verification_approved_request;
let uri_str = format!("{}/verification.approved", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_on_verification_approved_request);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
if !status.is_client_error() && !status.is_server_error() {
Ok(())
} else {
let content = resp.text().await?;
let entity: Option<OnVerificationApprovedError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent { status, content, entity }))
}
}
/// Fired when a managed-OTP verification is exhausted (the maximum number of wrong code attempts was reached).
pub async fn on_verification_failed(configuration: &configuration::Configuration, on_verification_failed_request: models::OnVerificationFailedRequest) -> Result<(), Error<OnVerificationFailedError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_body_on_verification_failed_request = on_verification_failed_request;
let uri_str = format!("{}/verification.failed", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_on_verification_failed_request);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
if !status.is_client_error() && !status.is_server_error() {
Ok(())
} else {
let content = resp.text().await?;
let entity: Option<OnVerificationFailedError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent { status, content, entity }))
}
}
/// Fired when sending a test webhook to verify the endpoint configuration.
pub async fn on_webhook_test(configuration: &configuration::Configuration, webhook_payload_test: models::WebhookPayloadTest) -> Result<(), Error<OnWebhookTestError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_body_webhook_payload_test = webhook_payload_test;
let uri_str = format!("{}/webhook.test", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_webhook_payload_test);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
if !status.is_client_error() && !status.is_server_error() {
Ok(())
} else {
let content = resp.text().await?;
let entity: Option<OnWebhookTestError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent { status, content, entity }))
}
}
/// Fired when Meta finishes reviewing a WhatsApp Business display-name change. Forwarded from Meta's `phone_number_name_update` webhook field on the WhatsApp Business Account. Fires only on a review outcome (`name.status` APPROVED, DECLINED, or PENDING_REVIEW); a name applied without review reports `name_status: AVAILABLE_WITHOUT_REVIEW` on the phone node instead and produces no event here. `decision` REJECTED maps to DECLINED and DEFERRED maps to PENDING_REVIEW, matching the `name_status` vocabulary returned by `GET /v1/whatsapp/number-info`. Delivery is at-least-once; dedupe on `(account.accountId, name.status, name.requestedName)`.
pub async fn on_whats_app_account_name_status_updated(configuration: &configuration::Configuration, webhook_payload_whats_app_account_name_status_updated: models::WebhookPayloadWhatsAppAccountNameStatusUpdated) -> Result<(), Error<OnWhatsAppAccountNameStatusUpdatedError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_body_webhook_payload_whats_app_account_name_status_updated = webhook_payload_whats_app_account_name_status_updated;
let uri_str = format!("{}/whatsapp.account.name_status_updated", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_webhook_payload_whats_app_account_name_status_updated);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
if !status.is_client_error() && !status.is_server_error() {
Ok(())
} else {
let content = resp.text().await?;
let entity: Option<OnWhatsAppAccountNameStatusUpdatedError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent { status, content, entity }))
}
}
/// Fired when Meta's automatic event identification (opt-in during Embedded Signup; not available for EU/UK/JP businesses) detects a lead or purchase in a Click-to-WhatsApp conversation. Branch on `eventName` (`LeadSubmitted` | `Purchase`). Carries the `ctwa_clid`. Meta omits that clid on a minority of referrals on any number (coexistence or not, most often WhatsApp Status placements); when it does, this event can supply it and Zernio writes it back onto the conversation, so POST /v1/whatsapp/conversions becomes usable for the thread.
pub async fn on_whats_app_automatic_event(configuration: &configuration::Configuration, on_whats_app_automatic_event_request: models::OnWhatsAppAutomaticEventRequest) -> Result<(), Error<OnWhatsAppAutomaticEventError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_body_on_whats_app_automatic_event_request = on_whats_app_automatic_event_request;
let uri_str = format!("{}/whatsapp.automatic_event", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_on_whats_app_automatic_event_request);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
if !status.is_client_error() && !status.is_server_error() {
Ok(())
} else {
let content = resp.text().await?;
let entity: Option<OnWhatsAppAutomaticEventError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent { status, content, entity }))
}
}
/// Fired when the regulator asks for more information on an already-placed regulated number order. The number stays pending (nothing was rejected); the customer can provide the missing information from the dashboard, or via the remediation endpoint. `reason` carries the regulator's request verbatim when available. `requirements` lists every requirement on the order with the reviewer's current verdict; the `declined` ones are what to fix, keyed by the same `requirementId` the remediation endpoint uses. Verdicts only change when a reviewer acts, so they describe the review at `reviewedAt`, the time of the reviewer's last comment.
pub async fn on_whats_app_number_action_required(configuration: &configuration::Configuration, on_whats_app_number_action_required_request: models::OnWhatsAppNumberActionRequiredRequest) -> Result<(), Error<OnWhatsAppNumberActionRequiredError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_body_on_whats_app_number_action_required_request = on_whats_app_number_action_required_request;
let uri_str = format!("{}/whatsapp.number.action_required", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_on_whats_app_number_action_required_request);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
if !status.is_client_error() && !status.is_server_error() {
Ok(())
} else {
let content = resp.text().await?;
let entity: Option<OnWhatsAppNumberActionRequiredError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent { status, content, entity }))
}
}
/// Fired when a purchased WhatsApp number becomes active and usable. Both the synchronous (Tier 1/2) path and the asynchronous regulated (Tier 3/4) path land here. Lets integrators react without polling GET /v1/phone-numbers.
pub async fn on_whats_app_number_activated(configuration: &configuration::Configuration, on_whats_app_number_activated_request: models::OnWhatsAppNumberActivatedRequest) -> Result<(), Error<OnWhatsAppNumberActivatedError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_body_on_whats_app_number_activated_request = on_whats_app_number_activated_request;
let uri_str = format!("{}/whatsapp.number.activated", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_on_whats_app_number_activated_request);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
if !status.is_client_error() && !status.is_server_error() {
Ok(())
} else {
let content = resp.text().await?;
let entity: Option<OnWhatsAppNumberActivatedError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent { status, content, entity }))
}
}
/// Fired when a regulated (Tier 3/4) number order is declined or fails review. The number is never billed. `reason` carries the reviewer's rejection reason when available.
pub async fn on_whats_app_number_declined(configuration: &configuration::Configuration, on_whats_app_number_declined_request: models::OnWhatsAppNumberDeclinedRequest) -> Result<(), Error<OnWhatsAppNumberDeclinedError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_body_on_whats_app_number_declined_request = on_whats_app_number_declined_request;
let uri_str = format!("{}/whatsapp.number.declined", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_on_whats_app_number_declined_request);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
if !status.is_client_error() && !status.is_server_error() {
Ok(())
} else {
let content = resp.text().await?;
let entity: Option<OnWhatsAppNumberDeclinedError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent { status, content, entity }))
}
}
/// Fired when an end customer completes a hosted KYC share link (POST /v1/phone-numbers/kyc/share). The number enters review (pending_regulatory) under your account; `whatsapp.number.activated` or `whatsapp.number.declined` follows once the provider rules on it.
pub async fn on_whats_app_number_kyc_submitted(configuration: &configuration::Configuration, on_whats_app_number_kyc_submitted_request: models::OnWhatsAppNumberKycSubmittedRequest) -> Result<(), Error<OnWhatsAppNumberKycSubmittedError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_body_on_whats_app_number_kyc_submitted_request = on_whats_app_number_kyc_submitted_request;
let uri_str = format!("{}/whatsapp.number.kyc_submitted", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_on_whats_app_number_kyc_submitted_request);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
if !status.is_client_error() && !status.is_server_error() {
Ok(())
} else {
let content = resp.text().await?;
let entity: Option<OnWhatsAppNumberKycSubmittedError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent { status, content, entity }))
}
}
/// Fired when a suspended number is reactivated (e.g. the payment recovered) and is usable again.
pub async fn on_whats_app_number_reactivated(configuration: &configuration::Configuration, on_whats_app_number_reactivated_request: models::OnWhatsAppNumberReactivatedRequest) -> Result<(), Error<OnWhatsAppNumberReactivatedError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_body_on_whats_app_number_reactivated_request = on_whats_app_number_reactivated_request;
let uri_str = format!("{}/whatsapp.number.reactivated", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_on_whats_app_number_reactivated_request);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
if !status.is_client_error() && !status.is_server_error() {
Ok(())
} else {
let content = resp.text().await?;
let entity: Option<OnWhatsAppNumberReactivatedError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent { status, content, entity }))
}
}
/// Fired when a number is released and is no longer usable (by the user, a billing cleanup, or an admin). Terminal. `reason` carries the cause (e.g. `user_requested`, `cleanup_suspended`).
pub async fn on_whats_app_number_released(configuration: &configuration::Configuration, on_whats_app_number_released_request: models::OnWhatsAppNumberReleasedRequest) -> Result<(), Error<OnWhatsAppNumberReleasedError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_body_on_whats_app_number_released_request = on_whats_app_number_released_request;
let uri_str = format!("{}/whatsapp.number.released", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_on_whats_app_number_released_request);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
if !status.is_client_error() && !status.is_server_error() {
Ok(())
} else {
let content = resp.text().await?;
let entity: Option<OnWhatsAppNumberReleasedError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent { status, content, entity }))
}
}
/// Fired when an active number is suspended (e.g. a failed payment). The number stops working until the issue is resolved, after which a `whatsapp.number.reactivated` event is sent. `reason` carries the cause (e.g. `payment_failed`, `subscription_ended`).
pub async fn on_whats_app_number_suspended(configuration: &configuration::Configuration, on_whats_app_number_suspended_request: models::OnWhatsAppNumberSuspendedRequest) -> Result<(), Error<OnWhatsAppNumberSuspendedError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_body_on_whats_app_number_suspended_request = on_whats_app_number_suspended_request;
let uri_str = format!("{}/whatsapp.number.suspended", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_on_whats_app_number_suspended_request);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
if !status.is_client_error() && !status.is_server_error() {
Ok(())
} else {
let content = resp.text().await?;
let entity: Option<OnWhatsAppNumberSuspendedError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent { status, content, entity }))
}
}
/// Fired when a regulated number has an out-of-band identity-verification step (e.g. Onfido). `verificationUrl` is the link to forward to the number's end user; the order completes once they pass.
pub async fn on_whats_app_number_verification_required(configuration: &configuration::Configuration, on_whats_app_number_verification_required_request: models::OnWhatsAppNumberVerificationRequiredRequest) -> Result<(), Error<OnWhatsAppNumberVerificationRequiredError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_body_on_whats_app_number_verification_required_request = on_whats_app_number_verification_required_request;
let uri_str = format!("{}/whatsapp.number.verification_required", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_on_whats_app_number_verification_required_request);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
if !status.is_client_error() && !status.is_server_error() {
Ok(())
} else {
let content = resp.text().await?;
let entity: Option<OnWhatsAppNumberVerificationRequiredError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent { status, content, entity }))
}
}
/// Fired when Meta reclassifies a WhatsApp Business template's category after approval. Forwarded from Meta's `template_category_update` webhook field on the WhatsApp Business Account. Category drives Meta's per-conversation tariff and whether the template is subject to the recipient's marketing opt-out. `template.changeType` is `scheduled` (24h advance notice) or `applied`; `template.category` is always the category right now.
pub async fn on_whats_app_template_category_updated(configuration: &configuration::Configuration, webhook_payload_whats_app_template_category_updated: models::WebhookPayloadWhatsAppTemplateCategoryUpdated) -> Result<(), Error<OnWhatsAppTemplateCategoryUpdatedError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_body_webhook_payload_whats_app_template_category_updated = webhook_payload_whats_app_template_category_updated;
let uri_str = format!("{}/whatsapp.template.category_updated", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_webhook_payload_whats_app_template_category_updated);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
if !status.is_client_error() && !status.is_server_error() {
Ok(())
} else {
let content = resp.text().await?;
let entity: Option<OnWhatsAppTemplateCategoryUpdatedError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent { status, content, entity }))
}
}
/// Fired when Meta finishes (re)reviewing a WhatsApp Business template attached to a connected WABA. Forwarded from Meta's `message_template_status_update` webhook field on the WhatsApp Business Account. Consumers branch on `template.status` (APPROVED, REJECTED, PENDING, PAUSED, DISABLED, IN_APPEAL, PENDING_DELETION). Meta does not include the previous status or the template's category in this event.
pub async fn on_whats_app_template_status_updated(configuration: &configuration::Configuration, webhook_payload_whats_app_template_status_updated: models::WebhookPayloadWhatsAppTemplateStatusUpdated) -> Result<(), Error<OnWhatsAppTemplateStatusUpdatedError>> {
// add a prefix to parameters to efficiently prevent name collisions
let p_body_webhook_payload_whats_app_template_status_updated = webhook_payload_whats_app_template_status_updated;
let uri_str = format!("{}/whatsapp.template.status_updated", configuration.base_path);
let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
if let Some(ref user_agent) = configuration.user_agent {
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
}
if let Some(ref token) = configuration.bearer_access_token {
req_builder = req_builder.bearer_auth(token.to_owned());
};
req_builder = req_builder.json(&p_body_webhook_payload_whats_app_template_status_updated);
let req = req_builder.build()?;
let resp = configuration.client.execute(req).await?;
let status = resp.status();
if !status.is_client_error() && !status.is_server_error() {
Ok(())
} else {
let content = resp.text().await?;
let entity: Option<OnWhatsAppTemplateStatusUpdatedError> = serde_json::from_str(&content).ok();
Err(Error::ResponseError(ResponseContent { status, content, entity }))
}
}