Skip to content

Commit

Permalink
[EN-6471] feat(newsletter): remove plezi to use mailjet for newslette…
Browse files Browse the repository at this point in the history
…r subscription
  • Loading branch information
emile-bex committed Oct 9, 2023
1 parent 411706a commit d09cfda
Show file tree
Hide file tree
Showing 19 changed files with 237 additions and 326 deletions.
28 changes: 16 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ yarn
docker-compose up --build
```

Dans le cas où vous travaillez sur mac, le module Sharp peut poser problème, vous devez donc le réinstaller au sein du container:
Dans le cas où vous travaillez sur mac, le module Sharp peut poser problème, vous devez donc le réinstaller au sein du
container:

```
docker exec -it api_new bash
Expand All @@ -87,15 +88,17 @@ Pour lancer les migrations :
yarn db:migrate
```

APour remplir la base de données avec un utilisateur administrateur permettant la création par la suite d'autres utilisateurs :
APour remplir la base de données avec un utilisateur administrateur permettant la création par la suite d'autres
utilisateurs :

```
yarn db:seed
```

#### Avec Docker

La même chose que sans Docker, mais vous devez précéder les commandes par la suivante, et ne pas lancer la commande de création de DB:
La même chose que sans Docker, mais vous devez précéder les commandes par la suivante, et ne pas lancer la commande de
création de DB:

```
docker exec -it api bash
Expand Down Expand Up @@ -152,9 +155,11 @@ yarn start

#### Mode développement

Pour pouvoir utiliser le worker en local il faut lancer une instance de **_Redis_** en local : https://redis.io/docs/getting-started
Pour pouvoir utiliser le worker en local il faut lancer une instance de **_Redis_** en
local : https://redis.io/docs/getting-started

Il faut également enlever les variables d'environnement _REDIS_URL_ et _REDIS_TLS_URL_ afin que les modules **_Redis_** et **_Bull_** utilisent leur configuration par défaut pour se connecter à _**Redis**_ en local (`127.0.0.1:6379`)
Il faut également enlever les variables d'environnement _REDIS_URL_ et _REDIS_TLS_URL_ afin que les modules **_Redis_**
et **_Bull_** utilisent leur configuration par défaut pour se connecter à _**Redis**_ en local (`127.0.0.1:6379`)

```
yarn worker:start:dev
Expand Down Expand Up @@ -222,10 +227,6 @@ MAILJET_SMS_TOKEN=
MAILJET_SUPPORT_EMAIL=
OFFER_NO_RESPONSE_DELAY=
OFFER_REMINDER_DELAY=
PLEZI_API_KEY=
PLEZI_CONTENT_WEB_FORM_ID=
PLEZI_FORM_ID=
PLEZI_TENANT_NAME=
PORT=
PUSHER_API_KEY=
PUSHER_API_SECRET=
Expand Down Expand Up @@ -263,7 +264,8 @@ VONAGE_API_SECRET=
docker run --name linkedout-db-test -e POSTGRES_PASSWORD=linkedout -e POSTGRES_USER=linkedout -e POSTGRES_DB=linkedout -d -p 54300:5432 postgres
```

Vous avez besoin des données du fichier `.env.test` pour les tests en local, et de renseigner le champ _DATABASE_URL_ (_ex:_ `postgresql://linkedout:linkedout@localhost:54300/linkedout`) avec l'adresse de l'instance **_Docker_**
Vous avez besoin des données du fichier `.env.test` pour les tests en local, et de renseigner le champ _DATABASE_URL_ (
_ex:_ `postgresql://linkedout:linkedout@localhost:54300/linkedout`) avec l'adresse de l'instance **_Docker_**

```
NODE_ENV=dev-test yarn db:migrate
Expand All @@ -278,9 +280,11 @@ NODE_ENV=dev-test yarn db:migrate

Le déploiement se fait automatiquement grâce à **_Github Actions_** et **_Heroku_**.

Si un commit est poussé sur `develop`, l'application sera déployé sur la pre-production : **[https://entourage-job-preprod.herokuapp.com](https://entourage-job-preprod.herokuapp.com)**
Si un commit est poussé sur `develop`, l'application sera déployé sur la pre-production : *
*[https://entourage-job-preprod.herokuapp.com](https://entourage-job-preprod.herokuapp.com)**

Si un commit est poussé sur `master`, l'application sera déployé sur la production : **[https://api.linkedout.fr](https://api.linkedout.fr)**
Si un commit est poussé sur `master`, l'application sera déployé sur la production : *
*[https://api.linkedout.fr](https://api.linkedout.fr)**

Les tests sont effectués sur **_Github Actions_** avant de déployer le projet sur **_Heroku_**.

Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
"moment": "^2.29.4",
"moment-timezone": "^0.5.43",
"node-fetch": "^2.6.7",
"node-mailjet": "^3.3.7",
"node-mailjet": "^3.3.9",
"passport": "^0.6.0",
"passport-jwt": "^4.0.0",
"passport-local": "^1.0.0",
Expand Down Expand Up @@ -103,7 +103,7 @@
"@types/multer": "^1.4.7",
"@types/node": "^16.0.0",
"@types/node-fetch": "2.x",
"@types/node-mailjet": "^3.3.8",
"@types/node-mailjet": "^3.3.9",
"@types/passport-jwt": "^3.0.6",
"@types/passport-local": "^1.0.34",
"@types/puppeteer": "^5.4.6",
Expand Down
2 changes: 0 additions & 2 deletions src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ import { ExternalDatabasesModule } from './external-databases/external-databases
import { ExternalMessagesModule } from './external-messages/external-messages.module';
import { BitlyModule } from './external-services/bitly/bitly.module';
import { MailjetModule } from './external-services/mailjet/mailjet.module';
import { PleziModule } from './external-services/plezi/plezi.module';
import { SalesforceModule } from './external-services/salesforce/salesforce.module';
import { MailsModule } from './mails/mails.module';
import { OpportunitiesModule } from './opportunities/opportunities.module';
Expand Down Expand Up @@ -120,7 +119,6 @@ export function getSequelizeOptions(): SequelizeModuleOptions {
SMSModule,
BitlyModule,
ContactsModule,
PleziModule,
OrganizationsModule,
ExternalMessagesModule,
],
Expand Down
20 changes: 5 additions & 15 deletions src/contacts/contacts.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,7 @@ import {
ContactUsFormDto,
ContactUsFormPipe,
} from 'src/contacts/dto';
import {
ContactStatus,
PleziTrackingData,
} from 'src/external-services/plezi/plezi.types';
import { ContactStatus } from 'src/external-services/mailjet/mailjet.types';
import { isValidPhone } from 'src/utils/misc';
import { AdminZone } from 'src/utils/types';
import { ContactsService } from './contacts.service';
Expand Down Expand Up @@ -81,25 +78,18 @@ export class ContactsController {
@Post('newsletter')
async addContactForNewsletter(
@Body('email') email: string,
@Body('zone') zone: AdminZone | AdminZone[],
@Body('status') status: ContactStatus | ContactStatus[],
@Body('visit') visit?: PleziTrackingData['visit'],
@Body('visitor') visitor?: PleziTrackingData['visitor'],
@Body('urlParams')
urlParams?: PleziTrackingData['urlParams']
@Body('zone') zone?: AdminZone | AdminZone[],
@Body('status') status?: ContactStatus | ContactStatus[]
) {
if (!email) {
throw new BadRequestException();
}

return this.contactsService.sendContactToPlezi(
await this.contactsService.sendContactToMailjet({
email,
zone,
status,
visit,
visitor,
urlParams
);
});
}

@Public()
Expand Down
4 changes: 2 additions & 2 deletions src/contacts/contacts.module.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { Module } from '@nestjs/common';
import { PleziModule } from 'src/external-services/plezi/plezi.module';
import { MailjetModule } from 'src/external-services/mailjet/mailjet.module';
import { SalesforceModule } from 'src/external-services/salesforce/salesforce.module';
import { MailsModule } from 'src/mails/mails.module';
import { ContactsController } from './contacts.controller';
import { ContactsService } from './contacts.service';

@Module({
imports: [MailsModule, SalesforceModule, PleziModule],
imports: [MailsModule, SalesforceModule, MailjetModule],
controllers: [ContactsController],
providers: [ContactsService],
exports: [ContactsService],
Expand Down
29 changes: 5 additions & 24 deletions src/contacts/contacts.service.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,9 @@
import { Injectable } from '@nestjs/common';

import { MailjetService } from '../external-services/mailjet/mailjet.service';
import { CustomContactParams } from '../external-services/mailjet/mailjet.types';
import { ContactCompanyFormDto, ContactUsFormDto } from 'src/contacts/dto';
import { PleziService } from 'src/external-services/plezi/plezi.service';
import {
ContactStatus,
PleziTrackingData,
} from 'src/external-services/plezi/plezi.types';
import { SalesforceService } from 'src/external-services/salesforce/salesforce.service';
import { MailsService } from 'src/mails/mails.service';
import { AdminZone } from 'src/utils/types';
import { ContactCandidateFormDto } from './dto/contact-candidate-form.dto';
import { InscriptionCandidateFormDto } from './dto/inscription-candidate-form.dto';

Expand All @@ -17,25 +12,11 @@ export class ContactsService {
constructor(
private mailsService: MailsService,
private salesforceService: SalesforceService,
private pleziService: PleziService
private mailjetService: MailjetService
) {}

async sendContactToPlezi(
email: string,
zone: AdminZone | AdminZone[],
status: ContactStatus | ContactStatus[],
visit?: PleziTrackingData['visit'],
visitor?: PleziTrackingData['visitor'],
urlParams?: PleziTrackingData['urlParams']
) {
return this.pleziService.sendContactToPlezi(
email,
zone,
status,
visit,
visitor,
urlParams
);
async sendContactToMailjet(contact: CustomContactParams) {
return this.mailjetService.sendContact(contact);
}

async sendCompanyContactToSalesforce(
Expand Down
48 changes: 44 additions & 4 deletions src/external-services/mailjet/mailjet.service.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,38 @@
import { Injectable } from '@nestjs/common';
import _ from 'lodash';
import { Email, connect } from 'node-mailjet';
import { CustomMailParams, MailjetTemplates } from './mailjet.types';
import { connect, Email } from 'node-mailjet';
import {
CustomContactParams,
CustomMailParams,
MailjetError,
MailjetTemplates,
} from './mailjet.types';
import SendParams = Email.SendParams;
import SendParamsRecipient = Email.SendParamsRecipient;

const useCampaigns = process.env.MAILJET_CAMPAIGNS_ACTIVATED === 'true';

@Injectable()
export class MailjetService {
private send: Email.PostResource;
private contact: Email.PostResource;

constructor() {
const mailjet = connect(
const mailjetTransactional = connect(
`${process.env.MAILJET_PUB}`,
`${process.env.MAILJET_SEC}`
);

this.send = mailjet.post('send', { version: 'v3.1' });
this.send = mailjetTransactional.post('send', {
version: 'v3.1',
});

const mailjetNewsletter = connect(
`${process.env.MAILJET_NEWSLETTER_PUB}`,
`${process.env.MAILJET_NEWSLETTER_SEC}`
);

this.contact = mailjetNewsletter.post('contact', { version: 'v3' });
}

createMail({
Expand Down Expand Up @@ -114,4 +130,28 @@ export class MailjetService {

return this.send.request(mailjetParams);
}

createContact({ email /* status, zone */ }: CustomContactParams) {
const contacts: SendParamsRecipient = {
Email: email,
};
return contacts;
}

async sendContact(params: CustomContactParams) {
const mailjetParams: SendParamsRecipient = this.createContact(params);

try {
await this.contact.request(mailjetParams);
} catch (err) {
console.error(err);
// Check if not a duplicate value error, otherwise consider it as successful request
if (
(err as MailjetError).statusCode !== 400 ||
!(err as MailjetError).ErrorMessage.includes('MJ18')
) {
throw err;
}
}
}
}
39 changes: 39 additions & 0 deletions src/external-services/mailjet/mailjet.types.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { AdminZone, AdminZones } from 'src/utils/types';

export interface CustomMailParams {
toEmail:
| string
Expand All @@ -15,6 +17,12 @@ export interface CustomMailParams {
templateId: MailjetTemplate;
}

export interface CustomContactParams {
email: string;
zone: AdminZone | AdminZone[];
status: ContactStatus | ContactStatus[];
}

export const MailjetTemplates = {
ACCOUNT_CREATED: 3920498,
CV_PREPARE: 3782475,
Expand Down Expand Up @@ -52,3 +60,34 @@ export const MailjetTemplates = {
export type MailjetTemplateKey = keyof typeof MailjetTemplates;

export type MailjetTemplate = typeof MailjetTemplates[MailjetTemplateKey];

export const ContactStatuses = {
INDIVIDUAL: 'PARTICULIER',
COMPANY: 'ENTREPRISE',
STRUCTURE: 'STRUCTURE_INSERTION',
CANDIDATE: 'CANDIDAT_POTENTIEL',
} as const;

export type ContactStatus =
typeof ContactStatuses[keyof typeof ContactStatuses];

export const MailjetContactRegions: { [K in AdminZone]: string } = {
[AdminZones.LYON]: AdminZones.LYON.toLowerCase(),
[AdminZones.PARIS]: AdminZones.PARIS.toLowerCase(),
[AdminZones.LILLE]: AdminZones.LILLE.toLowerCase(),
[AdminZones.LORIENT]: AdminZones.LORIENT.toLowerCase(),
[AdminZones.RENNES]: AdminZones.RENNES.toLowerCase(),
[AdminZones.HZ]: AdminZones.HZ.toLowerCase(),
} as const;

export const MailjetContactStatuses: { [K in ContactStatus]: string } = {
PARTICULIER: 'un-particulier',
ENTREPRISE: 'une-entreprise',
STRUCTURE_INSERTION: 'une-structure-d-insertion',
CANDIDAT_POTENTIEL: 'un-candidat-potentiel',
} as const;

export interface MailjetError {
statusCode: number;
ErrorMessage: string;
}
8 changes: 0 additions & 8 deletions src/external-services/plezi/plezi.module.ts

This file was deleted.

Loading

0 comments on commit d09cfda

Please sign in to comment.