Add translation hooks to transactional emails (#11785)

* First pass

* fix: Missing translations

* fix: Missing translations

* welcome

* Apply suggestions from code review

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* translations

---------

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
Tom Moor
2026-03-20 23:28:51 -04:00
committed by GitHub
parent a0039b2a09
commit 5693618de4
36 changed files with 714 additions and 256 deletions
+3
View File
@@ -80,6 +80,7 @@ router.post(
// send email to users email address with a short-lived token and code
await new SigninEmail({
to: user.email,
language: user.language,
token,
teamUrl: team.url,
client,
@@ -171,6 +172,7 @@ const emailCallback = async (ctx: APIContext<T.EmailCallbackReq>) => {
if (user.isInvited) {
await new WelcomeEmail({
to: user.email,
language: user.language,
role: user.role,
teamUrl: user.team.url,
}).schedule();
@@ -179,6 +181,7 @@ const emailCallback = async (ctx: APIContext<T.EmailCallbackReq>) => {
if (inviter?.subscribedToEventType(NotificationEventType.InviteAccepted)) {
await new InviteAcceptedEmail({
to: inviter.email,
language: inviter.language,
inviterId: inviter.id,
invitedName: user.name,
teamUrl: user.team.url,
@@ -29,29 +29,31 @@ export class PasskeyCreatedEmail extends BaseEmail<InputProps> {
}
protected subject() {
return `New passkey added to your ${env.APP_NAME} account`;
return this.t("New passkey added to your {{ appName }} account", {
appName: env.APP_NAME,
});
}
protected preview() {
return "A new passkey was created for your account.";
return this.t("A new passkey was created for your account.");
}
protected renderAsText({ passkeyName, teamUrl }: Props) {
return `
New Passkey Created
${this.t("New Passkey Created")}
A new passkey has been added to your ${env.APP_NAME} account:
${this.t("A new passkey has been added to your {{ appName }} account", { appName: env.APP_NAME }) + ":"}
${passkeyName}
Passkeys provide a secure, passwordless way to sign in to your account. If you did not create this passkey, please review your account security settings immediately.
${this.t("Passkeys provide a secure, passwordless way to sign in to your account. If you did not create this passkey, please review your account security settings immediately.")}
You can manage your passkeys at any time:
${this.t("You can manage your passkeys at any time")}:
${teamUrl}/settings/passkeys
---
If you have any concerns about your account security, please contact a workspace admin.
${this.t("If you have any concerns about your account security, please contact a workspace admin.")}
`;
}
@@ -63,24 +65,30 @@ If you have any concerns about your account security, please contact a workspace
<Header />
<Body>
<Heading>New Passkey Created</Heading>
<p>A new passkey has been added to your {env.APP_NAME} account:</p>
<Heading>{this.t("New Passkey Created")}</Heading>
<p>
{this.t(
"A new passkey has been added to your {{ appName }} account",
{ appName: env.APP_NAME }
) + ":"}
</p>
<p>
<strong>{passkeyName}</strong>
</p>
<p>
Passkeys provide a secure, passwordless way to sign in to your
account. If you did not create this passkey, please review your
account security settings immediately.
{this.t(
"Passkeys provide a secure, passwordless way to sign in to your account. If you did not create this passkey, please review your account security settings immediately."
)}
</p>
<EmptySpace height={10} />
<p>
<Button href={securityUrl}>Manage Passkeys</Button>
<Button href={securityUrl}>{this.t("Manage Passkeys")}</Button>
</p>
<EmptySpace height={10} />
<p style={{ fontSize: "14px", color: "#666" }}>
If you have any concerns about your account security, please contact
a workspace admin.
{this.t(
"If you have any concerns about your account security, please contact a workspace admin."
)}
</p>
</Body>
@@ -19,6 +19,7 @@ export class PasskeyCreatedProcessor extends BaseProcessor {
await new PasskeyCreatedEmail({
to: user.email,
language: user.language,
userId: user.id,
passkeyId: userPasskey.id,
passkeyName: userPasskey.name,
@@ -886,6 +886,7 @@ export default class DeliverWebhookTask extends BaseTask<Props> {
if (createdBy && team) {
await new WebhookDisabledEmail({
to: createdBy.email,
language: createdBy.language,
teamUrl: team.url,
webhookName: subscription.name,
}).schedule();