use crate::client::Client;
use crate::error::Result;
use serde::{Deserialize, Serialize};
pub struct WabaApi {
client: Client,
waba_id: String,
}
impl WabaApi {
pub(crate) fn new(client: Client, waba_id: String) -> Self {
Self { client, waba_id }
}
pub async fn get(&self) -> Result<WabaDetails> {
let url = self.client.endpoint_url(&self.waba_id);
self.client.get(&url).await
}
pub async fn subscribe_webhooks(&self) -> Result<crate::types::SuccessResponse> {
let body = SubscribeRequest {
subscribed_fields: vec![
"messages".to_string(),
"message_template_status_update".to_string(),
],
};
let url = format!(
"{}/subscribed_apps",
self.client.endpoint_url(&self.waba_id)
);
self.client.post(&url, &body).await
}
pub async fn subscribe_fields(
&self,
fields: Vec<WebhookField>,
) -> Result<crate::types::SuccessResponse> {
let body = SubscribeRequest {
subscribed_fields: fields.iter().map(|f| f.as_str().to_string()).collect(),
};
let url = format!(
"{}/subscribed_apps",
self.client.endpoint_url(&self.waba_id)
);
self.client.post(&url, &body).await
}
pub async fn unsubscribe_webhooks(&self) -> Result<crate::types::SuccessResponse> {
let url = format!(
"{}/subscribed_apps",
self.client.endpoint_url(&self.waba_id)
);
self.client.delete(&url).await
}
pub async fn get_subscribed_apps(&self) -> Result<SubscribedAppsResponse> {
let url = format!(
"{}/subscribed_apps",
self.client.endpoint_url(&self.waba_id)
);
self.client.get(&url).await
}
pub async fn get_phone_numbers(&self) -> Result<PhoneNumbersResponse> {
let url = format!(
"{}/phone_numbers",
self.client.endpoint_url(&self.waba_id)
);
self.client.get(&url).await
}
pub async fn get_assigned_users(&self) -> Result<AssignedUsersResponse> {
let url = format!(
"{}/assigned_users",
self.client.endpoint_url(&self.waba_id)
);
self.client.get(&url).await
}
pub async fn get_system_users(&self) -> Result<SystemUsersResponse> {
let url = format!(
"{}/system_users",
self.client.endpoint_url(&self.waba_id)
);
self.client.get(&url).await
}
pub async fn get_templates(&self) -> Result<WabaTemplatesResponse> {
let url = format!(
"{}/message_templates",
self.client.endpoint_url(&self.waba_id)
);
self.client.get(&url).await
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum WebhookField {
Messages,
MessageTemplateStatusUpdate,
MessageTemplateQualityUpdate,
AccountAlerts,
AccountReviewUpdate,
AccountUpdate,
BusinessCapabilityUpdate,
PhoneNumberNameUpdate,
PhoneNumberQualityUpdate,
Security,
}
impl WebhookField {
fn as_str(&self) -> &'static str {
match self {
WebhookField::Messages => "messages",
WebhookField::MessageTemplateStatusUpdate => "message_template_status_update",
WebhookField::MessageTemplateQualityUpdate => "message_template_quality_update",
WebhookField::AccountAlerts => "account_alerts",
WebhookField::AccountReviewUpdate => "account_review_update",
WebhookField::AccountUpdate => "account_update",
WebhookField::BusinessCapabilityUpdate => "business_capability_update",
WebhookField::PhoneNumberNameUpdate => "phone_number_name_update",
WebhookField::PhoneNumberQualityUpdate => "phone_number_quality_update",
WebhookField::Security => "security",
}
}
}
#[derive(Debug, Serialize)]
struct SubscribeRequest {
subscribed_fields: Vec<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WabaDetails {
pub id: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub timezone_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub message_template_namespace: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub account_review_status: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub business_verification_status: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub primary_funding_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub purchase_order_number: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SubscribedAppsResponse {
pub data: Vec<SubscribedApp>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SubscribedApp {
pub id: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
#[serde(default)]
pub subscribed_fields: Vec<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PhoneNumbersResponse {
pub data: Vec<WabaPhoneNumber>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WabaPhoneNumber {
pub id: String,
pub display_phone_number: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub verified_name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub quality_rating: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AssignedUsersResponse {
pub data: Vec<AssignedUser>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AssignedUser {
pub id: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
#[serde(default)]
pub tasks: Vec<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SystemUsersResponse {
pub data: Vec<SystemUser>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SystemUser {
pub id: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub role: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WabaTemplatesResponse {
pub data: Vec<WabaTemplate>,
#[serde(skip_serializing_if = "Option::is_none")]
pub paging: Option<Paging>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WabaTemplate {
pub id: String,
pub name: String,
pub status: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub category: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub language: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Paging {
#[serde(skip_serializing_if = "Option::is_none")]
pub cursors: Option<PagingCursors>,
#[serde(skip_serializing_if = "Option::is_none")]
pub next: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PagingCursors {
#[serde(skip_serializing_if = "Option::is_none")]
pub before: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub after: Option<String>,
}