Job alerts
Build double-opt-in email alerts and signed-in alert management without mixing token models.
A
JCavuno supports two alert experiences. Anonymous email alerts use confirmation and HMAC manage tokens; signed-in candidates manage alerts under board.me.alerts. These tokens are not board-user sessions.
Prerequisites
board.context().features.jobAlertsistrue.- A consent checkbox that is not preselected.
- Routes for the confirmation and email-management links Cavuno sends.
- A server-owned candidate session for
board.me.alerts.
Subscribe and confirm an email
12345678910111213141516171819// src/data/job-alerts.tsimport { board } from '../lib/board';export async function subscribeToRemoteEngineering(email: string) {return board.jobAlerts.subscribe({email,consent: true,frequency: 'weekly',filters: {jobFunctions: ['engineering'],remoteOptions: ['remote'],},context: { source: 'jobs-search' },});}export function confirmJobAlert(token: string) {return board.jobAlerts.confirm({ token });}
The subscription result reports created or duplicate and whether confirmation is required. Confirmation always returns HTTP 200; branch on status, which can be confirmed, already_confirmed, expired, or not_found.
Build the email management page
123456789101112131415161718export async function loadAlertManagement(subscription: string,token: string,) {return board.jobAlerts.manage({ subscription, token });}export async function updateAlertPreference(input: {subscriptionId: string;preferenceId: string;token: string;frequency: 'weekly';}) {return board.jobAlerts.updatePreference({...input,filters: { remoteOptions: ['remote'] },});}
Preference updates are full replacements. Restate frequency and every filter the subscriber wants to keep.
Weekly is the only supported alert cadence. Do not render a daily selector or preserve a legacy daily value when replacing a preference.
Build signed-in alerts
1234567891011121314const options = {cache: 'no-store' as const,headers: { authorization: `Bearer ${accessToken}` },};const alert = await board.me.alerts.create({label: 'Remote engineering',frequency: 'weekly',jobFunctions: ['engineering'],remoteOptions: ['remote'],},options,);
Use the returned alert.id for retrieve, update, and remove calls.
Expected result
Anonymous subscribe and confirmation calls return explicit status objects for every normal branch. Signed-in creation returns an active alert that appears in board.me.alerts.list().
Verify the result
- The subscription form is absent when job alerts are disabled.
- New subscriptions cannot be created without explicit consent.
- Expired and unknown confirmation tokens get distinct messages.
- Anonymous manage URLs work without a board-user session.
- Signed-in alert responses never enter a shared cache.
Errors and edge cases
- Only job functions, place slugs, and remote options currently filter digest delivery. Seniority and salary values are stored but do not filter delivery.
- Resend can return
sent,not_found,already_confirmed,throttled, orsend_failed. - Manage tokens grant access to one subscription. Treat them as secrets and keep them out of analytics and logs.
- Do not exchange a manage token for a candidate session.
Production cautions
- Explain cadence and consent next to the subscription control.
- Use generic completion copy where revealing subscription existence would leak personal data.
- Preserve the complete current preference on replacement updates.
- Handle throttling without repeatedly calling resend.
Next, add signed-in communication with Messaging.