import { announcementMessage, DiscordClient, DiscordDeliveryError, } from "./discord-client"; import type { DiscordAnnouncement } from "../shared/discord"; type Source = Parameters[3]; export async function deliverDiscordAnnouncement( job: DiscordAnnouncement, dependencies: { origin: string; channel: string; client: Pick; load: () => Promise; finish: (patch: Partial) => Promise; now?: () => number; }, ) { const { origin, channel, client, load, finish, now = Date.now, } = dependencies; const released = { lease_owner: null, lease_until: null }; try { const source = await load(); if (!source) { await finish({ ...released, state: "skipped", last_error: null }); return; } const messageId = await client.send( channel, announcementMessage(job.id, job.kind, origin, source), ); await finish({ ...released, state: "sent", channel_id: channel, message_id: messageId, sent_at: new Date(now()).toISOString(), last_error: null, }); } catch (failure) { const error = failure instanceof DiscordDeliveryError ? failure : new DiscordDeliveryError( "Discord delivery could not be confirmed. Delivery will retry.", ); await finish({ ...released, state: error.permanent || job.attempts >= 8 ? "failed" : "pending", last_error: error.message, next_attempt_at: new Date( now() + Math.max( error.retryAfter, Math.min(3600, 30 * 2 ** (job.attempts - 1)), ) * 1000, ).toISOString(), }); } }