Skip to content

Commit

Permalink
feat: progress
Browse files Browse the repository at this point in the history
  • Loading branch information
alanlr committed Dec 6, 2023
1 parent 4fe9f59 commit b586ba4
Show file tree
Hide file tree
Showing 9 changed files with 48 additions and 132 deletions.
28 changes: 0 additions & 28 deletions server/src/http/routes/campaignWebhook.controller.ts

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ import { zRoutes } from "shared/index"

import config from "@/config"

import { logger } from "../../../common/logger"
import { Etablissement } from "../../../common/model"
import { addEmailToBlacklist } from "../../../services/application.service"
import * as appointmentService from "../../../services/appointment.service"
import { BrevoEventStatus } from "../../../services/brevo.service"
import dayjs from "../../../services/dayjs.service"
import * as eligibleTrainingsForAppointmentService from "../../../services/eligibleTrainingsForAppointment.service"
import { Server } from "../../server"
import { logger } from "../../common/logger"
import { Etablissement } from "../../common/model"
import { addEmailToBlacklist, removeEmailFromLbaCompanies } from "../../services/application.service"
import * as appointmentService from "../../services/appointment.service"
import { BrevoEventStatus } from "../../services/brevo.service"
import dayjs from "../../services/dayjs.service"
import * as eligibleTrainingsForAppointmentService from "../../services/eligibleTrainingsForAppointment.service"
import { Server } from "../server"

/**
* Email controllers.
Expand All @@ -31,7 +31,30 @@ export default (server: Server) => {
throw Boom.forbidden()
}

const { date, event } = req.body
const { date, event, email } = req.body

if (event === BrevoEventStatus.HARD_BOUNCE) {
// ???? comment identifier la source du blacklisting

await Promise.all([addEmailToBlacklist(email, "campaign"), removeEmailFromLbaCompanies(email)])
}

// server.post(
// "/application/webhook",
// {
// schema: zRoutes.post["/application/webhook"],
// },
// async (req, res) => {
// const { apikey } = req.query
// if (apikey !== config.smtp.brevoWebhookApiKey) {
// throw Boom.unauthorized()
// }

// await updateApplicationStatus({ payload: req.body })
// return res.status(200).send({ result: "ok" })
// }
// )

const messageId = req.body["message-id"]
const eventDate = dayjs.utc(date).tz("Europe/Paris").toDate()

Expand Down
21 changes: 1 addition & 20 deletions server/src/http/routes/sendApplication.controller.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
import Boom from "boom"
import mongoose from "mongoose"
import { zRoutes } from "shared/index"

import config from "@/config"

import { Application } from "../../common/model/index"
import { decryptWithIV } from "../../common/utils/encryptString"
import { sentryCaptureException } from "../../common/utils/sentryUtils"
import { sendNotificationToApplicant, updateApplicationStatus, validateFeedbackApplicationComment } from "../../services/application.service"
import { sendNotificationToApplicant, validateFeedbackApplicationComment } from "../../services/application.service"
import { Server } from "../server"

const rateLimitConfig = {
Expand Down Expand Up @@ -77,20 +74,4 @@ export default function (server: Server) {
return res.status(200).send({ result: "ok" })
}
)

server.post(
"/application/webhook",
{
schema: zRoutes.post["/application/webhook"],
},
async (req, res) => {
const { apikey } = req.query
if (apikey !== config.smtp.brevoWebhookApiKey) {
throw Boom.unauthorized()
}

await updateApplicationStatus({ payload: req.body })
return res.status(200).send({ result: "ok" })
}
)
}
4 changes: 1 addition & 3 deletions server/src/http/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,9 @@ import eligibleTrainingsForAppointmentRoute from "./routes/admin/eligibleTrainin
import adminEtablissementRoute from "./routes/admin/etablissement.controller"
import formationsRoute from "./routes/admin/formations.controller"
import appointmentRequestRoute from "./routes/appointmentRequest.controller"
import emailsRoute from "./routes/auth/emails.controller"
import login from "./routes/auth/login.controller"
import campaignWebhook from "./routes/campaignWebhook.controller"
import { coreRoutes } from "./routes/core.controller"
import emailsRoute from "./routes/emails.controller"
import etablissementRoute from "./routes/etablissement.controller"
import etablissementsRecruteurRoute from "./routes/etablissementRecruteur.controller"
import formulaireRoute from "./routes/formulaire.controller"
Expand Down Expand Up @@ -134,7 +133,6 @@ export async function bind(app: Server) {
metiers(typedSubApp)
rome(typedSubApp)
updateLbaCompany(typedSubApp)
campaignWebhook(typedSubApp)
sendApplication(typedSubApp)
sendApplicationAPI(typedSubApp)
unsubscribeLbaCompany(typedSubApp)
Expand Down
35 changes: 13 additions & 22 deletions server/src/services/brevo.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,45 +10,36 @@ apiKey.apiKey = config.smtp.brevoApiKey

const apiInstance = new SibApiV3Sdk.WebhooksApi()

let applicationStatusWebhook = new SibApiV3Sdk.CreateWebhook()
let emailWebhook = new SibApiV3Sdk.CreateWebhook()

export const enum BrevoEventStatus {
HARD_BOUNCE = "hard_bounce",
}

applicationStatusWebhook = {
description: "Changements d'états des emails de candidatures",
url: `${config.publicUrl}/api/application/webhook?apikey=${config.smtp.brevoWebhookApiKey}`,
events: ["hardBounce"],
type: "transactional",
}

let campaignHarbounceWebhook = new SibApiV3Sdk.CreateWebhook()

campaignHarbounceWebhook = {
description: "Traitement des harbounces des emails des campagnes",
url: `${config.publicUrl}/api/campaign/webhook?apikey=${config.smtp.brevoWebhookApiKey}`,
events: ["hardBounce"],
type: "marketing",
emailWebhook = {
description: "Changements d'états des emails de candidatures ou de rendez-vous ou de marketing",
// url: `${config.publicUrl}/api/email/webhook?apikey=${config.smtp.brevoWebhookApiKey}`,
url: `https://labonnealternance-recette.apprentissage.beta.gouv.fr/api/emails/webhook?apikey=${config.smtp.brevoWebhookApiKey}`,
events: ["hardBounce", "delivered", "request", "click", "uniqueOpened"],
}

/**
* Initialise les webhooks Brevo au démarrage du docker server. Echoue sans conséquences s'ils existent déjà
*/
export const initBrevoWebhooks = () => {
if (config.env !== "production") {
return
}
// if (config.env !== "production") {
// return
// }

apiInstance.createWebhook(applicationStatusWebhook).then(
apiInstance.createWebhook({ ...emailWebhook, type: "transactional" }).then(
function (data) {
logger.info("Brevo webhook API called successfully for application email status changes. Returned data: " + JSON.stringify(data))
logger.info("Brevo webhook API called successfully for email (appointment, application) status changes. Returned data: " + JSON.stringify(data))
},
function (error) {
logger.error("Brevo webhook API Error for application email status changes. Returned data: " + error.response.res.text)
logger.error("Brevo webhook API Error for email (appointment, application) status changes. Returned data: " + error.response.res.text)
}
)
apiInstance.createWebhook(campaignHarbounceWebhook).then(
apiInstance.createWebhook({ ...emailWebhook, events: ["hardBounce"], type: "marketing" }).then(
function (data) {
logger.info("Brevo webhook API called successfully for campaign hardbounce detection. Returned data: " + JSON.stringify(data))
},
Expand Down
19 changes: 0 additions & 19 deletions shared/routes/application.routes.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { extensions } from "../helpers/zodHelpers/zodPrimitives"
import { z } from "../helpers/zodWithOpenApi"
import { ZLbacError } from "../models"
import { ZApplicationUI } from "../models/applications.model"
Expand Down Expand Up @@ -85,23 +84,5 @@ export const zApplicationRoutes = {
},
securityScheme: null,
},
"/application/webhook": {
path: "/application/webhook",
method: "post",
querystring: z
.object({
apikey: z.string(),
})
.strict(),
body: extensions.brevoWebhook(),
response: {
"200": z
.object({
result: z.literal("ok"),
})
.strict(),
},
securityScheme: null,
},
},
} as const satisfies IRoutesDef
27 changes: 0 additions & 27 deletions shared/routes/campaignWebhook.routes.ts

This file was deleted.

3 changes: 1 addition & 2 deletions shared/routes/emails.routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { z } from "../helpers/zodWithOpenApi"
import { IRoutesDef } from "./common.routes"

export const zEmailsRoutes = {
// TODO_SECURITY_FIX à ajouter dans le init . ne faire qu'un seul webhook au lieu de trois
post: {
"/emails/webhook": {
method: "post",
Expand All @@ -13,7 +12,7 @@ export const zEmailsRoutes = {
.object({
apiKey: z.string(),
})
.passthrough(),
.strict(),
body: extensions.brevoWebhook(),
response: {
"200": z.object({}).strict(),
Expand Down
2 changes: 0 additions & 2 deletions shared/routes/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import z, { ZodType } from "zod"

import { zApplicationRoutes } from "./application.routes"
import { zAppointmentsRoute } from "./appointments.routes"
import { zCampaignWebhookRoutes } from "./campaignWebhook.routes"
import { IRouteSchema, IRouteSchemaWrite } from "./common.routes"
import { zCoreRoutes } from "./core.routes"
import { zEligibleTrainingsForAppointmentRoutes } from "./eligibleTrainingsForAppointment.routes"
Expand Down Expand Up @@ -77,7 +76,6 @@ const zRoutesPost1 = {
const zRoutesPost2 = {
...zFormulaireRoute.post,
...zRecruiterRoutes.post,
...zCampaignWebhookRoutes.post,
}

const zRoutesPost3 = {
Expand Down

0 comments on commit b586ba4

Please sign in to comment.