import type { CapabilityProvider, CapabilityRequest, ProviderResult } from '@insignia/iios-contracts'; interface EmailPayload { subject?: string; text?: string; html?: string; inReplyTo?: string; } /** * Email egress provider: shapes the outbound command into an email envelope * ({to, subject, text, html, inReplyTo}) and POSTs it to a configured send endpoint * (a vendor mail API / SMTP relay behind a URL). Activated only when * IIOS_PROVIDER_URL_EMAIL is set; a transport failure is surfaced as FAILED, never thrown. */ export class EmailProvider implements CapabilityProvider { readonly name = 'email-http'; readonly channelTypes = ['EMAIL']; readonly capabilities = { canSend: true }; constructor(private readonly url: string) {} async send(req: CapabilityRequest): Promise { const started = Date.now(); const p = (req.payload ?? {}) as EmailPayload; const email = { to: req.target, subject: p.subject ?? '(no subject)', text: p.text, html: p.html, inReplyTo: p.inReplyTo }; try { const res = await fetch(this.url, { method: 'POST', headers: { 'content-type': 'application/json', 'idempotency-key': req.idempotencyKey }, body: JSON.stringify(email), }); const latencyMs = Date.now() - started; if (!res.ok) return { providerRef: `email-${res.status}`, outcome: 'FAILED', errorCode: `HTTP_${res.status}`, latencyMs }; return { providerRef: `email-${req.idempotencyKey}`, outcome: 'SENT', latencyMs }; } catch (err) { return { providerRef: 'email-error', outcome: 'FAILED', errorCode: (err as Error).message.slice(0, 60), latencyMs: Date.now() - started }; } } }