89eaef495f
* debug tooltip now scrolls * Added a link to subscribe to alerts and improved the project alerts blank state * Better external link icon * Docs: Removed webhook tasks * Docs: removed limits performance * Docs: removed FAQs * Docs: Removed Architecture section * Docs: Removed API reference: CLI * Docs: Removed API reference: Objects * Docs: Removed API reference: Functions * Docs: removed automated tests * Docs: removed Middleware * Docs: removed Using APIs * Docs: removed Rollbacks * Docs: removed Trigger Filters * Docs: removed Webhook Tasks * Docs: removed Zod Tasks * Docs: Renamed Community page * Docs: Added a new Troubleshooting section and Alerts docs page * Hide the New Alerts button again if list is greater than 10 items * Customers now have to contact us for Slack Connect Support. * Fix the alerts docs link * Added env vars for a different alert email address, and whether the feature is enabled or not * Only show the alerts sidemenu item if the feature is enabled * Use a separate email client for sending alerts * Removed the link to Context from v3 docs * Removed obvious docs links that are now missing pages --------- Co-authored-by: Matt Aitken <matt@mattaitken.com>
85 lines
2.5 KiB
TypeScript
85 lines
2.5 KiB
TypeScript
import type { DeliverEmail, SendPlainTextOptions } from "emails";
|
|
import { EmailClient } from "emails";
|
|
import type { SendEmailOptions } from "remix-auth-email-link";
|
|
import { redirect } from "remix-typedjson";
|
|
import { env } from "~/env.server";
|
|
import type { User } from "~/models/user.server";
|
|
import type { AuthUser } from "./authUser";
|
|
import { workerQueue } from "./worker.server";
|
|
import { logger } from "./logger.server";
|
|
import { singleton } from "~/utils/singleton";
|
|
|
|
const client = singleton(
|
|
"email-client",
|
|
() =>
|
|
new EmailClient({
|
|
apikey: env.RESEND_API_KEY,
|
|
imagesBaseUrl: env.APP_ORIGIN,
|
|
from: env.FROM_EMAIL ?? "team@email.trigger.dev",
|
|
replyTo: env.REPLY_TO_EMAIL ?? "help@email.trigger.dev",
|
|
})
|
|
);
|
|
|
|
const alertsClient = singleton(
|
|
"alerts-email-client",
|
|
() =>
|
|
new EmailClient({
|
|
apikey: env.ALERT_RESEND_API_KEY,
|
|
imagesBaseUrl: env.APP_ORIGIN,
|
|
from: env.ALERT_FROM_EMAIL ?? "noreply@alerts.trigger.dev",
|
|
replyTo: env.REPLY_TO_EMAIL ?? "help@email.trigger.dev",
|
|
})
|
|
);
|
|
|
|
export async function sendMagicLinkEmail(options: SendEmailOptions<AuthUser>): Promise<void> {
|
|
// Auto redirect when in development mode
|
|
if (env.NODE_ENV === "development") {
|
|
throw redirect(options.magicLink);
|
|
}
|
|
|
|
logger.debug("Sending magic link email", { emailAddress: options.emailAddress });
|
|
|
|
try {
|
|
return await client.send({
|
|
email: "magic_link",
|
|
to: options.emailAddress,
|
|
magicLink: options.magicLink,
|
|
});
|
|
} catch (error) {
|
|
logger.error("Error sending magic link email", { error: JSON.stringify(error) });
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
export async function sendPlainTextEmail(options: SendPlainTextOptions) {
|
|
return client.sendPlainText(options);
|
|
}
|
|
|
|
export async function scheduleWelcomeEmail(user: User) {
|
|
//delay for one minute in development, longer in production
|
|
const delay = process.env.NODE_ENV === "development" ? 1000 * 60 : 1000 * 60 * 22;
|
|
|
|
await workerQueue.enqueue(
|
|
"scheduleEmail",
|
|
{
|
|
email: "welcome",
|
|
to: user.email,
|
|
name: user.name ?? undefined,
|
|
},
|
|
{ runAt: new Date(Date.now() + delay) }
|
|
);
|
|
}
|
|
|
|
export async function scheduleEmail(data: DeliverEmail, delay?: { seconds: number }) {
|
|
const runAt = delay ? new Date(Date.now() + delay.seconds * 1000) : undefined;
|
|
await workerQueue.enqueue("scheduleEmail", data, { runAt });
|
|
}
|
|
|
|
export async function sendEmail(data: DeliverEmail) {
|
|
return client.send(data);
|
|
}
|
|
|
|
export async function sendAlertEmail(data: DeliverEmail) {
|
|
return alertsClient.send(data);
|
|
}
|