Skip to content

Commit

Permalink
Refactor services email et sms (#4066)
Browse files Browse the repository at this point in the history
* refactor: déplace enum email

* refactor: outil d'envoi d'email

* refactor: déplace le schema du followup dans un fichier dédié

* refactor: création de email-service (separation des responsabilités)

* feat: ajoute un enum commun pour le service de messages

* refactor: arborescence service messaging

* refacto: messaging enum path

* refactor : renderAndSendEmail en sendEmail + sendMail en sendEmailSmtp

* refactor: followup sendSurvey

* refactor: supprime enum non utile

* refactor: déplace méthode followup dans email-service

* refactor: déplace le script outil d'envoi d'email

* refactor: supprime email.sh et ajoute son contenu dans une commande du package.json

* refactor: smsCategory pas utilisé ici

* refactor: enum EmailCategory -> EmailType

* refactor: service email

* fix: Lever des erreurs si accès à une props d'un objet undefined

* refactor: sort sendSimulationResultsEmail du followup -> email-service

* refactor: déplace sendSurvey (modele Followup -> email-service) & suppr sendEmail d'email-service

* refactor: supprime emailPromise

* fix: manquait champ type à la création du survey

* refactor: ordre des méthodes

* refactor: manque un await

* refactor: homogénéise -> msg de succès dans l'envoi de l'email de sondage

* refactor: supprime une condition de rendu par email (getFollowupEmail)

La gestion d'erreur est traitée dans la fonction renderEmailByType
  • Loading branch information
Shamzic authored Nov 28, 2023
1 parent f898a80 commit 93ebe94
Show file tree
Hide file tree
Showing 14 changed files with 186 additions and 186 deletions.
16 changes: 9 additions & 7 deletions backend/controllers/emails.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import { EmailType } from "../../backend/enums/email.js"
import emailRender from "../../backend/lib/mes-aides/emails/email-render.js"
import { EmailType } from "../../lib/enums/messaging.js"
import { SurveyType } from "../../lib/enums/survey.js"
import {
emailRender,
emailRenderBySurveyType,
} from "../../backend/lib/mes-aides/emails/email-render.js"

const renderFollowupEmailByType = async (followup, emailType: EmailType) => {
const renderEmailByType = async (followup, emailType: EmailType) => {
let surveyType: SurveyType | undefined

switch (emailType) {
Expand All @@ -17,16 +20,15 @@ const renderFollowupEmailByType = async (followup, emailType: EmailType) => {
default:
throw new Error(`Unknown email type: ${emailType}`)
}

return followup.renderSurveyEmail(surveyType)
return emailRenderBySurveyType(surveyType, followup)
}

const getFollowupEmail = async (req, res, next) => {
try {
const { emailType }: { emailType: EmailType } = req.query
const followup = req.followup
const result = await renderFollowupEmailByType(followup, emailType)
res.send(result["html"])
const result = await renderEmailByType(followup, emailType)
res.send(result?.html)
} catch (err) {
next(err)
}
Expand Down
3 changes: 2 additions & 1 deletion backend/controllers/followups.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { FetchSurvey } from "../../lib/types/survey.d.js"
import Request from "../types/express.d.js"
import { phoneNumberValidation } from "../../lib/phone-number.js"
import config from "../config/index.js"
import { sendSimulationResultsEmail } from "../lib/messaging/email/email-service.js"

export function followup(
req: Request,
Expand Down Expand Up @@ -58,7 +59,7 @@ export async function persist(req: Request, res: Response) {
phone
)) as Followup
if (email) {
await followup.sendSimulationResultsEmail()
await sendSimulationResultsEmail(followup)
}
if (phone) {
if (
Expand Down
5 changes: 0 additions & 5 deletions backend/lib/email.sh

This file was deleted.

29 changes: 27 additions & 2 deletions backend/lib/mes-aides/emails/email-render.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import config from "../../../config/index.js"
import openfiscaController from "../../openfisca/parameters.js"
import { formatBenefits, basicBenefitText } from "./simulation-results.js"
import { mjml } from "./index.js"
import { EmailType } from "../../../enums/email.js"
import { EmailType } from "../../../../lib/enums/messaging.js"
import { SurveyType } from "../../../../lib/enums/survey.js"

const __dirname = new URL(".", import.meta.url).pathname

Expand Down Expand Up @@ -90,7 +91,7 @@ function renderAsHtml(emailType: EmailType, dataTemplate) {
})
}

export default async function emailRender(emailType: EmailType, followup) {
export async function emailRender(emailType: EmailType, followup) {
let benefits: any = null
let parameters: any = null
let formatedBenefits: any = {}
Expand Down Expand Up @@ -152,3 +153,27 @@ export default async function emailRender(emailType: EmailType, followup) {
}
})
}

export async function emailRenderBySurveyType(
surveyType: SurveyType,
followup
) {
switch (surveyType) {
case SurveyType.TrackClickOnBenefitActionEmail:
return emailRender(EmailType.BenefitAction, followup)
case SurveyType.TrackClickOnSimulationUsefulnessEmail:
return emailRender(EmailType.SimulationUsefulness, followup)
case SurveyType.TousABordNotification:
return emailRender(EmailType.TousABordNotification, followup)
case SurveyType.BenefitAction:
return Promise.reject(
new Error(
`This surveyType "${surveyType}" is not supposed to be sent through an email`
)
)
default:
return Promise.reject(
new Error(`This surveyType "${surveyType}" has no email template`)
)
}
}
58 changes: 58 additions & 0 deletions backend/lib/messaging/email/email-service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { sendEmailSmtp } from "../../smtp.js"
import {
emailRender,
emailRenderBySurveyType,
} from "../../mes-aides/emails/email-render.js"
import { EmailType } from "../../../../lib/enums/messaging.js"
import { SurveyType } from "../../../../lib/enums/survey.js"
import { Survey } from "../../../../lib/types/survey.js"
import { Followup } from "../../../../lib/types/followup.js"
import dayjs from "dayjs"

export async function sendSimulationResultsEmail(
followup: Followup
): Promise<Followup> {
if (!followup.email) {
throw new Error("Missing followup email")
}
const render: any = await emailRender(EmailType.SimulationResults, followup)
const sendEmailSmtpResponse = await sendEmailSmtp({
to: followup.email,
subject: render.subject,
text: render.text,
html: render.html,
tags: [EmailType.SimulationResults],
})

followup.sentAt = dayjs().toDate()
followup.messageId = sendEmailSmtpResponse.messageId

if (!followup.surveyOptin) {
followup.email = undefined
}
followup.error = undefined

return await followup.save()
}

export async function sendSurveyEmail(
followup: Followup,
surveyType: SurveyType
): Promise<Survey> {
if (!followup.email) {
throw new Error("Missing followup email")
}
const survey = await followup.addSurveyIfMissing(surveyType)
const render: any = await emailRenderBySurveyType(surveyType, followup)
const sendEmailSmtpResponse = await sendEmailSmtp({
to: followup.email,
subject: render.subject,
text: render.text,
html: render.html,
tags: ["survey", surveyType],
})

survey.messageId = sendEmailSmtpResponse.messageId
await followup.save()
return survey
}
29 changes: 14 additions & 15 deletions backend/lib/emails/sending.ts → backend/lib/messaging/sending.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import dayjs from "dayjs"

import { EmailType } from "../../enums/email.js"
import { EmailType } from "../../../lib/enums/messaging.js"
import { SurveyType } from "../../../lib/enums/survey.js"
import Followups from "../../models/followup.js"
import { Followup } from "../../../lib/types/followup.js"
import {
sendSimulationResultsEmail,
sendSurveyEmail,
} from "../messaging/email/email-service.js"

const DaysBeforeInitialEmail = 6
const DaysBeforeTousABordNotificationEmail = 2
Expand Down Expand Up @@ -52,8 +56,8 @@ async function sendMultipleInitialEmails(limit: number) {
: SurveyType.TrackClickOnSimulationUsefulnessEmail

try {
const result = await followup.sendSurvey(surveyType)
return { ok: result._id }
const survey = await sendSurveyEmail(followup, surveyType)
return { survey_id: survey._id }
} catch (error) {
return { ko: error }
}
Expand Down Expand Up @@ -91,10 +95,11 @@ async function sendMultipleTousABordNotificationEmails(limit: number) {
const results = await Promise.all(
followups.map(async (followup: Followup) => {
try {
const result = await followup.sendSurvey(
const survey = await sendSurveyEmail(
followup,
SurveyType.TousABordNotification
)
return { ok: result._id }
return { survey_id: survey._id }
} catch (error) {
return { ko: error }
}
Expand All @@ -109,28 +114,22 @@ async function processSingleEmail(emailType: EmailType, followupId: string) {
throw new Error("Followup not found")
}

let emailPromise: Promise<void>

switch (emailType) {
case EmailType.SimulationResults:
emailPromise = followup.sendSimulationResultsEmail()
await sendSimulationResultsEmail(followup)
break
case EmailType.BenefitAction:
emailPromise = followup.sendSurvey(
SurveyType.TrackClickOnBenefitActionEmail
)
await sendSurveyEmail(followup, SurveyType.TrackClickOnBenefitActionEmail)
break
case EmailType.SimulationUsefulness:
emailPromise = followup.sendSurvey(
await sendSurveyEmail(
followup,
SurveyType.TrackClickOnSimulationUsefulnessEmail
)
break
default:
throw new Error(`Unknown email type: ${emailType}`)
}

const email = await emailPromise
console.log("Email sent", email)
}

export async function processSendEmails(
Expand Down
2 changes: 1 addition & 1 deletion backend/lib/smtp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Email } from "../../lib/types/email.js"

const transporter = nodemailer.createTransport(config.smtp)

export function sendMail(email: Email) {
export function sendEmailSmtp(email: Email) {
const { tags, ...emailParameters } = email
const tagsFormatted = tags?.map((tag) => tag.replace(/-/g, "_")) || []

Expand Down
49 changes: 49 additions & 0 deletions backend/models/followup-schema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import mongoose from "mongoose"
import validator from "validator"
import { Followup } from "../../lib/types/followup.d.js"
import { FollowupModel } from "../types/models.d.js"
import SurveySchema from "./survey-schema.js"

const FollowupSchema = new mongoose.Schema<Followup, FollowupModel>(
{
simulation: {
type: mongoose.Schema.Types.ObjectId,
ref: "Simulation",
},
email: {
type: String,
validate: {
validator: validator.isEmail,
message: "Email invalide",
isAsync: false,
},
},
phone: {
type: String,
validate: {
validator: validator.isMobilePhone,
message: "Numéro de téléphone invalide",
isAsync: false,
},
},
createdAt: { type: Date, default: Date.now },
sentAt: { type: Date },
smsSentAt: { type: Date },
messageId: { type: String },
smsMessageId: { type: String },
surveySentAt: { type: Date },
benefits: { type: Object },
surveyOptin: { type: Boolean, default: false },
surveys: {
type: [SurveySchema],
default: [],
},
version: Number,
error: { type: Object },
smsError: { type: Object },
accessToken: { type: String },
},
{ minimize: false, id: false }
)

export default FollowupSchema
Loading

0 comments on commit 93ebe94

Please sign in to comment.