Skip to content

Notifications

Overview

The Notification service provides real-time WebSocket connections for receiving notifications about events in your workspace. Get instant updates about data changes, function executions, and system events.

WebSocket Connection

Connection URL

Connect to the WebSocket server with your user ID and workspace:

// WebSocket URL format
ws://notification.centrali.io:8085?userId=YOUR_USER_ID&workspaceSlug=YOUR_WORKSPACE

Native WebSocket (JavaScript)

// Create WebSocket connection
const userId = 'user_abc123';
const workspaceSlug = 'my-workspace';
const ws = new WebSocket(`ws://notification.centrali.io:8085?userId=${userId}&workspaceSlug=${workspaceSlug}`);

// Connection opened
ws.onopen = (event) => {
  console.log('Connected to notifications');
};

// Listen for messages
ws.onmessage = (event) => {
  const notification = JSON.parse(event.data);
  console.log('Received notification:', notification);

  // Notification structure:
  // {
  //   id: 'notif_123',
  //   title: 'New Order',
  //   message: 'Order #12345 has been placed',
  //   type: 'info',
  //   read: false
  // }
};

// Connection closed
ws.onclose = (event) => {
  console.log('Disconnected from notifications', event.code, event.reason);
};

// Handle errors
ws.onerror = (error) => {
  console.error('WebSocket error:', error);
};

Using with a WebSocket Library

// Using the 'ws' library in Node.js
import WebSocket from 'ws';

const userId = 'user_abc123';
const workspaceSlug = 'my-workspace';

const ws = new WebSocket(`ws://notification.centrali.io:8085?userId=${userId}&workspaceSlug=${workspaceSlug}`);

ws.on('open', () => {
  console.log('Connected to Centrali notifications');
});

ws.on('message', (data) => {
  const notification = JSON.parse(data.toString());
  console.log('Notification:', notification);
  handleNotification(notification);
});

ws.on('close', (code, reason) => {
  console.log(`Connection closed: ${code} - ${reason}`);
  // Implement reconnection logic if needed
});

ws.on('error', (error) => {
  console.error('WebSocket error:', error);
});

function handleNotification(notification) {
  switch(notification.type) {
    case 'record_created':
      console.log('New record created');
      break;
    case 'function_complete':
      console.log('Function execution complete');
      break;
    case 'alert':
      console.log('Alert:', notification.message);
      break;
    default:
      console.log('Notification:', notification.message);
  }
}

React Example

import { useEffect, useState } from 'react';

function useNotifications(userId, workspaceSlug) {
  const [notifications, setNotifications] = useState([]);
  const [connected, setConnected] = useState(false);

  useEffect(() => {
    if (!userId || !workspaceSlug) return;

    const ws = new WebSocket(`ws://notification.centrali.io:8085?userId=${userId}&workspaceSlug=${workspaceSlug}`);

    ws.onopen = () => {
      setConnected(true);
      console.log('Connected to notifications');
    };

    ws.onmessage = (event) => {
      const notification = JSON.parse(event.data);
      setNotifications(prev => [notification, ...prev]);
    };

    ws.onclose = () => {
      setConnected(false);
      console.log('Disconnected from notifications');
    };

    ws.onerror = (error) => {
      console.error('WebSocket error:', error);
    };

    // Cleanup on unmount
    return () => {
      ws.close();
    };
  }, [userId, workspaceSlug]);

  return { notifications, connected };
}

// Usage in component
function NotificationPanel() {
  const { notifications, connected } = useNotifications('user_123', 'my-workspace');

  return (
    <div>
      <div>Status: {connected ? 'Connected' : 'Disconnected'}</div>
      {notifications.map(notif => (
        <div key={notif.id}>
          <h3>{notif.title}</h3>
          <p>{notif.message}</p>
        </div>
      ))}
    </div>
  );
}

Notification Structure

Each notification message contains:

interface Notification {
  id: string;           // Unique notification ID
  title: string;        // Notification title
  message: string;      // Detailed message
  type: string;         // Type: 'info', 'success', 'warning', 'error', 'alert'
  read: boolean;        // Read status
  timestamp?: string;   // When the notification was created
  metadata?: any;       // Additional data specific to the notification type
}

Notification Types

System Notifications

  • Workspace events
  • User account updates
  • System maintenance alerts

Data Notifications

  • Record created
  • Record updated
  • Record deleted
  • Bulk operation completed

Function Notifications

  • Function execution started
  • Function execution completed
  • Function execution failed
  • Function timeout

Custom Notifications

  • Triggered from compute functions
  • Application-specific events

Sending Notifications from Functions

While WebSocket connections are for receiving notifications, you can trigger notifications from compute functions:

exports.handler = async (event, context) => {
  const { centrali } = context.apis;

  // Process something
  const result = await processOrder(event.data);

  // Trigger a notification that will be sent via WebSocket
  await centrali.notifications.send({
    userId: event.data.userId,
    title: 'Order Processed',
    message: `Your order ${result.orderId} has been processed successfully`,
    type: 'success',
    metadata: {
      orderId: result.orderId,
      total: result.total
    }
  });

  return { success: true, data: result };
};

Connection Management

Authentication

The WebSocket connection requires: - userId: Your user ID in Centrali - workspaceSlug: The workspace you want to receive notifications for

Both parameters must be provided as query parameters in the connection URL.

Reconnection Strategy

class NotificationManager {
  constructor(userId, workspaceSlug) {
    this.userId = userId;
    this.workspaceSlug = workspaceSlug;
    this.ws = null;
    this.reconnectAttempts = 0;
    this.maxReconnectAttempts = 5;
    this.reconnectDelay = 1000; // Start with 1 second
  }

  connect() {
    const url = `ws://notification.centrali.io:8085?userId=${this.userId}&workspaceSlug=${this.workspaceSlug}`;
    this.ws = new WebSocket(url);

    this.ws.onopen = () => {
      console.log('Connected to notifications');
      this.reconnectAttempts = 0;
      this.reconnectDelay = 1000;
    };

    this.ws.onmessage = (event) => {
      const notification = JSON.parse(event.data);
      this.handleNotification(notification);
    };

    this.ws.onclose = (event) => {
      console.log('Connection closed', event.code);
      this.attemptReconnect();
    };

    this.ws.onerror = (error) => {
      console.error('WebSocket error:', error);
    };
  }

  attemptReconnect() {
    if (this.reconnectAttempts >= this.maxReconnectAttempts) {
      console.error('Max reconnection attempts reached');
      return;
    }

    this.reconnectAttempts++;
    console.log(`Reconnecting... Attempt ${this.reconnectAttempts}`);

    setTimeout(() => {
      this.connect();
    }, this.reconnectDelay);

    // Exponential backoff
    this.reconnectDelay = Math.min(this.reconnectDelay * 2, 30000); // Max 30 seconds
  }

  handleNotification(notification) {
    // Your notification handling logic
    console.log('Notification received:', notification);
  }

  disconnect() {
    if (this.ws) {
      this.ws.close();
    }
  }
}

// Usage
const notificationManager = new NotificationManager('user_123', 'my-workspace');
notificationManager.connect();

Best Practices

1. Connection Lifecycle

  • Open connection when user logs in or enters workspace
  • Close connection when user logs out or leaves
  • Implement reconnection logic for network interruptions

2. Error Handling

  • Always handle connection errors gracefully
  • Provide user feedback when connection is lost
  • Queue important actions during disconnection

3. Performance

  • Avoid keeping connections open when not needed
  • Use a single connection per user/workspace pair
  • Process notifications efficiently to avoid blocking

4. Security

  • Never expose sensitive data in notifications
  • Validate userId and workspaceSlug on the server
  • Use WSS (WebSocket Secure) in production environments

Limitations

  • Maximum 1 connection per user per workspace
  • Messages are not persisted - only real-time delivery
  • Connection timeout after 5 minutes of inactivity
  • Maximum message size: 64KB

Troubleshooting

Connection Fails

  • Verify userId and workspaceSlug are correct
  • Check network connectivity to port 8085
  • Ensure user has access to the workspace

Not Receiving Notifications

  • Confirm connection is established (check onopen)
  • Verify notification events are being triggered
  • Check browser console for errors

Connection Drops Frequently

  • Implement reconnection logic
  • Check for network stability
  • Consider using heartbeat/ping messages