From 20fd741e6c3c9a06ebce3f056f107d28e9cf50f8 Mon Sep 17 00:00:00 2001 From: Hugo SUBTIL <ext.sopra.husubtil@grandlyon.com> Date: Fri, 22 Jan 2021 18:04:31 +0100 Subject: [PATCH] feat: add email sending for outdated structures --- src/configuration/config.ts | 4 ++ .../mail-templates/structureOutdatedInfo.ejs | 6 ++ .../mail-templates/structureOutdatedInfo.json | 3 + src/structures/services/structures.service.ts | 64 ++++++++++++++++++- src/users/interfaces/user.interface.ts | 1 + src/users/schemas/user.schema.ts | 3 + 6 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 src/mailer/mail-templates/structureOutdatedInfo.ejs create mode 100644 src/mailer/mail-templates/structureOutdatedInfo.json diff --git a/src/configuration/config.ts b/src/configuration/config.ts index 00bbfff6d..c11b20a7b 100644 --- a/src/configuration/config.ts +++ b/src/configuration/config.ts @@ -29,5 +29,9 @@ export const config = { ejs: 'structureClaimValidation.ejs', json: 'structureClaimValidation.json', }, + structureOutdatedInfo: { + ejs: 'structureOutdatedInfo.ejs', + json: 'structureOutdatedInfo.json', + }, }, }; diff --git a/src/mailer/mail-templates/structureOutdatedInfo.ejs b/src/mailer/mail-templates/structureOutdatedInfo.ejs new file mode 100644 index 000000000..945129e78 --- /dev/null +++ b/src/mailer/mail-templates/structureOutdatedInfo.ejs @@ -0,0 +1,6 @@ +Bonjour<br /> +<br /> +La fiche de votre structure: <strong><%= name %></strong> n'a pas été mise a jour depuis 6mois. +<br /> +<br /> +Ce mail est un mail automatique. Merci de ne pas y répondre. diff --git a/src/mailer/mail-templates/structureOutdatedInfo.json b/src/mailer/mail-templates/structureOutdatedInfo.json new file mode 100644 index 000000000..1782ea483 --- /dev/null +++ b/src/mailer/mail-templates/structureOutdatedInfo.json @@ -0,0 +1,3 @@ +{ + "subject": "Votre fiche structure n'est plus a jour, Réseau des Acteurs de la Médiation Numérique de la Métropole de Lyon" +} diff --git a/src/structures/services/structures.service.ts b/src/structures/services/structures.service.ts index dde0166a7..57e672008 100644 --- a/src/structures/services/structures.service.ts +++ b/src/structures/services/structures.service.ts @@ -1,19 +1,23 @@ -import { HttpException, HttpService, Injectable, HttpStatus } from '@nestjs/common'; +import { HttpException, HttpService, Injectable, HttpStatus, Logger } from '@nestjs/common'; import { InjectModel } from '@nestjs/mongoose'; import { Types, Model } from 'mongoose'; import { Observable } from 'rxjs'; import { AxiosResponse } from 'axios'; import { Structure, StructureDocument } from '../schemas/structure.schema'; -import { Logger } from '@nestjs/common'; +import * as ejs from 'ejs'; import { structureDto } from '../dto/structure.dto'; import { UsersService } from '../../users/users.service'; import { User } from '../../users/schemas/user.schema'; +import { MailerService } from '../../mailer/mailer.service'; +import { Cron, CronExpression } from '@nestjs/schedule'; +import { DateTime } from 'luxon'; @Injectable() export class StructuresService { constructor( private readonly httpService: HttpService, private readonly userService: UsersService, + private readonly mailerService: MailerService, @InjectModel(Structure.name) private structureModel: Model<StructureDocument> ) {} @@ -201,4 +205,60 @@ export class StructuresService { Logger.log(`Request : ${req}`, 'StructureService - getCoord'); return this.httpService.get(encodeURI(req)); } + + @Cron(CronExpression.EVERY_DAY_AT_4AM) + public async checkOutdatedStructuresInfo(): Promise<void> { + const MONTH_OUTDATED = 2; + const structureList = await this.findAll(); + const local = DateTime.local().setZone('Europe/Paris'); + // Get outdated structures + const filteredList = structureList.filter((structure) => { + const updateDate = DateTime.fromFormat(structure.updatedAt.split(' GMT')[0], 'EEE MMM dd yyyy HH:mm:ss'); + const diff = local.diff(updateDate, ['months']); + if (diff.values.months > MONTH_OUTDATED) { + return true; + } + }); + // Get owners of outdated structures + const ownerList = await Promise.all( + filteredList.map(async (structure) => { + const owner = await this.userService.isStructureClaimed(structure._id.toString()); + if (owner) { + return { structure: structure, owner: owner }; + } + }) + ); + // Send email if possible and update user + ownerList + .filter((x) => x != undefined) + .forEach(async (data) => { + this.userService.findOne(data.owner.email).then((user) => { + // If mail is already sent, do not resend + if (user.structureOutdatedMailSent.includes(data.structure._id)) { + return; + } else { + this.sendOutdatedEmailToUser(data.owner.email, data.structure.structureName); + user.structureOutdatedMailSent.push(data.structure._id); + user.save(); + } + }); + }); + } + + /** + * Generate activation token and send it to user by email, in order to validate + * a new account. + * @param user User + */ + private async sendOutdatedEmailToUser(userEmail: string, structureName: string): Promise<any> { + const config = this.mailerService.config; + const ejsPath = this.mailerService.getTemplateLocation(config.templates.structureOutdatedInfo.ejs); + const jsonConfig = this.mailerService.loadJsonConfig(config.templates.structureOutdatedInfo.json); + + const html = await ejs.renderFile(ejsPath, { + config, + name: structureName, + }); + this.mailerService.send(userEmail, jsonConfig.subject, html); + } } diff --git a/src/users/interfaces/user.interface.ts b/src/users/interfaces/user.interface.ts index a348aacb0..9ca1767ff 100644 --- a/src/users/interfaces/user.interface.ts +++ b/src/users/interfaces/user.interface.ts @@ -15,4 +15,5 @@ export interface IUser extends Document { newEmail: string; structuresLink: string[]; pendingStructuresLink: string[]; + structureOutdatedMailSent: string[]; } diff --git a/src/users/schemas/user.schema.ts b/src/users/schemas/user.schema.ts index 15261937b..5accf9e7c 100644 --- a/src/users/schemas/user.schema.ts +++ b/src/users/schemas/user.schema.ts @@ -40,6 +40,9 @@ export class User { @Prop({ default: null }) pendingStructuresLink: string[]; + + @Prop({ default: null }) + structureOutdatedMailSent: string[]; } export const UserSchema = SchemaFactory.createForClass(User); -- GitLab