Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor services email et sms #4066

Merged
merged 25 commits into from
Nov 28, 2023
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
dce9cf3
refactor: déplace enum email
Shamzic Nov 9, 2023
4783f15
refactor: outil d'envoi d'email
Shamzic Nov 14, 2023
d52e7dd
refactor: déplace le schema du followup dans un fichier dédié
Shamzic Nov 10, 2023
ae3723e
refactor: création de email-service (separation des responsabilités)
Shamzic Nov 10, 2023
7370835
feat: ajoute un enum commun pour le service de messages
Shamzic Nov 10, 2023
7d41dd2
refactor: arborescence service messaging
Shamzic Nov 15, 2023
5a99399
refacto: messaging enum path
Shamzic Nov 15, 2023
c06f0f8
refactor : renderAndSendEmail en sendEmail + sendMail en sendEmailSmtp
Shamzic Nov 16, 2023
470d904
refactor: followup sendSurvey
Shamzic Nov 16, 2023
0943e29
refactor: supprime enum non utile
Shamzic Nov 16, 2023
f9e06fb
refactor: déplace méthode followup dans email-service
Shamzic Nov 16, 2023
93d5f9b
refactor: déplace le script outil d'envoi d'email
Shamzic Nov 16, 2023
796b14c
refactor: supprime email.sh et ajoute son contenu dans une commande d…
Shamzic Nov 16, 2023
9159807
refactor: smsCategory pas utilisé ici
Shamzic Nov 20, 2023
5644f94
refactor: enum EmailCategory -> EmailType
Shamzic Nov 20, 2023
5c2fba9
refactor: service email
Shamzic Nov 20, 2023
a95bf65
fix: Lever des erreurs si accès à une props d'un objet undefined
Shamzic Nov 20, 2023
1f2e56b
refactor: sort sendSimulationResultsEmail du followup -> email-service
Shamzic Nov 20, 2023
30c238c
refactor: déplace sendSurvey (modele Followup -> email-service) & sup…
Shamzic Nov 20, 2023
949c02a
refactor: supprime emailPromise
Shamzic Nov 21, 2023
e53f734
fix: manquait champ type à la création du survey
Shamzic Nov 21, 2023
5740053
refactor: ordre des méthodes
Shamzic Nov 23, 2023
9491fd9
refactor: manque un await
Shamzic Nov 23, 2023
258b8aa
refactor: homogénéise -> msg de succès dans l'envoi de l'email de son…
Shamzic Nov 27, 2023
22f7321
refactor: supprime une condition de rendu par email (getFollowupEmail)
Shamzic Nov 28, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 11 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) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pour avancé on va pas changer cette PR, mais ici j'ai l'impression finalement que c'est exactement la fonction emailRender qu'on veut recoder (en inversant le sens des argument ? Je créé un ticket pour plus tard.

let surveyType: SurveyType | undefined

switch (emailType) {
Expand All @@ -17,16 +20,17 @@ 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)
if (result) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Si on rajoute ce if sans else on pourrait ne jamais répondre à la requête, on peut soit l'enlever, en se disant qu'au pire on repond rien, soit throw une erreur, mais normalement la fonction au dessus le fait deja non ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Shamzic je sais pas si tu avais vu

Copy link
Contributor Author

@Shamzic Shamzic Nov 28, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

J'ai supprimé la condition car, comme tu l'indiques, renderEmailByType relève déjà les cas d'erreur

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,31 @@ function renderAsHtml(emailType: EmailType, dataTemplate) {
})
}

export default async function emailRender(emailType: EmailType, followup) {
export async function emailRenderBySurveyType(
Shamzic marked this conversation as resolved.
Show resolved Hide resolved
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`)
)
}
}

export async function emailRender(emailType: EmailType, followup) {
let benefits: any = null
let parameters: any = null
let formatedBenefits: any = {}
Expand Down
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"
baptou12 marked this conversation as resolved.
Show resolved Hide resolved
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 }
Shamzic marked this conversation as resolved.
Show resolved Hide resolved
} 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 { ok: 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()
sendSimulationResultsEmail(followup)
Shamzic marked this conversation as resolved.
Show resolved Hide resolved
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