A Rust client library for the Facebook Graph API v23.0, with full support for both native and WebAssembly (WASM) environments.
- β Facebook Graph API v23.0 - Latest version with 2-year support guarantee
- π¦ Rust & WASM - Works in both backend servers and frontend browsers
- π OAuth Flow - Complete manual login flow implementation
- π Pages API - Manage Facebook pages, posts, photos, and videos
- πΈ Instagram Business API - Access Instagram business accounts, media, and hashtags
- π Batch Requests - Optimize API calls with batch operations
- β‘ Async/Await - Modern asynchronous Rust patterns
- π― Type-Safe - Strongly-typed API responses with serde
- π§ Flexible HTTP - Choose between
reqwest(default) orweb-sysfor HTTP
- Rust 1.81.0 or later
- A Facebook App with App ID and App Secret (Create one here)
- Valid Facebook access tokens for API calls
Add this to your Cargo.toml:
[dependencies]
facebook_api_rs = "0.1.2"Or install via cargo:
cargo add facebook_api_rsYou can also install directly from GitHub:
[dependencies]
facebook_api_rs = { git = "https://github.com/osain-az/facebook-api-rs" }Or specify a particular branch, tag, or commit:
[dependencies]
# Use main branch
facebook_api_rs = { git = "https://github.com/osain-az/facebook-api-rs", branch = "main" }
# Use specific tag
facebook_api_rs = { git = "https://github.com/osain-az/facebook-api-rs", tag = "v0.1.0" }
# Use specific commit
facebook_api_rs = { git = "https://github.com/osain-az/facebook-api-rs", rev = "abc123" }The crate provides two HTTP client implementations:
reqwest(default) - Uses reqwest for native and WASM targetsweb-sys- Uses web-sys for browser-based WASM applications
[dependencies]
facebook_api_rs = { git = "https://github.com/osain-az/facebook-api-rs" }[dependencies]
facebook_api_rs = { git = "https://github.com/osain-az/facebook-api-rs", default-features = false, features = ["web-sys"] }Generate a Facebook OAuth login URL to authenticate users:
use facebook_api_rs::prelude::{Config, LoginResponseType, LoginUrlParameters};
fn create_login_url() -> String {
let config = Config::new(
"YOUR_APP_ID".to_string(),
"https://yourapp.com/callback".to_string()
);
LoginUrlParameters::new(config)
.add_response_type(LoginResponseType::TOKEN)
.add_scope(vec!["email", "public_profile"])
.full_login_url()
}After users authenticate, extract tokens from the redirect URL:
use facebook_api_rs::prelude::UserToken;
async fn handle_callback(redirect_url: String) -> Result<(), Box<dyn std::error::Error>> {
let tokens = UserToken::extract_user_tokens(redirect_url);
if let Some(error) = tokens.login_error {
eprintln!("Login error: {:?}", error);
return Err(Box::new(error));
}
println!("Access token: {}", tokens.access_token);
Ok(())
}Use the client to interact with Facebook Graph API:
use facebook_api_rs::prelude::{Client, TokenLiveType};
async fn get_user_pages(user_token: UserToken) -> Result<(), Box<dyn std::error::Error>> {
let client = Client::new(user_token, String::new());
let accounts = client
.accounts(TokenLiveType::LONGLIVE)
.get()
.await?;
for account in accounts.data {
println!("Page: {} (ID: {})", account.name, account.id);
}
Ok(())
}By default, this crate uses Facebook Graph API v23.0. You can specify a custom version if needed:
use facebook_api_rs::prelude::{Config, Client, UserToken};
// Using default v23.0
let config = Config::new(
"your_app_id".to_string(),
"redirect_uri".to_string()
);
// Using custom version (format: vXX.X)
let config = Config::new_with_version(
"your_app_id".to_string(),
"redirect_uri".to_string(),
"v22.0".to_string()
);
// Client with custom version
let client = Client::new_with_version(
UserToken::default(),
"page_token".to_string(),
"v22.0".to_string()
);Note: Facebook guarantees each API version for at least 2 years. Always use the latest stable version when possible.
Build the Facebook OAuth login URL (can be done on frontend or backend):
use facebook_api_rs::prelude::{Config, LoginResponseType, LoginUrlParameters};
```rust
use facebook_api_rs::prelude::{Config, LoginResponseType, LoginUrlParameters};
fn build_login_url() -> String {
let config = Config::new(
"YOUR_APP_ID".to_string(),
"https://yourapp.com/callback".to_string()
);
// Use TOKEN response type to get access token directly
let response_type = LoginResponseType::TOKEN;
// Or use CODE to exchange for token on server
// let response_type = LoginResponseType::CODE;
LoginUrlParameters::new(config)
.add_response_type(response_type)
.add_scope(vec!["email", "public_profile", "pages_manage_posts"])
.full_login_url()
}After successful login, extract tokens or handle errors:
use facebook_api_rs::prelude::{Client, Me, TokenLiveType, UserToken};
async fn handle_login_response(redirect_url: String) -> Result<(), Box<dyn std::error::Error>> {
let tokens = UserToken::extract_user_tokens(redirect_url);
// Check for login errors
if let Some(error) = tokens.login_error {
eprintln!("Login failed: {:?}", error);
return Err(Box::new(error));
}
// If using CODE response type, exchange it for access token
if !tokens.code.is_empty() {
// Send code to server for token exchange
println!("Authorization code: {}", tokens.code);
}
// If using TOKEN response type, verify the access token
if !tokens.access_token.is_empty() {
// Get user information
let client = Client::new(tokens.clone(), String::new());
let user: Me = client
.accounts(TokenLiveType::LONGLIVE)
.user()
.await?;
println!("User ID: {}", user.id);
println!("User Name: {}", user.name.unwrap_or_default());
}
Ok(())
}Verify access tokens or exchange authorization codes on your server:
use facebook_api_rs::prelude::{Config, UserToken};
// Verify an access token
async fn verify_access_token(
access_token: String,
user_id: String,
app_id: String
) -> Result<bool, Box<dyn std::error::Error>> {
// Use a valid app token or admin token for verification
let app_token = "YOUR_APP_TOKEN";
let token_info = UserToken::access_token_information(
app_token,
&access_token
).await?;
// Validate token properties
if !token_info.is_valid {
return Ok(false);
}
if token_info.app_id != app_id {
return Ok(false);
}
if token_info.user_id != user_id {
return Ok(false);
}
Ok(true)
}
// Exchange authorization code for access token
async fn exchange_code_for_token(
code: String
) -> Result<UserToken, Box<dyn std::error::Error>> {
let config = Config::new(
"YOUR_APP_ID".to_string(),
"https://yourapp.com/callback".to_string()
);
let token = UserToken::default()
.exchange_code_for_access_token_at_server(
code,
"YOUR_APP_SECRET".to_string(),
config
)
.await?;
Ok(token)
}Get user's pages and manage page content:
use facebook_api_rs::prelude::{Client, TokenLiveType};
async fn get_user_pages(user_token: UserToken) -> Result<(), Box<dyn std::error::Error>> {
let client = Client::new(user_token, String::new());
// Get all pages the user manages
let accounts = client
.accounts(TokenLiveType::LONGLIVE)
.get()
.await?;
for account in accounts.data {
println!("Page: {} (ID: {})", account.name, account.id);
println!("Access Token: {}", account.access_token);
println!("Category: {}", account.category);
}
Ok(())
}Create posts, upload photos, and publish videos:
use facebook_api_rs::prelude::{Client, TokenLiveType};
async fn publish_page_post(
user_token: UserToken,
page_token: String
) -> Result<(), Box<dyn std::error::Error>> {
let client = Client::new(user_token, page_token);
// Publish a text post
let result = client
.pages("PAGE_ID".to_string(), TokenLiveType::LONGLIVE)
.feed()
.publish_message("Hello from Rust! π¦".to_string())
.await?;
println!("Post ID: {}", result.id);
Ok(())
}Access Instagram business accounts and media:
use facebook_api_rs::prelude::{Client, TokenLiveType};
async fn get_instagram_media(
user_token: UserToken,
page_token: String
) -> Result<(), Box<dyn std::error::Error>> {
let client = Client::new(user_token, page_token);
// Get Instagram account media
let media = client
.instagram_account("INSTAGRAM_BUSINESS_ACCOUNT_ID".to_string())
.media()
.fields(vec!["id", "caption", "media_type", "media_url", "timestamp"])
.get()
.await?;
for item in media.data {
println!("Media ID: {}", item.id);
}
Ok(())
}This crate currently supports:
- β OAuth login flow with customizable scopes
- β Authorization code exchange
- β Access token verification
- β Short-lived and long-lived tokens
- β Token inspection and debugging
- β Get user profile information
- β List user's managed pages
- β Page access token management
- β Publish posts to pages
- β Upload photos to pages
- β Upload videos to pages
- β Page feed management
- β Search functionality
- β Instagram Business Account access
- β Media publishing and management
- β Hashtag search
- β Media insights
- β Batch API requests
- β Custom API version support
- β Error handling with typed errors
- OAuth login dialog and redirect URL handling
- Login response parsing
- Authorization code exchange for access tokens
- JSON response handling
- Access token inspection
- Token storage and login status tracking
- Canceled login handling
- Identity confirmation
- Permission checking
- Re-requesting declined permissions
- User logout functionality
- App uninstall detection
- User data deletion request handling
The crate uses strongly-typed errors through the ClientErr enum:
use facebook_api_rs::prelude::{Client, ClientErr};
async fn handle_api_errors() {
match some_api_call().await {
Ok(data) => println!("Success: {:?}", data),
Err(ClientErr::HttpError(e)) => eprintln!("HTTP error: {}", e),
Err(ClientErr::ParseError(e)) => eprintln!("Parse error: {}", e),
Err(e) => eprintln!("Other error: {:?}", e),
}
}Check out the examples directory for more detailed usage examples, including:
- Complete OAuth flow implementation
- Instagram integration
- Page management
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
# Clone the repository
git clone https://github.com/osain-az/facebook-api-rs.git
cd facebook-api-rs
# Run tests
cargo test
# Build documentation
cargo doc --open
# Run examples (requires Facebook App credentials)
cargo run --example seedThis project is licensed under the MIT License - see the LICENSE file for details.
- Facebook for Developers - Official API documentation
- Built with β€οΈ using Rust
- οΏ½ Repository
- π Issue Tracker
- π¬ Discussions
This crate is ready for publication to crates.io. When published, users will be able to install it with:
[dependencies]
facebook_api_rs = "0.1.0"To publish (for maintainers):
# Ensure all tests pass
cargo test
# Check the package
cargo package
# Publish to crates.io
cargo publishNote: This is an unofficial library and is not affiliated with Meta Platforms, Inc.