import { GetServerInfo } from '@/modules/core/domain/server/operations' import { FindEmailsByUserId } from '@/modules/core/domain/userEmails/operations' import { EmailTemplateParams, RenderEmail, SendEmail, SendEmailParams } from '@/modules/emails/domain/operations' import { getServerOrigin } from '@/modules/shared/helpers/envHelper' import { mixpanel } from '@/modules/shared/utils/mixpanel' import { GetWorkspaceCollaborators } from '@/modules/workspaces/domain/operations' import { WorkspaceTeamMember } from '@/modules/workspaces/domain/types' import { Workspace } from '@/modules/workspacesCore/domain/types' import { Roles } from '@speckle/shared' type TrialExpiresArgs = { workspace: Workspace expiresInDays: number } type TrialExpiresArgsWithAdmin = TrialExpiresArgs & { workspaceAdmin: WorkspaceTeamMember } const buildMjmlBody = ({ workspace, expiresInDays, workspaceAdmin }: TrialExpiresArgsWithAdmin) => { const expireMessage = expiresInDays === 0 ? `today` : `in ${expiresInDays} days` const bodyStart = ` Hi ${workspaceAdmin.name}!

The trial for your workspace ${workspace.name} expires ${expireMessage}.

Upgrade to a paid plan before the trial expires to keep using your workspace. You can compare plans and get an overview of your estimated billing from your workspace's billing settings.

` const bodyEnd = ` Have questions or feedback? Please write us at hello@speckle.systems and we'd be more than happy to talk. ` return { bodyStart, bodyEnd } } const buildTextBody = ({ workspace, expiresInDays, workspaceAdmin }: TrialExpiresArgsWithAdmin) => { const expireMessage = expiresInDays === 0 ? `today` : `in ${expiresInDays} days` const bodyStart = ` Hi ${workspaceAdmin.name}! \r\n\r\n The trial for your workspace ${workspace.name} expires ${expireMessage}. \r\n\r\n Upgrade to a paid plan before the trial expires to keep using your workspace. You can compare plans and get an overview of your estimated billing from your workspace's billing settings. \r\n\r\n ` const bodyEnd = `Have questions or feedback? Please write us at hello@speckle.systems and we'd be more than happy to talk.` return { bodyStart, bodyEnd } } const buildEmailTemplateParams = ( args: TrialExpiresArgsWithAdmin ): EmailTemplateParams => { const url = new URL(`workspaces/${args.workspace.slug}`, getServerOrigin()).toString() return { mjml: buildMjmlBody(args), text: buildTextBody(args), cta: { title: 'Upgrade your workspace', url } } } export const sendWorkspaceTrialExpiresEmailFactory = ({ renderEmail, sendEmail, getServerInfo, getWorkspaceCollaborators, getUserEmails }: { renderEmail: RenderEmail sendEmail: SendEmail getServerInfo: GetServerInfo getWorkspaceCollaborators: GetWorkspaceCollaborators getUserEmails: FindEmailsByUserId }) => async (args: TrialExpiresArgs) => { const mp = mixpanel({ userEmail: undefined, req: undefined }) const [serverInfo, workspaceAdmins] = await Promise.all([ getServerInfo(), getWorkspaceCollaborators({ workspaceId: args.workspace.id, limit: 100, filter: { roles: [Roles.Workspace.Admin] } }) ]) const sendEmailParams = await Promise.all( workspaceAdmins.map(async (admin) => { const userEmails = await getUserEmails({ userId: admin.id }) const emailTemplateParams = buildEmailTemplateParams({ ...args, workspaceAdmin: admin }) const { html, text } = await renderEmail(emailTemplateParams, serverInfo, null) const subject = args.expiresInDays === 0 ? 'Your workspace trial expires today' : `Your workspace trial expires in ${args.expiresInDays} days` const sendEmailParams: SendEmailParams = { html, text, subject, to: userEmails.map((e) => e.email) } return sendEmailParams }) ) await Promise.all(sendEmailParams.map((params) => sendEmail(params))) await mp.track('Workspace Trial Expiration Email Sent', { workspaceId: args.workspace.id, // eslint-disable-next-line camelcase workspace_id: args.workspace.id, expiresInDays: args.expiresInDays }) }