Skip to content

Commit

Permalink
can send push notifications
Browse files Browse the repository at this point in the history
  • Loading branch information
arnaudambro committed Oct 2, 2024
1 parent 72c5511 commit 780eda7
Show file tree
Hide file tree
Showing 8 changed files with 183 additions and 11 deletions.
Binary file modified .yarn/install-state.gz
Binary file not shown.
12 changes: 12 additions & 0 deletions app/routes/api.action.fei.$fei_numero.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { getFeiByNumero } from "~/db/fei.server";
import { prisma } from "~/db/prisma.server";
import { getUserFromCookie } from "~/services/auth.server";
import { type ExtractLoaderData } from "~/services/extract-loader-data";
import sendNotificationToUser from "~/services/notifications.server";

export async function action(args: ActionFunctionArgs) {
const { request, params } = args;
Expand Down Expand Up @@ -246,6 +247,17 @@ export async function action(args: ActionFunctionArgs) {

const fei = await getFeiByNumero(savedFei.numero);

if (formData.has(Prisma.FeiScalarFieldEnum.fei_next_owner_user_id)) {
const nextOwner = await prisma.user.findUnique({
where: { id: formData.get(Prisma.FeiScalarFieldEnum.fei_next_owner_user_id) as string },
});
sendNotificationToUser({
user: nextOwner!,
title: "Vous avez une nouvelle FEI à traiter",
body: `${user.prenom} ${user.nom_de_famille} vous a attribué une nouvelle FEI. Rendez vous sur Zacharie pour la traiter.`,
});
}

if (formData.has("_redirect")) {
return redirect(formData.get("_redirect") as string);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { Stepper } from "@codegouvfr/react-dsfr/Stepper";
import { Checkbox } from "@codegouvfr/react-dsfr/Checkbox";
import { UserNotifications, UserRoles } from "@prisma/client";
import { getMostFreshUser } from "~/utils-offline/get-most-fresh-user";
import { usePush } from "~/sw/web-push-notifications";
import { usePush } from "~/sw/notifications";
import { setCacheItem } from "~/services/indexed-db.client";

export function meta() {
Expand Down
66 changes: 66 additions & 0 deletions app/services/notifications.server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import webpush from "web-push";
import { type User, UserNotifications } from "@prisma/client";
import * as Sentry from "@sentry/node";
import { sendEmail } from "./sendEmail";

type WebPushNotification = {
user: User;
body: string;
title: string;
img?: string;
};

export default async function sendNotificationToUser({
user,
body,
title,
img = "https://zacharie.beta.gouv.fr/favicon.svg",
}: WebPushNotification) {
if (user.notifications.includes(UserNotifications.PUSH)) {
if (user.web_push_tokens?.length) {
console.log("SENDING WEB PUSH NOTIFICATION", user.id);
for (const web_push_subscription of user.web_push_tokens) {
if (!web_push_subscription) {
continue;
}
if (web_push_subscription === "null") {
continue;
}
webpush
.sendNotification(JSON.parse(web_push_subscription), JSON.stringify({ title, body, img }), {
vapidDetails: {
subject: "mailto:contact@zacharie.beta.gouv.fr",
publicKey: process.env.VAPID_PUBLICKEY!,
privateKey: process.env.VAPID_PRIVATEKEY!,
},
urgency: "high",
})
.catch((error) => {
console.error("error in web push");
console.error(error, web_push_subscription, title, body, img);
Sentry.captureException(error, {
extra: { web_push_subscription, title, body, img },
});
});
}
}
// await prisma.user.update({
// where: { id: user.id },
// data: { badge_count: { increment: 1 } },
// });
}
if (user.notifications.includes(UserNotifications.EMAIL)) {
sendEmail({
subject: title,
text: body,
html: body,
from: "Zacharie <contact@zacharie.beta.gouv.fr>",
}).catch((error) => {
console.error("error in send email");
console.error(error);
Sentry.captureException(error, {
extra: { user, body, title, img },
});
});
}
}
8 changes: 2 additions & 6 deletions app/services/sendEmail.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,11 @@ export function sendEmail({
subject,
from = "contact@zacharie.beta.gouv.fr",
}: SendEmailProps) {
if (!process.env.TIPIMAIL_API_USER || !process.env.TIPIMAIL_API_KEY) {
console.error("TIPIMAIL_API_USER or TIPIMAIL_API_KEY not set");
return;
}
return fetch("https://api.tipimail.com/v1/messages/send", {
method: "POST",
headers: {
"X-Tipimail-ApiUser": process.env.TIPIMAIL_API_USER,
"X-Tipimail-ApiKey": process.env.TIPIMAIL_API_KEY,
"X-Tipimail-ApiUser": process.env.TIPIMAIL_API_USER!,
"X-Tipimail-ApiKey": process.env.TIPIMAIL_API_KEY!,
"Content-Type": "application/json",
},
body: JSON.stringify({
Expand Down
File renamed without changes.
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@
"react": "^18.3.1",
"react-dom": "^18.3.1",
"remix-utils": "^7.6.0",
"short-unique-id": "^5.2.0"
"short-unique-id": "^5.2.0",
"web-push": "^3.6.7"
},
"devDependencies": {
"@remix-run/dev": "^2.12.1",
Expand All @@ -52,6 +53,7 @@
"@types/react": "^18.3.10",
"@types/react-dom": "^18.3.0",
"@types/serviceworker": "^0.0.97",
"@types/web-push": "^3.6.3",
"@typescript-eslint/eslint-plugin": "^6.7.4",
"@typescript-eslint/parser": "^6.7.4",
"@vite-pwa/assets-generator": "^0.2.6",
Expand Down
102 changes: 99 additions & 3 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3857,6 +3857,15 @@ __metadata:
languageName: node
linkType: hard

"@types/web-push@npm:^3.6.3":
version: 3.6.3
resolution: "@types/web-push@npm:3.6.3"
dependencies:
"@types/node": "npm:*"
checksum: 10c0/c08830b5568939ef4d5b40a347893284feb94bbacaffdf105556a4285f565c2396be99d7a4e7fa98ce72ec8de061a04f0283961f90c809d19a0aeae322d8e50e
languageName: node
linkType: hard

"@typescript-eslint/eslint-plugin@npm:^6.7.4":
version: 6.21.0
resolution: "@typescript-eslint/eslint-plugin@npm:6.21.0"
Expand Down Expand Up @@ -4412,6 +4421,18 @@ __metadata:
languageName: node
linkType: hard

"asn1.js@npm:^5.3.0":
version: 5.4.1
resolution: "asn1.js@npm:5.4.1"
dependencies:
bn.js: "npm:^4.0.0"
inherits: "npm:^2.0.1"
minimalistic-assert: "npm:^1.0.0"
safer-buffer: "npm:^2.1.0"
checksum: 10c0/b577232fa6069cc52bb128e564002c62b2b1fe47f7137bdcd709c0b8495aa79cee0f8cc458a831b2d8675900eea0d05781b006be5e1aa4f0ae3577a73ec20324
languageName: node
linkType: hard

"ast-types-flow@npm:^0.0.8":
version: 0.0.8
resolution: "ast-types-flow@npm:0.0.8"
Expand Down Expand Up @@ -4625,6 +4646,13 @@ __metadata:
languageName: node
linkType: hard

"bn.js@npm:^4.0.0":
version: 4.12.0
resolution: "bn.js@npm:4.12.0"
checksum: 10c0/9736aaa317421b6b3ed038ff3d4491935a01419ac2d83ddcfebc5717385295fcfcf0c57311d90fe49926d0abbd7a9dbefdd8861e6129939177f7e67ebc645b21
languageName: node
linkType: hard

"body-parser@npm:1.20.3":
version: 1.20.3
resolution: "body-parser@npm:1.20.3"
Expand Down Expand Up @@ -4696,6 +4724,13 @@ __metadata:
languageName: node
linkType: hard

"buffer-equal-constant-time@npm:1.0.1":
version: 1.0.1
resolution: "buffer-equal-constant-time@npm:1.0.1"
checksum: 10c0/fb2294e64d23c573d0dd1f1e7a466c3e978fe94a4e0f8183937912ca374619773bef8e2aceb854129d2efecbbc515bbd0cc78d2734a3e3031edb0888531bbc8e
languageName: node
linkType: hard

"buffer-from@npm:^1.0.0":
version: 1.1.2
resolution: "buffer-from@npm:1.1.2"
Expand Down Expand Up @@ -5536,6 +5571,15 @@ __metadata:
languageName: node
linkType: hard

"ecdsa-sig-formatter@npm:1.0.11":
version: 1.0.11
resolution: "ecdsa-sig-formatter@npm:1.0.11"
dependencies:
safe-buffer: "npm:^5.0.1"
checksum: 10c0/ebfbf19d4b8be938f4dd4a83b8788385da353d63307ede301a9252f9f7f88672e76f2191618fd8edfc2f24679236064176fab0b78131b161ee73daa37125408c
languageName: node
linkType: hard

"ee-first@npm:1.1.1":
version: 1.1.1
resolution: "ee-first@npm:1.1.1"
Expand Down Expand Up @@ -7179,6 +7223,13 @@ __metadata:
languageName: node
linkType: hard

"http_ece@npm:1.2.0":
version: 1.2.0
resolution: "http_ece@npm:1.2.0"
checksum: 10c0/647edb7438a56e028acac8a598a685b9186497b0e30747a65889faa209fdde48d5b525da88e7fdcab2b0ce1840eba737f87fa57e96bfe967015d08759fab1771
languageName: node
linkType: hard

"https-proxy-agent@npm:^5.0.0":
version: 5.0.1
resolution: "https-proxy-agent@npm:5.0.1"
Expand All @@ -7189,7 +7240,7 @@ __metadata:
languageName: node
linkType: hard

"https-proxy-agent@npm:^7.0.1":
"https-proxy-agent@npm:^7.0.0, https-proxy-agent@npm:^7.0.1":
version: 7.0.5
resolution: "https-proxy-agent@npm:7.0.5"
dependencies:
Expand Down Expand Up @@ -8000,6 +8051,27 @@ __metadata:
languageName: node
linkType: hard

"jwa@npm:^2.0.0":
version: 2.0.0
resolution: "jwa@npm:2.0.0"
dependencies:
buffer-equal-constant-time: "npm:1.0.1"
ecdsa-sig-formatter: "npm:1.0.11"
safe-buffer: "npm:^5.0.1"
checksum: 10c0/6baab823b93c038ba1d2a9e531984dcadbc04e9eb98d171f4901b7a40d2be15961a359335de1671d78cb6d987f07cbe5d350d8143255977a889160c4d90fcc3c
languageName: node
linkType: hard

"jws@npm:^4.0.0":
version: 4.0.0
resolution: "jws@npm:4.0.0"
dependencies:
jwa: "npm:^2.0.0"
safe-buffer: "npm:^5.0.1"
checksum: 10c0/f1ca77ea5451e8dc5ee219cb7053b8a4f1254a79cb22417a2e1043c1eb8a569ae118c68f24d72a589e8a3dd1824697f47d6bd4fb4bebb93a3bdf53545e721661
languageName: node
linkType: hard

"keyv@npm:^4.5.3":
version: 4.5.4
resolution: "keyv@npm:4.5.4"
Expand Down Expand Up @@ -8835,6 +8907,13 @@ __metadata:
languageName: node
linkType: hard

"minimalistic-assert@npm:^1.0.0":
version: 1.0.1
resolution: "minimalistic-assert@npm:1.0.1"
checksum: 10c0/96730e5601cd31457f81a296f521eb56036e6f69133c0b18c13fe941109d53ad23a4204d946a0d638d7f3099482a0cec8c9bb6d642604612ce43ee536be3dddd
languageName: node
linkType: hard

"minimatch@npm:9.0.3":
version: 9.0.3
resolution: "minimatch@npm:9.0.3"
Expand Down Expand Up @@ -8880,7 +8959,7 @@ __metadata:
languageName: node
linkType: hard

"minimist@npm:^1.2.0, minimist@npm:^1.2.3, minimist@npm:^1.2.6":
"minimist@npm:^1.2.0, minimist@npm:^1.2.3, minimist@npm:^1.2.5, minimist@npm:^1.2.6":
version: 1.2.8
resolution: "minimist@npm:1.2.8"
checksum: 10c0/19d3fcdca050087b84c2029841a093691a91259a47def2f18222f41e7645a0b7c44ef4b40e88a1e58a40c84d2ef0ee6047c55594d298146d0eb3f6b737c20ce6
Expand Down Expand Up @@ -10822,7 +10901,7 @@ __metadata:
languageName: node
linkType: hard

"safer-buffer@npm:>= 2.1.2 < 3, safer-buffer@npm:>= 2.1.2 < 3.0.0":
"safer-buffer@npm:>= 2.1.2 < 3, safer-buffer@npm:>= 2.1.2 < 3.0.0, safer-buffer@npm:^2.1.0":
version: 2.1.2
resolution: "safer-buffer@npm:2.1.2"
checksum: 10c0/7e3c8b2e88a1841c9671094bbaeebd94448111dd90a81a1f606f3f67708a6ec57763b3b47f06da09fc6054193e0e6709e77325415dc8422b04497a8070fa02d4
Expand Down Expand Up @@ -12466,6 +12545,21 @@ __metadata:
languageName: node
linkType: hard

"web-push@npm:^3.6.7":
version: 3.6.7
resolution: "web-push@npm:3.6.7"
dependencies:
asn1.js: "npm:^5.3.0"
http_ece: "npm:1.2.0"
https-proxy-agent: "npm:^7.0.0"
jws: "npm:^4.0.0"
minimist: "npm:^1.2.5"
bin:
web-push: src/cli.js
checksum: 10c0/d6a90dfe12f938396d0bff4e211a73347c3d584591768f6e62d006b5426710b033bae196a39cf28114f14dc0443a714c24ada1528ec8f11dfa5cb92153643c96
languageName: node
linkType: hard

"web-streams-polyfill@npm:^3.1.1":
version: 3.3.3
resolution: "web-streams-polyfill@npm:3.3.3"
Expand Down Expand Up @@ -12938,6 +13032,7 @@ __metadata:
"@types/react": "npm:^18.3.10"
"@types/react-dom": "npm:^18.3.0"
"@types/serviceworker": "npm:^0.0.97"
"@types/web-push": "npm:^3.6.3"
"@typescript-eslint/eslint-plugin": "npm:^6.7.4"
"@typescript-eslint/parser": "npm:^6.7.4"
"@uidotdev/usehooks": "npm:^2.4.1"
Expand Down Expand Up @@ -12974,6 +13069,7 @@ __metadata:
vite: "npm:^5.1.0"
vite-plugin-pwa: "npm:^0.20.5"
vite-tsconfig-paths: "npm:^4.2.1"
web-push: "npm:^3.6.7"
workbox-cacheable-response: "npm:^7.1.0"
workbox-core: "npm:^7.1.0"
workbox-precaching: "npm:^7.1.0"
Expand Down

0 comments on commit 780eda7

Please sign in to comment.