Event Coordination

Event coordination allows you to send real-time messages between external systems and active browser instances. This is particularly useful for multi-factor authentication (MFA) where you need to inject authentication codes during browser automation.

Overview

The system provides two operations:

  • Signal Event: Send data to an event channel
  • Wait for Event: Listen for data on an event channel with timeout

Events are user-scoped and work across multiple browser instances.

API Endpoints

Signal an Event

POST https://api.anchorbrowser.io/api/v1/events/{eventName}

Wait for an Event

POST https://api.anchorbrowser.io/api/v1/events/{eventName}/wait

Both endpoints require anchor-api-key header and accept JSON payloads.

MFA Use Case

Handle MFA codes during automated login flows:

// In your browser automation script
async function handleMFAFlow() {
  await page.fill('#username', 'user@example.com');
  await page.fill('#password', 'password');
  await page.click('#login-button');
  
  // Wait for MFA code from external system
  const mfaEvent = await waitForEvent('mfa_code', 30000);
  
  if (mfaEvent?.data?.code) {
    await page.fill('#mfa-code', mfaEvent.data.code);
    await page.click('#verify-button');
  }
}
// In your external system (mobile app, webhook, etc.)
async function sendMFACode(code) {
  await signalEvent('mfa_code', { code });
}

Implementation

JavaScript Helper Functions

const apiKey = 'your-api-key';
const apiBase = 'https://api.anchorbrowser.io';

async function signalEvent(eventName, data) {
  const response = await fetch(`${apiBase}/api/v1/events/${eventName}`, {
    method: 'POST',
    headers: {
      'anchor-api-key': apiKey,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ data: data || {} }),
  });
  
  if (!response.ok) throw new Error(`Failed to signal event: ${response.status}`);
  return await response.json();
}

async function waitForEvent(eventName, timeoutMs = 60000) {
  const response = await fetch(`${apiBase}/api/v1/events/${eventName}/wait`, {
    method: 'POST',
    headers: {
      'anchor-api-key': apiKey,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ timeoutMs }),
  });

  if (response.status === 408) return null; // Timeout
  if (!response.ok) throw new Error(`Failed to wait for event: ${response.status}`);
  return await response.json();
}

Event Flow Patterns

Signal First, Wait Later (immediate consumption):

await signalEvent("data", { value: "preloaded" });
const data = await waitForEvent("data", 1000); // Short timeout

Wait First, Signal Later (typical MFA flow):

const waitPromise = waitForEvent("mfa_code", 60000);
// ... other operations ...
const mfaData = await waitPromise;

Best Practices

  • Use descriptive event names: mfa_code_login, mfa_code_transfer
  • Always set appropriate timeouts
  • Validate received event data
  • Handle timeout scenarios gracefully
const mfaEvent = await waitForEvent('mfa_code', 30000);
if (mfaEvent?.data?.code && /^\d{6}$/.test(mfaEvent.data.code)) {
  // Use validated MFA code
} else {
  throw new Error('Invalid or missing MFA code');
}