Life Butler - SuperApp

← The Butler Developers

A stylized icon depicting a butler's face with a monocle, mustache, and bow tie
CORE

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 Butler
  • entity.updated - Entity updated in any Butler
  • entity.deleted - Entity deleted in any Butler
  • transaction.created - Transaction created
  • contact.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.