67 lines
1.8 KiB
TypeScript
67 lines
1.8 KiB
TypeScript
import Mailgun from 'mailgun.js'
|
|
import formData from 'form-data'
|
|
import type {
|
|
EmailService,
|
|
SendEmailInput,
|
|
SendEmailResult,
|
|
} from '@pikku/core/services'
|
|
|
|
const isProduction = process.env.NODE_ENV === 'production'
|
|
|
|
export class MailgunEmailService implements EmailService {
|
|
private readonly mg: ReturnType<Mailgun['client']> | undefined
|
|
|
|
constructor(
|
|
apiKey: string | undefined,
|
|
private readonly domain: string,
|
|
) {
|
|
if (apiKey) {
|
|
const mailgun = new Mailgun(formData)
|
|
this.mg = mailgun.client({
|
|
username: 'api',
|
|
key: apiKey,
|
|
url: 'https://api.eu.mailgun.net',
|
|
})
|
|
}
|
|
}
|
|
|
|
async send(input: SendEmailInput): Promise<SendEmailResult> {
|
|
if ('template' in input) {
|
|
throw new Error('MailgunEmailService expects rendered email content, not template references')
|
|
}
|
|
|
|
if (!isProduction || !this.mg) {
|
|
const recipients = normalizeRecipients(input.to)
|
|
console.log(
|
|
`Would have sent email to ${recipients.join(', ')} with subject "${input.subject || ''}"`
|
|
)
|
|
return {}
|
|
}
|
|
|
|
const result = await this.mg.messages.create('mail.hey-germany.com', {
|
|
from: input.from || `HeyGermany <info@${this.domain}>`,
|
|
to: normalizeRecipients(input.to),
|
|
cc: normalizeRecipients(input.cc),
|
|
bcc: normalizeRecipients(input.bcc),
|
|
subject: input.subject,
|
|
html: 'html' in input ? input.html : undefined,
|
|
text: 'text' in input ? input.text : undefined,
|
|
h: input.headers,
|
|
} as any)
|
|
|
|
return {
|
|
messageId: typeof result === 'object' && result && 'id' in result
|
|
? String(result.id)
|
|
: undefined,
|
|
}
|
|
}
|
|
}
|
|
|
|
const normalizeRecipients = (value?: string | string[]) => {
|
|
if (!value) {
|
|
return []
|
|
}
|
|
|
|
return Array.isArray(value) ? value : [value]
|
|
}
|