Files
speckle-server/packages/server/modules/emails/services/sending.ts
T
Kristaps Fabians Geikins bde148f286 chore(server): migrating fully to ESM (#5042)
* wip

* some extra fixes

* stuff kinda works?

* need to figure out mocks

* need to figure out mocks

* fix db listener

* gqlgen fix

* minor gqlgen watch adjustment

* lint fixes

* delete old codegen file

* converting migrations to ESM

* getModuleDIrectory

* vitest sort of works

* added back ts-vitest

* resolve gql double load

* fixing test timeout configs

* TSC lint fix

* fix automate tests

* moar debugging

* debugging

* more debugging

* codegen update

* server works

* yargs migrated

* chore(server): getting rid of global mocks for Server ESM (#5046)

* got rid of email mock

* got rid of comment mocks

* got rid of multi region mocks

* got rid of stripe mock

* admin override mock updated

* removed final mock

* fixing import.meta.resolve calls

* another import.meta.resolve fix

* added requested test

* nyc ESM fix

* removed unneeded deps + linting

* yarn lock forgot to commit

* tryna fix flakyness

* email capture util fix

* sendEmail fix

* fix TSX check

* sender transporter fix + CR comments

* merge main fix

* test fixx

* circleci fix

* gqlgen bigint fix

* error formatter fix

* more error formatting improvements

* esmloader added to Dockerfile

* more dockerfile fixes

* bg jobs fix
2025-07-14 10:26:19 +03:00

78 lines
2.0 KiB
TypeScript

import { emailLogger } from '@/observability/logging'
import { SendEmail, SendEmailParams } from '@/modules/emails/domain/operations'
import { getTransporter } from '@/modules/emails/utils/transporter'
import { getEmailFromAddress } from '@/modules/shared/helpers/envHelper'
import { resolveMixpanelUserId } from '@speckle/shared'
import {
getRequestLogger,
loggerWithMaybeContext
} from '@/observability/utils/requestContext'
import type Mail from 'nodemailer/lib/mailer'
import { getEventBus } from '@/modules/shared/services/eventBus'
import { EmailsEvents } from '@/modules/emails/domain/events'
/**
* Send out an e-mail
*/
export const sendEmail: SendEmail = async ({
from,
to,
subject,
text,
html
}: SendEmailParams): Promise<boolean> => {
const eventBus = getEventBus()
const logger = getRequestLogger() || loggerWithMaybeContext({ logger: emailLogger })
try {
const baseOptions = {
to,
subject,
text,
html
}
await eventBus.emit({
eventName: EmailsEvents.PreparingToSend,
payload: { options: baseOptions }
})
const transporter = getTransporter()
if (!transporter) {
logger.warn('No email transport present. Cannot send emails. Skipping send...')
return false
}
const emailFrom = getEmailFromAddress()
const options: Mail.Options = {
...baseOptions,
from: from || `"Speckle" <${emailFrom}>`
}
await transporter.sendMail(options)
await eventBus.emit({
eventName: EmailsEvents.Sent,
payload: { options }
})
const emails = typeof to === 'string' ? [to] : to
const distinctIds = await Promise.all(
emails.map((email) => resolveMixpanelUserId(email))
)
logger.info(
{
subject,
distinctIds
},
'Email "{subject}" sent out to distinctIds {distinctIds}'
)
return true
} catch (error) {
logger.error(error)
}
return false
}
export type { SendEmailParams } from '@/modules/emails/domain/operations'