How to create a Supabase Realtime API client

Viewed 7

I'm running Apache Answer on a DigitalOcean Droplet. I'm experimenting with running its database on Supabase Postgres. I have a DigitalOcean Function that makes an API update to Apache Answer whenever I call it manually, and it's working well.

Now I want that DigitalOcean Function to get called automatically whenever a new question is inserted into the Postgres database.

In answer to another question, you suggested the below approach. Can you help me get this setup and running step by step.

A. Using Supabase Realtime API

Supabase provides a Realtime feature that can listen to changes in your database. You can subscribe to new inserts and, once detected, trigger your DigitalOcean Function.

Steps:

  1. Set up Realtime:

    import { createClient } from '@supabase/supabase-js';
    
    const supabase = createClient('https://your-project-id.supabase.co', 'your-public-anon-key');
    
    const channel = supabase
      .channel('*')
      .on('postgres_changes', { event: 'INSERT', schema: 'public', table: 'questions' }, payload => {
        console.log(payload);
        // Call the DigitalOcean function with the new question payload
        fetch('https://faas-nyc1-2ef2e6cc.doserverless.co/api/v1/namespaces/fn-4debf4e9-6121-41dc-a674-9ba721490ff8/actions/answer/test-pg-chatgpt-4o?blocking=true&result=true', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
            'Authorization': `Basic ${process.env.DO_TOKEN}`,
          },
          body: JSON.stringify({ question_id: payload.new.id }),
        }).then(response => response.json())
          .then(data => console.log(data))
          .catch(error => console.error('Error:', error));
      })
      .subscribe();
    
  2. Deploy and Run:

    • Deploy this script on a serverless environment or a microservice framework to ensure it runs continuously.
    • Handle potential network interruptions and auto-reconnect to Supabase Realtime.
1 Answers

Sure! Setting up a Supabase Realtime API client to trigger a DigitalOcean Function when a new question is inserted into your Postgres database involves several steps. Here’s a detailed guide to help you through the process:

Prerequisites:

  1. Supabase Account and Project: You need a Supabase account and an active project.
  2. DigitalOcean Account: You need a DigitalOcean Function already set up.
  3. Node.js Environment: You'll be writing and running JavaScript code, so make sure Node.js is installed on your server or development environment.

Step-by-Step Setup:

Step 1: Set Up Supabase Realtime

  1. Create a Supabase Client
    First, you need to set up a Supabase client in your JavaScript code. You can use the @supabase/supabase-js library for this.

    Install Supabase Client:
    If not already installed, you can add it to your project with npm:

    npm install @supabase/supabase-js
    

    Initialize Supabase Client:

    import { createClient } from '@supabase/supabase-js';
    
    const supabaseUrl = 'https://your-project-id.supabase.co';
    const supabaseKey = 'your-public-anon-key';
    const supabase = createClient(supabaseUrl, supabaseKey);
    

    Replace your-project-id and your-public-anon-key with your actual Supabase project details.

  2. Subscribe to Database Changes
    Now that you have the Supabase client set up, you can subscribe to changes in your database. For your case, you need to listen to new INSERT events in the questions table.

    const channel = supabase
      .channel('*')
      .on('postgres_changes', { event: 'INSERT', schema: 'public', table: 'questions' }, async (payload) => {
        console.log('New question inserted:', payload);
    
        // Call the DigitalOcean function
        await fetch('https://faas-nyc1-2ef2e6cc.doserverless.co/api/v1/namespaces/fn-4debf4e9-6121-41dc-a674-9ba721490ff8/actions/answer/test-pg-chatgpt-4o?blocking=true&result=true', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
            'Authorization': `Basic ${process.env.DO_TOKEN}`,
          },
          body: JSON.stringify({ question_id: payload.new.id }),
        })
        .then(response => response.json())
        .then(data => console.log(data))
        .catch(error => console.error('Error calling DO Function:', error));
      })
      .subscribe();
    

    Ensure you replace the URL and token with your actual DigitalOcean Function details and authentication token.

Step 2: Deploy and Run the Script

You need to deploy the above script in an environment where it can run continuously. Here are a few options:

  1. Server (e.g., DigitalOcean Droplet)
    If you are using a server (like the existing DigitalOcean Droplet), you can use Node.js to run the script.

    • Create a new script file, e.g., realtime-listener.js:

      import { createClient } from '@supabase/supabase-js';
      
      const supabaseUrl = 'https://your-project-id.supabase.co';
      const supabaseKey = 'your-public-anon-key';
      const supabase = createClient(supabaseUrl, supabaseKey);
      
      const channel = supabase
        .channel('*')
        .on('postgres_changes', { event: 'INSERT', schema: 'public', table: 'questions' }, async (payload) => {
          console.log('New question inserted:', payload);
          await fetch('https://faas-nyc1-2ef2e6cc.doserverless.co/api/v1/namespaces/fn-4debf4e9-6121-41dc-a674-9ba721490ff8/actions/answer/test-pg-chatgpt-4o?blocking=true&result=true', {
            method: 'POST',
            headers: {
              'Content-Type': 'application/json',
              'Authorization': `Basic ${process.env.DO_TOKEN}`,
            },
            body: JSON.stringify({ question_id: payload.new.id }),
          })
          .then(response => response.json())
          .then(data => console.log(data))
          .catch(error => console.error('Error calling DO Function:', error));
        })
        .subscribe();
      
    • Run the script using Node.js:

      node realtime-listener.js
      
  2. Serverless Environment
    Alternatively, you can use a serverless function to run the script, such as Vercel or AWS Lambda. This typically involves packaging the script within a handler and deploying it to the service.

    Example using Vercel:

    • Create a new project.
    • Add your script in the /api directory.
    • Ensure the script exports a handler function.
    // /api/realtime-listener.js
    
    import { createClient } from '@supabase/supabase-js';
    
    const supabaseUrl = 'https://your-project-id.supabase.co';
    const supabaseKey = 'your-public-anon-key';
    const supabase = createClient(supabaseUrl, supabaseKey);
    
    export default async (req, res) => {
      const channel = supabase
        .channel('*')
        .on('postgres_changes', { event: 'INSERT', schema: 'public', table: 'questions' }, async (payload) => {
          console.log('New question inserted:', payload);
          await fetch('https://faas-nyc1-2ef2e6cc.doserverless.co/api/v1/namespaces/fn-4debf4e9-6121-41dc-a674-9ba721490ff8/actions/answer/test-pg-chatgpt-4o?blocking=true&result=true', {
            method: 'POST',
            headers: {
              'Content-Type': 'application/json',
              'Authorization': `Basic ${process.env.DO_TOKEN}`,
            },
            body: JSON.stringify({ question_id: payload.new.id }),
          })
          .then(response => response.json())
          .then(data => console.log(data))
          .catch(error => console.error('Error calling DO Function:', error));
        })
        .subscribe();
    
      // Optionally, send a response
      res.json({ message: 'Realtime listener set up' });
    }
    

After deploying the script in a suitable environment, ensure it runs continuously and handles potential network interruptions with the ability to auto-reconnect to the Supabase Realtime API.

Step 3: Additional Considerations

  • Environment Variables: Safely store your sensitive information (like API keys) in environment variables.
  • Error Handling: Proper error handling and logging mechanisms to track any issues that arise.
  • Auto-Reconnect: Implement logic to handle and reconnect for network interruptions. Supabase's client should handle this to some extent.

With these steps, you should be able to set up a Supabase Realtime client that listens for changes in your Postgres database and triggers a DigitalOcean Function upon new question inserts.