mailship/src/actions.ts

67 lines
1.7 KiB
TypeScript
Raw Normal View History

import { instrument } from 'succinct-async'
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}`
if (!sub.confirmed_at) {
// New or email-changed subscription — send a confirmation email.
await mailer.sendConfirm(sub)
} else {
// Already confirmed (e.g. frequency-only change) — reschedule the
// cron job so it uses the new cadence immediately.
worker.registerSubscription(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)
}
},
)