use lago_client::LagoClient;
use lago_types::{
error::LagoError,
models::PaginationParams,
requests::event::{CreateEventInput, CreateEventRequest, GetEventRequest, ListEventsRequest},
};
use serde_json::json;
use std::time::{SystemTime, UNIX_EPOCH};
async fn create_or_get_event(
client: &LagoClient,
event_input: CreateEventInput,
) -> Result<String, Box<dyn std::error::Error>> {
let transaction_id = event_input.transaction_id.clone();
let request = CreateEventRequest::new(event_input);
match client.create_event(request).await {
Ok(response) => {
println!("Created event: {}", response.event.transaction_id);
Ok(response.event.transaction_id)
}
Err(LagoError::Api { status: 422, .. }) => {
println!("Event {} already exists, fetching it...", transaction_id);
let get_request = GetEventRequest::new(transaction_id.clone());
let event = client.get_event(get_request).await?;
println!(
"Retrieved existing event: transaction_id={}, code={}",
event.event.transaction_id, event.event.code
);
Ok(event.event.transaction_id)
}
Err(e) => Err(e.into()),
}
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = LagoClient::from_env()?;
let timestamp = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_secs() as i64;
let unique_id = timestamp;
println!("\n--- Example 1: Create event for customer ---");
let transaction_id_1 = format!("txn_customer_{}", unique_id);
let event_input = CreateEventInput::for_customer(
transaction_id_1.clone(),
"customer_123".to_string(),
"api_calls".to_string(),
)
.with_properties(json!({"calls": 150}))
.with_timestamp(timestamp);
create_or_get_event(&client, event_input).await?;
println!("\n--- Example 2: Create event for subscription ---");
let transaction_id_2 = format!("txn_subscription_{}", unique_id);
let subscription_event = CreateEventInput::for_subscription(
transaction_id_2,
"subscription_456".to_string(),
"storage_gb".to_string(),
)
.with_properties(json!({"gb": 50.5}));
create_or_get_event(&client, subscription_event).await?;
println!("\n--- Example 3: Create event with precise amount ---");
let transaction_id_3 = format!("txn_precise_{}", unique_id);
let precise_event = CreateEventInput::for_customer(
transaction_id_3,
"customer_789".to_string(),
"compute_hours".to_string(),
)
.with_precise_total_amount_cents(1234567);
create_or_get_event(&client, precise_event).await?;
println!("\n--- Example 4: Retrieve event by transaction ID ---");
let get_request = GetEventRequest::new(transaction_id_1);
match client.get_event(get_request).await {
Ok(event) => println!(
"Retrieved event: transaction_id={}, code={}, timestamp={}",
event.event.transaction_id, event.event.code, event.event.timestamp
),
Err(e) => println!("Failed to retrieve event: {}", e),
}
println!("\n--- Example 5: Idempotency test (same transaction_id) ---");
let idempotent_id = format!("txn_idempotent_{}", unique_id);
let first_event = CreateEventInput::for_customer(
idempotent_id.clone(),
"customer_123".to_string(),
"api_calls".to_string(),
)
.with_properties(json!({"calls": 100}));
create_or_get_event(&client, first_event).await?;
let second_event = CreateEventInput::for_customer(
idempotent_id,
"customer_123".to_string(),
"api_calls".to_string(),
)
.with_properties(json!({"calls": 200}));
create_or_get_event(&client, second_event).await?;
println!("\n--- Example 6: List all events ---");
match client.list_events(None).await {
Ok(response) => {
println!(
"Found {} events (page {} of {})",
response.events.len(),
response.meta.current_page,
response.meta.total_pages
);
for event in response.events.iter().take(5) {
println!(
" - transaction_id={}, code={}, timestamp={}",
event.transaction_id, event.code, event.timestamp
);
}
if response.events.len() > 5 {
println!(" ... and {} more events", response.events.len() - 5);
}
}
Err(e) => println!("Failed to list events: {}", e),
}
println!("\n--- Example 7: List events with filters ---");
let filter_request = ListEventsRequest::new()
.with_pagination(PaginationParams::new().with_page(1).with_per_page(10))
.with_code("api_calls".to_string());
match client.list_events(Some(filter_request)).await {
Ok(response) => {
println!(
"Found {} events with code 'api_calls' (total: {})",
response.events.len(),
response.meta.total_count
);
for event in &response.events {
println!(
" - transaction_id={}, timestamp={}",
event.transaction_id, event.timestamp
);
}
}
Err(e) => println!("Failed to list filtered events: {}", e),
}
println!("\n--- All examples completed successfully! ---");
Ok(())
}