import { instrument } from 'succinct-async' import type { Subscription } from './alert.js' import { getCronExpression } from './alert.js' import * as mailer from './mailer.js' import * as worker from './worker/index.js' import * as db from './database.js' export class ActionError extends Error { toString() { return this.message } } export type RegisterSubscriptionParams = { pubkey: string email: string frequency: string } export const registerSubscription = instrument( 'actions.registerSubscription', async ({ pubkey, email, frequency }: RegisterSubscriptionParams) => { const sub = await db.insertSubscription(pubkey, email, frequency) const callback = `${process.env.BASE_URL}/notify/${sub.id}` // Only send a confirmation when the subscription is new, unconfirmed, or // its email address changed. An already-confirmed, unchanged subscription // (or one where only the frequency changed) skips it. if (!sub.confirmed_at) { await mailer.sendConfirm(sub) } return { key: sub.key, callback } }, ) export type ConfirmSubscriptionParams = { token: string } export const confirmSubscriptionAction = instrument( 'actions.confirmSubscription', async ({ token }: ConfirmSubscriptionParams) => { const sub = await db.confirmSubscription(token) if (!sub) { throw new ActionError('That confirmation code is invalid or has expired.') } worker.registerSubscription(sub) }, ) export type UnsubscribeParams = { token: string } export const unsubscribeAction = instrument( 'actions.unsubscribe', async ({ token }: UnsubscribeParams) => { const sub = await db.unsubscribeSubscription(token) if (sub) { worker.unregisterSubscription(sub) } }, )