feat: Notification Email Templates (#13940)

This commit is contained in:
Tim Van Onckelen
2024-12-04 21:26:02 +01:00
committed by GitHub
parent 4bf1b84cc2
commit 292182fa7f
32 changed files with 1136 additions and 105 deletions

View File

@@ -140,7 +140,7 @@ export class NotificationService extends BaseService {
setTimeout(() => this.eventRepository.clientSend('on_session_delete', sessionId, sessionId), 500);
}
async sendTestEmail(id: string, dto: SystemConfigSmtpDto) {
async sendTestEmail(id: string, dto: SystemConfigSmtpDto, tempTemplate?: string) {
const user = await this.userRepository.get(id, { withDeleted: false });
if (!user) {
throw new Error('User not found');
@@ -160,8 +160,8 @@ export class NotificationService extends BaseService {
baseUrl: getExternalDomain(server, port),
displayName: user.name,
},
customTemplate: tempTemplate!,
});
const { messageId } = await this.notificationRepository.sendEmail({
to: user.email,
subject: 'Test email from Immich',
@@ -175,6 +175,69 @@ export class NotificationService extends BaseService {
return { messageId };
}
async getTemplate(name: EmailTemplate, customTemplate: string) {
const { server, templates } = await this.getConfig({ withCache: false });
const { port } = this.configRepository.getEnv();
let templateResponse = '';
switch (name) {
case EmailTemplate.WELCOME: {
const { html: _welcomeHtml } = await this.notificationRepository.renderEmail({
template: EmailTemplate.WELCOME,
data: {
baseUrl: getExternalDomain(server, port),
displayName: 'John Doe',
username: 'john@doe.com',
password: 'thisIsAPassword123',
},
customTemplate: customTemplate || templates.email.welcomeTemplate,
});
templateResponse = _welcomeHtml;
break;
}
case EmailTemplate.ALBUM_UPDATE: {
const { html: _updateAlbumHtml } = await this.notificationRepository.renderEmail({
template: EmailTemplate.ALBUM_UPDATE,
data: {
baseUrl: getExternalDomain(server, port),
albumId: '1',
albumName: 'Favorite Photos',
recipientName: 'Jane Doe',
cid: undefined,
},
customTemplate: customTemplate || templates.email.albumInviteTemplate,
});
templateResponse = _updateAlbumHtml;
break;
}
case EmailTemplate.ALBUM_INVITE: {
const { html } = await this.notificationRepository.renderEmail({
template: EmailTemplate.ALBUM_INVITE,
data: {
baseUrl: getExternalDomain(server, port),
albumId: '1',
albumName: "John Doe's Favorites",
senderName: 'John Doe',
recipientName: 'Jane Doe',
cid: undefined,
},
customTemplate: customTemplate || templates.email.albumInviteTemplate,
});
templateResponse = html;
break;
}
default: {
templateResponse = '';
break;
}
}
return { name, html: templateResponse };
}
@OnJob({ name: JobName.NOTIFY_SIGNUP, queue: QueueName.NOTIFICATION })
async handleUserSignup({ id, tempPassword }: JobOf<JobName.NOTIFY_SIGNUP>) {
const user = await this.userRepository.get(id, { withDeleted: false });
@@ -182,7 +245,7 @@ export class NotificationService extends BaseService {
return JobStatus.SKIPPED;
}
const { server } = await this.getConfig({ withCache: true });
const { server, templates } = await this.getConfig({ withCache: true });
const { port } = this.configRepository.getEnv();
const { html, text } = await this.notificationRepository.renderEmail({
template: EmailTemplate.WELCOME,
@@ -192,6 +255,7 @@ export class NotificationService extends BaseService {
username: user.email,
password: tempPassword,
},
customTemplate: templates.email.welcomeTemplate,
});
await this.jobRepository.queue({
@@ -227,7 +291,7 @@ export class NotificationService extends BaseService {
const attachment = await this.getAlbumThumbnailAttachment(album);
const { server } = await this.getConfig({ withCache: false });
const { server, templates } = await this.getConfig({ withCache: false });
const { port } = this.configRepository.getEnv();
const { html, text } = await this.notificationRepository.renderEmail({
template: EmailTemplate.ALBUM_INVITE,
@@ -239,6 +303,7 @@ export class NotificationService extends BaseService {
recipientName: recipient.name,
cid: attachment ? attachment.cid : undefined,
},
customTemplate: templates.email.albumInviteTemplate,
});
await this.jobRepository.queue({
@@ -273,7 +338,7 @@ export class NotificationService extends BaseService {
);
const attachment = await this.getAlbumThumbnailAttachment(album);
const { server } = await this.getConfig({ withCache: false });
const { server, templates } = await this.getConfig({ withCache: false });
const { port } = this.configRepository.getEnv();
for (const recipient of recipients) {
@@ -297,6 +362,7 @@ export class NotificationService extends BaseService {
recipientName: recipient.name,
cid: attachment ? attachment.cid : undefined,
},
customTemplate: templates.email.albumUpdateTemplate,
});
await this.jobRepository.queue({

View File

@@ -190,6 +190,13 @@ const updatedConfig = Object.freeze<SystemConfig>({
},
},
},
templates: {
email: {
albumInviteTemplate: '',
welcomeTemplate: '',
albumUpdateTemplate: '',
},
},
});
describe(SystemConfigService.name, () => {