Event Pipeline
How to integrate your Butler with The Butler's event pipeline. A central event bus for cross-Butler updates enables automation and consistent state without tight coupling.
Overview
The Butler provides a central event bus for cross-Butler updates. When one Butler changes data (e.g., new expense, new reminder), others can subscribe and react—enabling automation and consistent state without tight coupling. This allows Butlers to work together seamlessly without direct dependencies.
Subscribe to Events
Subscribe to events published by other Butlers or The Butler itself.
Basic Event Subscription
// Subscribe to events
const unsubscribe = await window.lifeButler.events.subscribe('transaction.created', (event) => {
const { transaction, butlerId } = event;
// Handle new transaction
if (transaction.category === 'groceries') {
updateGroceryBudget(transaction.amount);
}
});
// Subscribe with filters
const unsubscribe = await window.lifeButler.events.subscribe('transaction.created', (event) => {
// Handle event
}, {
filter: (event) => event.transaction.category === 'groceries'
});Subscribe to Multiple Events
// Subscribe to multiple event types
const unsubscribe = await window.lifeButler.events.subscribeMany([
'transaction.created',
'transaction.updated',
'transaction.deleted'
], (event) => {
// Handle any of these events
refreshExpenseList();
});
// Unsubscribe when done
unsubscribe();Publish Events
Publish events when your Butler performs actions or changes data. Other Butlers can subscribe to these events.
Publish Event
// Publish event
await window.lifeButler.events.publish('expense.created', {
expenseId: 'exp-123',
amount: 25.50,
category: 'groceries',
date: '2024-01-15',
butlerId: 'my-butler'
});
// Publish with metadata
await window.lifeButler.events.publish('expense.created', {
expenseId: 'exp-123',
amount: 25.50,
category: 'groceries',
date: '2024-01-15',
butlerId: 'my-butler',
metadata: {
source: 'manual-entry',
linkedContactId: 'contact-123'
}
});Event Types
Common event types used across the platform. Your Butler can publish custom events or subscribe to platform events.
Data Events
entity.created- Entity created in any Butlerentity.updated- Entity updated in any Butlerentity.deleted- Entity deleted in any Butlertransaction.created- Transaction createdcontact.created- Contact created
Custom Events
Your Butler can publish custom events with any event type. Use namespaced event types (e.g., my-butler.expense.processed) to avoid conflicts.
Event-Driven Automation
Use events to enable automation workflows that span multiple Butlers.
// Example: When expense is created, update budget
window.lifeButler.events.subscribe('transaction.created', async (event) => {
const { transaction } = event;
if (transaction.category === 'groceries') {
// Update grocery budget
const budget = await window.lifeButler.data.get('Budget', 'grocery-budget');
const updated = await window.lifeButler.data.update('Budget', budget.id, {
spent: budget.spent + transaction.amount
});
// Publish budget update event
await window.lifeButler.events.publish('budget.updated', {
budgetId: budget.id,
category: 'groceries',
spent: updated.spent
});
}
});
// Example: When contact is created, link to expenses
window.lifeButler.events.subscribe('contact.created', async (event) => {
const { contact } = event;
// Find related expenses
const expenses = await window.lifeButler.data.query('Transaction', {
where: { merchant: contact.name }
});
// Link expenses to contact
for (const expense of expenses) {
await window.lifeButler.data.link('Transaction', expense.id, 'Contact', contact.id);
}
});Requirements
- Publish events: Publish events when your Butler performs actions or changes data that other Butlers might care about.
- Subscribe to events: Subscribe to events from other Butlers to enable cross-Butler workflows.
- Use namespaced events: Use namespaced event types (e.g.,
my-butler.event-name) for custom events to avoid conflicts. - Clean up subscriptions: Unsubscribe from events when your Butler unmounts or no longer needs the subscription.
- Handle errors: Handle errors in event handlers gracefully to prevent breaking other Butlers.