Skip to content

Commit 49d4712

Browse files
committed
fix(task): add mattermost notifications bot
1 parent 25def82 commit 49d4712

File tree

4 files changed

+91
-54
lines changed

4 files changed

+91
-54
lines changed

src/api/auth/auth.middlewares.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ export const signup = async (req, res, next) => {
4646
const { firstName, lastName, email } = body;
4747
agenda.now('send welcome email', { user: { firstName, lastName, email } });
4848
agenda.now('send user creation notification email', { user: { firstName, lastName } });
49+
agenda.now(
50+
'send mattermost notification',
51+
{ message: `:tada: Un nouvel utilisateur a été créé !\n**Nom :** ${firstName} ${lastName}\n**Email :** ${email}` },
52+
);
4953
res.status(201).json({ message: 'Compte crée.' });
5054
return next();
5155
};

src/api/jobs/jobs.routes.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ function getDateXDaysAfter(x) {
1515
return new Date(Date.now() + x * 24 * 60 * 60 * 1000);
1616
}
1717

18-
const SKIP_JOBS = ['send welcome email', 'send confirmed email', 'send signin email', 'send recovery email', 'send contact email'];
18+
const SKIP_JOBS = ['send mattermost notification',
19+
'send welcome email', 'send confirmed email', 'send signin email', 'send recovery email', 'send contact email'];
1920

2021
router.route('/jobs')
2122
.get([

src/jobs/index.js

Lines changed: 61 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
1-
import os from "os";
2-
import { Agenda } from "agenda";
3-
import config from "../config";
4-
import logger from "../services/logger.service";
5-
import { db } from "../services/mongo.service";
6-
import askForEmailRevalidation from "./ask-for-email-validation";
1+
import os from 'os';
2+
import { Agenda } from 'agenda';
3+
import config from '../config';
4+
import logger from '../services/logger.service';
5+
import { db } from '../services/mongo.service';
6+
import askForEmailRevalidation from './ask-for-email-validation';
77
import {
88
sendAccountConfirmedEmail,
99
sendAuthenticationEmail,
1010
sendContactEmail,
1111
sendNewUserNotificationEmail,
1212
sendPasswordRecoveryEmail,
1313
sendWelcomeEmail,
14-
} from "./emails";
15-
import reindex from "./indexer";
16-
import updateKeyNumbers from "./key-numbers";
14+
} from './emails';
15+
import reindex from './indexer';
16+
import updateKeyNumbers from './key-numbers';
1717
import {
1818
exportFrEsrAnnelisPaysageEtablissements,
1919
exportFrEsrPaysageFonctionsGourvernance,
@@ -22,118 +22,126 @@ import {
2222
exportFrEsrPrizes,
2323
exportFrEsrStructureIdentifiers,
2424
exportFrEsrStructureWebsites,
25-
} from "./opendata";
26-
import { monitorSiren, monitorSiret } from "./sirene";
27-
import synchronizeAnnuaireCollection from "./synchronize/annuaire-collection";
28-
import synchronizeCuriexploreActors from "./synchronize/curiexplore-actors";
29-
import synchronizeFrEsrReferentielGeographique from "./synchronize/fr-esr-referentiel-geographique";
30-
import deletePassedGouvernancePersonnalInformation from "./treatments/delete-passed-gouvernance-personal-infos";
31-
import { setStructureStatus, setIdentifierStatus } from "./treatments/set-statuses";
32-
import dedupLegalCategorySirene from "./dedup-legal-category-sirene";
25+
} from './opendata';
26+
import { monitorSiren, monitorSiret } from './sirene';
27+
import synchronizeAnnuaireCollection from './synchronize/annuaire-collection';
28+
import synchronizeCuriexploreActors from './synchronize/curiexplore-actors';
29+
import synchronizeFrEsrReferentielGeographique from './synchronize/fr-esr-referentiel-geographique';
30+
import deletePassedGouvernancePersonnalInformation from './treatments/delete-passed-gouvernance-personal-infos';
31+
import { setStructureStatus, setIdentifierStatus } from './treatments/set-statuses';
32+
import dedupLegalCategorySirene from './dedup-legal-category-sirene';
33+
import { sendMattermostNotification } from './send-mattermost-notification';
3334

3435
const { taskName } = config.sirene;
3536

3637
const agenda = new Agenda()
37-
.mongo(db, "_jobs")
38+
.mongo(db, '_jobs')
3839
.name(`worker-${os.hostname}-${process.pid}`)
39-
.processEvery("30 seconds");
40+
.processEvery('30 seconds');
4041

4142
agenda.define(
42-
"send user creation notification email",
43+
'send user creation notification email',
4344
{ shouldSaveResult: true },
4445
sendNewUserNotificationEmail,
4546
);
4647
agenda.define(
47-
"send welcome email",
48+
'send welcome email',
4849
{ shouldSaveResult: true },
4950
sendWelcomeEmail,
5051
);
5152
agenda.define(
52-
"send confirmed email",
53+
'send confirmed email',
5354
{ shouldSaveResult: true },
5455
sendAccountConfirmedEmail,
5556
);
5657
agenda.define(
57-
"send signin email",
58+
'send signin email',
5859
{ shouldSaveResult: true },
5960
sendAuthenticationEmail,
6061
);
6162
agenda.define(
62-
"send recovery email",
63+
'send recovery email',
6364
{ shouldSaveResult: true },
6465
sendPasswordRecoveryEmail,
6566
);
6667
agenda.define(
67-
"send contact email",
68+
'send contact email',
6869
{ shouldSaveResult: true },
6970
sendContactEmail,
7071
);
7172
agenda.define(
72-
"update key numbers",
73+
'send mattermost notification',
74+
{ shouldSaveResult: true },
75+
sendMattermostNotification,
76+
);
77+
78+
agenda.define(
79+
'update key numbers',
7380
{
7481
shouldSaveResult: true,
7582
lockLifetime: 1000 * 60 * 60 * 5,
7683
},
7784
updateKeyNumbers,
7885
);
79-
agenda.define("reindex", { shouldSaveResult: true }, reindex);
86+
agenda.define('reindex', { shouldSaveResult: true }, reindex);
8087
agenda.define(
81-
"export fr-esr-paysage_prix",
88+
'export fr-esr-paysage_prix',
8289
{ shouldSaveResult: true },
8390
exportFrEsrPrizes,
8491
);
8592
agenda.define(
86-
"export fr-esr-paysage_structures_identifiants",
93+
'export fr-esr-paysage_structures_identifiants',
8794
{ shouldSaveResult: true },
8895
exportFrEsrStructureIdentifiers,
8996
);
9097
agenda.define(
91-
"export fr-esr-paysage_personnes_identifiants",
98+
'export fr-esr-paysage_personnes_identifiants',
9299
{ shouldSaveResult: true },
93100
exportFrEsrPersonIdentifiers,
94101
);
95102
agenda.define(
96-
"export fr-esr-paysage-fonctions-gourvernance",
103+
'export fr-esr-paysage-fonctions-gourvernance',
97104
{ shouldSaveResult: true },
98105
exportFrEsrPaysageFonctionsGourvernance,
99106
);
107+
100108
agenda.define(
101-
"export fr-esr-annelis-paysage-etablissements",
109+
'export fr-esr-annelis-paysage-etablissements',
102110
{ shouldSaveResult: true },
103111
exportFrEsrAnnelisPaysageEtablissements,
104112
);
105113
agenda.define(
106-
"export fr-esr-paysage_structures_websites",
114+
'export fr-esr-paysage_structures_websites',
107115
{ shouldSaveResult: true },
108116
exportFrEsrStructureWebsites,
109117
);
110118
agenda.define(
111-
"export fr_esr_paysage_laureat_all",
119+
'export fr_esr_paysage_laureat_all',
112120
{ shouldSaveResult: true },
113121
exportFrEsrPaysageLaureatAll,
114122
);
115123
agenda.define(
116-
"synchronize fr-esr-referentiel-geographique",
124+
'synchronize fr-esr-referentiel-geographique',
117125
{ shouldSaveResult: true },
118126
synchronizeFrEsrReferentielGeographique,
119127
);
120128
agenda.define(
121-
"synchronize curiexplore actors",
129+
'synchronize curiexplore actors',
122130
{ shouldSaveResult: true },
123131
synchronizeCuriexploreActors,
124132
);
125133
agenda.define(
126-
"ask for email revalidation with otp",
134+
'ask for email revalidation with otp',
127135
{ shouldSaveResult: true },
128136
askForEmailRevalidation,
129137
);
130138
agenda.define(
131-
"delete passed gouvernance personal info",
139+
'delete passed gouvernance personal info',
132140
{ shouldSaveResult: true },
133141
deletePassedGouvernancePersonnalInformation,
134142
);
135143
agenda.define(
136-
"synchronize governance collection",
144+
'synchronize governance collection',
137145
{ shouldSaveResult: true },
138146
synchronizeAnnuaireCollection,
139147
);
@@ -148,7 +156,7 @@ agenda.define(
148156
setIdentifierStatus,
149157
);
150158
agenda.define(
151-
"check de double catégories juridiques pour une unité légale",
159+
'check de double catégories juridiques pour une unité légale',
152160
{ shouldSaveResult: true },
153161
dedupLegalCategorySirene,
154162
);
@@ -170,18 +178,18 @@ agenda.define(
170178
);
171179

172180
agenda
173-
.on("ready", () => {
174-
logger.info("Agenda connected to mongodb");
181+
.on('ready', () => {
182+
logger.info('Agenda connected to mongodb');
175183
})
176-
.on("error", () => {
177-
logger.info("Agenda connexion to mongodb failed");
184+
.on('error', () => {
185+
logger.info('Agenda connexion to mongodb failed');
178186
});
179187

180-
agenda.on("complete", async (job) => {
181-
if (job.attrs?.type !== "single") return null;
188+
agenda.on('complete', async (job) => {
189+
if (job.attrs?.type !== 'single') return null;
182190

183-
const keepFailureFields = job.attrs.failedAt &&
184-
job.attrs.failedAt === job.attrs.lastFinishedAt;
191+
const keepFailureFields = job.attrs.failedAt
192+
&& job.attrs.failedAt === job.attrs.lastFinishedAt;
185193

186194
const {
187195
_id,
@@ -197,20 +205,20 @@ agenda.on("complete", async (job) => {
197205
...rest
198206
} = job.attrs;
199207

200-
return db.collection("_jobs").insertOne({
208+
return db.collection('_jobs').insertOne({
201209
...(keepFailureFields ? { failedAt, failReason, failCount } : {}),
202210
...rest,
203-
type: "normal",
211+
type: 'normal',
204212
});
205213
});
206214

207215
async function graceful() {
208-
logger.info("Gracefully stopping agenda");
216+
logger.info('Gracefully stopping agenda');
209217
await agenda.stop();
210218
process.exit(0);
211219
}
212220

213-
process.on("SIGTERM", graceful);
214-
process.on("SIGINT", graceful);
221+
process.on('SIGTERM', graceful);
222+
process.on('SIGINT', graceful);
215223

216224
export default agenda;
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
export const sendMattermostNotification = async (job) => {
2+
const { message } = job.attrs.data;
3+
const MATTERMOST_WEBHOOK_URL = process.env.MM_WEBHOOK_URL;
4+
const MATTERMOST_CHANNEL = process.env.MM_CHANNEL;
5+
const { BOT_ICON_URL } = process.env;
6+
7+
if (!MATTERMOST_WEBHOOK_URL || !MATTERMOST_CHANNEL) return;
8+
9+
try {
10+
await fetch(MATTERMOST_WEBHOOK_URL, {
11+
method: 'POST',
12+
headers: { 'Content-Type': 'application/json' },
13+
body: JSON.stringify({
14+
channel: MATTERMOST_CHANNEL,
15+
text: message,
16+
username: 'Bot-Anic le robot paysagiste',
17+
icon_url: BOT_ICON_URL,
18+
}),
19+
});
20+
} catch (error) {
21+
// eslint-disable-next-line no-console
22+
console.error('Error sending Mattermost notification', error);
23+
}
24+
};

0 commit comments

Comments
 (0)