Enable Notifications

Use Gmail and Supabase edge functions to send notifications for guestbook events.

When notifications are enabled, emails are sent for:

EventRecipients
New email added/invited to admin allow-list ("Admin list")The new address, and existing admin list
Invited admin completes sign-in for the first timeThe new user, and existing admin list
Email removed from the admin allow-listThe removed address, and existing admin list
Comment submittedAdmin list
Admin edits or deletes a commentAdmin list
Guestbook settings savedAdmin list

Setting Up

Create Webhook Secret

Supabase Edge Functions check a shared secret instead of a user JSON Web Token (JWT).

We'll first generate a shared secret that will be used with our Supabase Database Webhooks.

  1. Use a secure password generator like Bitwarden's password generator:

    • Choose Password and not Passphrase.
    • Set the Characters length to 32 or longer.
    • Leave A–Z, a–z, and 0–9 on, and keep !@#$%^&* off so you can paste the value into npx supabase secrets set without quoting.
  2. Copy the generated password. Hang on to this — we'll need to store this as Supabase secret when we connect Google OAuth 2.0 to Supabase under NOTIFY_WEBHOOK_SECRET:

    NOTIFY_WEBHOOK_SECRET=<your-webhook-secret>
    

Create Gmail Google Cloud Project

As sending emails requires more sensitive scopes, which may delay the approval of your OAuth client if you intend to publish the OAuth client for the admin authentication to the general public, let's create a new project for notifications.

Log in to your Google Cloud console:

  1. Create a new Google Cloud project.

  2. Make sure to select the project you just created by clicking Select your project (or the name of the guestbook project, if that is what you have currently selected).

  3. In the left sidebar, click APIs & Services, then Library.

  4. Under Google Workspace, select Gmail API.

  5. Click Enable.

Create Supabase Access Token

From within Supabase:

  1. Click on your profile icon in the top right corner, then select Account.

  2. In the left sidebar, click Access Tokens.

  3. Click Generate new token:

    • Enter in a Name for the token.
    • Set the time the token Expires in.
  4. Scope the Resource access to Project, then under Select projects choose your guestbook project.

  5. Under Permissions, select Preset - Read only.

  6. Click Project, then under Project Settings, select Read.

  7. Click Application services:

    • Under Edge Functions, select Read-write.
    • Under Edge Function Secrets, select Read-write.
  8. Click Review access >.

  9. Click Create token.

  10. Copy the token to your clipboard. Hang on to this — we'll need to store this as Supabase secret in the next section under SUPABASE_ACCESS_TOKEN:

    SUPABASE_ACCESS_TOKEN=<sbp_your_access_token>
    

Customize Notification Templates

Sender name is hardcoded in supabase/functions/_shared/gmail.ts. Change the FROM_NAME to your desired name:

const FROM_NAME = "y2k Guestbook";

Configuring Supabase

Deploy Edge Functions

Let's deploy the edge functions in supabase/functions to Supabase that will handle your notifications. a. First, make sure that your .env.local file contains the correct NEXT_PUBLIC_SUPABASE_URL: https://<your-database-url>.supabase.co.

  1. From your project root, call:

    export SUPABASE_ACCESS_TOKEN=<sbp_your_access_token>
    npx y2k-guestbook deploy-notifs
    
  1. Set the following Supabase secrets:

    1. From within your Supabase project, click Edge Functions in the left sidebar.

    2. Select Secrets.

    3. Under add or replace secrets, add the following secrets:

      NameValue
      GMAIL_USERyou@gmail.com
      GMAIL_CLIENT_ID<your-client-id>.apps.googleusercontent.com
      GMAIL_CLIENT_SECRET<your-client-secret>
      GMAIL_REFRESH_TOKEN<your-refresh-token>
      SITE_URLhttps://<your-project-url>.vercel.app
      NOTIFY_WEBHOOK_SECRET<your-webhook-secret>
      FLAG_NOTIFfalse

Configure Database Webhooks

  1. Within your Supabase project for the guestbook, select Integrations from the left sidebar.

  2. From the Explore all landing page, select Database Webhooks.

  3. Click Install integration.

  4. Click Install integration again to confirm the installation.

  5. Select the Webhooks tab. For each hook in the following list:

    TableEvents
    public.admin_allowlistINSERT, DELETE
    public.commentsINSERT, UPDATE, DELETE
    public.guestbook_settingsUPDATE
    1. Click Create a new hook.

    2. Enter a Name, such as admin_added.

    3. Under Table, select the table you want to add a hook for (you'll need to repeat these steps for each table).

    4. Set Type of webhook to HTTP Request.

    5. Then set HTTP Request to:

      • Method: POST
      • URL: https://<your-database-url>.supabase.co/functions/v1/notify-admins
    6. Under HTTP Headers, click Add header and add the following headers:

      NameValue
      Content-Typeapplication/json
      x-notify-webhook-secretThe same string as NOTIFY_WEBHOOK_SECRET
    7. Click Create webhook.

Enable Notifications

Notifications are gated behind the Supabase FLAG_NOTIF flag. To enable notifications, set this flag to true in your Supabase project:

  1. From within your Supabase project, click Edge Functions in the left sidebar.

  2. Select Secrets.

  3. Under add or replace secrets, update FLAG_NOTIF to true.

Review Webhooks

In your Supabase project, you can review webhook responses by running the following query from the SQL Editor in the left sidebar.

-- Original POST body is not stored after the request is sent
-- Rows older than ~6 hours have null status_code / response
select
  c.relname as table_name,
  h.hook_name,
  r.status_code,
  left(r.content, 500) as response,
  r.timed_out,
  r.error_msg,
  split_part(encode(t.tgargs, 'escape'), '\000', 1) as url,
  split_part(encode(t.tgargs, 'escape'), '\000', 2) as method,
  h.created_at as triggered_at,
  r.created as responded_at,
  h.request_id
from supabase_functions.hooks as h
left join net._http_response as r
  on r.id = h.request_id
left join pg_class as c
  on c.oid = h.hook_table_id
left join pg_namespace as n
  on n.oid = c.relnamespace
left join pg_trigger as t
  on t.tgrelid = h.hook_table_id
 and t.tgname = h.hook_name
order by h.created_at desc
-- Limit to the last 50 responses
limit 50;

Publish Notifications Client

Log in to your Google Cloud console and select your project:

  1. In the left sidebar, click APIs & Services, then select OAuth consent screen.

  2. Click Branding and enter your:

    • App name — This will be displayed instead of your generic Supabase project URL.
    • User support email — This will be displayed in the "Contact us" link in the Google OAuth consent screen.
  3. Under App domain, enter:

    • Application home page — The URL of your guestbook application.

    • Application privacy policy link — The URL of your guestbook's privacy policy.

    • Application terms of service link — The URL of your guestbook's terms of service.

  4. Under Authorized domains, enter any Authorized domains # where you intend to serve your guestbook application.

  5. In Developer contact information, enter your contact email.

  6. Click Save.

What's Next

Add a hit counter and customize guestbook settings: