whatsapp-business-rs

Crates.iowhatsapp-business-rs
lib.rswhatsapp-business-rs
version0.5.0
created_at2025-07-19 16:23:12.350323+00
updated_at2025-11-27 12:21:42.261987+00
descriptionRust SDK for the WhatsApp Business API โ€” bulk messaging, batching, and multi-tenant support.
homepagehttps://github.com/veecore/whatsapp-business-rs
repositoryhttps://github.com/veecore/whatsapp-business-rs
max_upload_size
id1760363
size773,882
Victor (veecore)

documentation

https://docs.rs/whatsapp-business-rs

README

โšก๏ธ whatsapp-business-rs

Crates.io Docs.rs CI

The ultimate Rust SDK for building WhatsApp Business integrations.

whatsapp-business-rs is a type-safe, async-ready toolkit for the complete WhatsApp Business Platform โ€” built with love in Rust ๐Ÿฆ€.

Send messages, handle webhooks, manage catalogs, or batch thousands of API calls in one shot. This crate brings it all together in a blazing-fast, developer-first package.


๐ŸŽฎ See it in Action!

Check out our Bulls & Cows Game Bot example, built entirely with this crate. It showcases an interactive, stateful bot using a state machine pattern.

Game screenshot


โœจ Features That Matter

  • ๐Ÿ“ฉ Messaging โ€” Send text, media, interactive buttons, templates, replies, and reactions.
  • ๐Ÿ“ฆ Batch Requests โ€” Compose and chain dependent API calls in a single round-trip.
  • โšก Webhook Server โ€” Spin up an async webhook server with built-in signature validation.
  • ๐Ÿ‘ฅ Onboarding & Registration โ€” Guide new numbers safely through setup.
  • ๐Ÿ›’ Catalog & Orders โ€” Manage products and commerce flows.
  • ๐Ÿง‘โ€๐Ÿคโ€๐Ÿง‘ Multi-Tenant Ready โ€” Easily serve multiple WhatsApp Business Accounts. Attach per-request auth tokens instead of re-initializing clients. Ideal for SaaS platforms.
  • ๐Ÿงฉ Feature Flags โ€” Enable only what you need: batch, server, onboarding.

๐Ÿ“ฆ Installation

# Add the crate and enable the server + message reply extensions
cargo add whatsapp-business-rs --features "server incoming_message_ext"

(Disable features you donโ€™t need for smaller builds.)


๐Ÿš€ Getting Started

Before diving in, youโ€™ll need a few things from the Meta for Developers dashboard:

  • Access Token
  • Phone Number ID
  • Business Account ID

๐Ÿ“ Quickstart Examples

๐Ÿ”น Send a Text Message (The "Hello, World!")

use whatsapp_business_rs::Client;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = Client::new("YOUR_ACCESS_TOKEN").await?;
    let business_phone_id = "YOUR_BUSINESS_NUMBER_ID";
    let recipient_number = "+16012345678"; 

    client.message(business_phone_id)
        .send(recipient_number, "Hello from Rust! ๐Ÿฆ€")
        .await?;
    
    println!("Text message sent!");
    Ok(())
}

๐Ÿ”น Start a Webhook Server (Echo Bot)

This example uses the incoming_message_ext feature for easy replies.

use whatsapp_business_rs::{
    client::Client,
    server::{Server, WebhookHandler, EventContext, IncomingMessage},
    app::SubscriptionField,
};
use std::error::Error;

// Define a simple handler struct
#[derive(Debug, Clone)]
struct EchoHandler;

impl WebhookHandler for EchoHandler {
    async fn handle_message(&self, _ctx: EventContext, msg: IncomingMessage) {
        println!("Received message from: {}", msg.sender.wa_id);
        
        // Echo the received message back to the sender
        msg.reply(msg.clone()).await;   
    }
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
    // Client is needed for registering the webhook
    let client = Client::new("YOUR_APP_OR_SYSTEM_USER_TOKEN").await?; 

    // Build and start the webhook server
    Server::builder()
        .endpoint("127.0.0.1:8080".parse().unwrap()) // Local address
        .verify_payload("YOUR_APP_SECRET") // For payload verification
        .build()
        .serve(EchoHandler, client.clone()) // Pass client for replying
        .register_webhook( // One-time webhook registration
            client
                .app("YOUR_APP_ID")
                .configure_webhook(("YOUR_VERIFY_TOKEN", "https://your-public-url.com"))
                .events([SubscriptionField::Messages].into())
                .with_auth(client.auth().clone()), // Use client's auth
        )
        .await?;

    Ok(())
}

๐Ÿš€ Send Bulk Messages with Batch

Batching reduces round-trips and lets you chain dependent requests.

use whatsapp_business_rs::Client;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = Client::new("YOUR_ACCESS_TOKEN").await?;
    let sender = client.message("YOUR_BUSINESS_PHONE_ID");

    client
        .batch()
        .include(sender.send("+1234567890", "Hi A!"))
        .include(sender.send("+1234667809", "Hi B!"))
        .include(sender.send("+1224537891", "Hi C!"))
        .execute()
        .await?;

    Ok(())
}

๐Ÿ”น Send an Interactive Message (Buttons)

use whatsapp_business_rs::message::Draft;
use whatsapp_business_rs::Client;

async fn send_cta_example() -> Result<(), Box<dyn std::error::Error>> {
    let client = Client::new("YOUR_ACCESS_TOKEN").await?;

    let draft = Draft::text("Would you like to continue?")
        .add_reply_button("yes_callback", "Yes")
        .add_reply_button("no_callback", "No")
        .footer("Please select an option.");

    client.message("YOUR_BUSINESS_PHONE_ID").send("+16012345678", draft).await?;
    Ok(())
}

๐Ÿ”น Send an Interactive Message (List of Options)

use whatsapp_business_rs::message::Draft;
use whatsapp_business_rs::Client;

async fn send_option_list_example() -> Result<(), Box<dyn std::error::Error>> {
    let client = Client::new("YOUR_ACCESS_TOKEN").await?;

    let draft = Draft::new()
        .body("Please make a selection.")
        .header("Main Menu ๐Ÿ•")
        .list("View Options") // The button text that opens the list
        .add_list_option("buy_pepperoni", "Pepperoni", "Classic pepperoni pizza.")
        .add_list_option("buy_margherita", "Margherita", "Simple and delicious.");

    client.message("YOUR_BUSINESS_PHONE_ID").send("+16012345678", draft).await?;
    Ok(())
}

๐Ÿ”น Send Media (Video from Path)

use whatsapp_business_rs::{Client, Media};

async fn send_video_example() -> Result<(), Box<dyn std::error::Error>> {
    let client = Client::new("YOUR_ACCESS_TOKEN").await?;

    let video = Media::from_path("path/to/your/video.mp4")
        .await?
        .caption("Check out this cool video!");

    client.message("YOUR_BUSINESS_PHONE_ID").send("+16012345678", video).await?;
    Ok(())
}

๐Ÿ”น Send a Location Message

use whatsapp_business_rs::{Client, Location};

async fn send_location_example() -> Result<(), Box<dyn std::error::Error>> {
    let client = Client::new("YOUR_ACCESS_TOKEN").await?;

    let location = Location::new(37.4421, -122.1615)
        .name("Philz Coffee")
        .address("101 Forest Ave, Palo Alto, CA 94301");

    client.message("YOUR_BUSINESS_PHONE_ID").send("+16012345678", location).await?;
    Ok(())
}

๐Ÿ”น List Product Catalogs

use whatsapp_business_rs::{client::Client, Waba, waba::CatalogMetadataField};
use futures::TryStreamExt as _;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = Client::new("YOUR_ACCESS_TOKEN").await?;
    
    let mut catalogs = client
        .waba("YOUR_WABA_ID")
        .list_catalogs()
        .into_stream();

    println!("Listing catalogs:");
    while let Some(catalog) = catalogs.try_next().await? {
        println!("{:?}", catalog);
    }
    Ok(())
}

๐Ÿ”น Create a Product

use whatsapp_business_rs::catalog::{ProductData, Price};
use whatsapp_business_rs::Client;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = Client::new("YOUR_ACCESS_TOKEN").await?;
    
    let product = ProductData::default()
        .name("Rust Programming Book")
        .description("Learn Rust with this comprehensive guide")
        .price(Price(39.99, "USD".into()))
        .build("rust-book-001"); // Your retailer ID

    let result = client.catalog("YOUR_CATALOG_ID")
        .create_product(product)
        .await?;

    println!("Product created with ID: {}", result.product.product_id());
    Ok(())
}

๐Ÿ’ฌ Why whatsapp-business-rs?

  • ๐Ÿง  Zero Guessing: Compile-time type safety ensures your integrations are robust.
  • โš™๏ธ Built for Production: Powered by reqwest, axum, and tokio for high performance.
  • ๐Ÿงช Testable: A clean, fluent API design makes your code inherently testable.
  • ๐Ÿง‘โ€๐Ÿคโ€๐Ÿง‘ Multi-Tenant Native: Built-in support for managing multiple business accounts from one app (see "Features").
  • ๐Ÿ’ฅ Extensible: Add your own layers or handlers, or fork and customize.

๐Ÿค Contributing

Contributions are very welcome! Open an issue, suggest features, or send a PR.


๐Ÿฆ€ Let's Rust WhatsApp Right.

Tired of bloated SDKs, missing docs, or inconsistent behavior? With whatsapp-business-rs, you own the stack โ€” fast, clean, and async-native. Perfect for bots, CRMs, and next-gen commerce apps.

Commit count: 21

cargo fmt