send notification when sms arrives
This commit is contained in:
66
app/core/hooks/use-notifications.ts
Normal file
66
app/core/hooks/use-notifications.ts
Normal file
@ -0,0 +1,66 @@
|
||||
import { getConfig, useMutation } from "blitz";
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
import setNotificationSubscription from "../mutations/set-notification-subscription";
|
||||
|
||||
const { publicRuntimeConfig } = getConfig();
|
||||
|
||||
export default function useNotifications() {
|
||||
const isServiceWorkerSupported = "serviceWorker" in navigator;
|
||||
const [subscription, setSubscription] = useState<PushSubscription | null>(null);
|
||||
const [setNotificationSubscriptionMutation] = useMutation(setNotificationSubscription);
|
||||
|
||||
useEffect(() => {
|
||||
(async () => {
|
||||
if (!isServiceWorkerSupported) {
|
||||
return;
|
||||
}
|
||||
|
||||
const registration = await navigator.serviceWorker.ready;
|
||||
const subscription = await registration.pushManager.getSubscription();
|
||||
setSubscription(subscription);
|
||||
})();
|
||||
}, [isServiceWorkerSupported]);
|
||||
|
||||
async function subscribe() {
|
||||
if (!isServiceWorkerSupported) {
|
||||
return;
|
||||
}
|
||||
|
||||
const registration = await navigator.serviceWorker.ready;
|
||||
const subscription = await registration.pushManager.subscribe({
|
||||
userVisibleOnly: true,
|
||||
applicationServerKey: urlBase64ToUint8Array(publicRuntimeConfig.webPush.publicKey),
|
||||
});
|
||||
setSubscription(subscription);
|
||||
await setNotificationSubscriptionMutation({ subscription: subscription.toJSON() as any }); // TODO remove as any
|
||||
}
|
||||
|
||||
async function unsubscribe() {
|
||||
if (!isServiceWorkerSupported) {
|
||||
return;
|
||||
}
|
||||
|
||||
return subscription?.unsubscribe();
|
||||
}
|
||||
|
||||
return {
|
||||
isServiceWorkerSupported,
|
||||
subscription,
|
||||
subscribe,
|
||||
unsubscribe,
|
||||
};
|
||||
}
|
||||
|
||||
function urlBase64ToUint8Array(base64String: string) {
|
||||
const padding = "=".repeat((4 - (base64String.length % 4)) % 4);
|
||||
const base64 = (base64String + padding).replace(/\-/g, "+").replace(/_/g, "/");
|
||||
|
||||
const rawData = window.atob(base64);
|
||||
const outputArray = new Uint8Array(rawData.length);
|
||||
|
||||
for (let i = 0; i < rawData.length; ++i) {
|
||||
outputArray[i] = rawData.charCodeAt(i);
|
||||
}
|
||||
return outputArray;
|
||||
}
|
38
app/core/mutations/set-notification-subscription.ts
Normal file
38
app/core/mutations/set-notification-subscription.ts
Normal file
@ -0,0 +1,38 @@
|
||||
import { resolver } from "blitz";
|
||||
import { z } from "zod";
|
||||
|
||||
import db from "../../../db";
|
||||
import appLogger from "../../../integrations/logger";
|
||||
|
||||
const logger = appLogger.child({ mutation: "set-notification-subscription" });
|
||||
|
||||
const Body = z.object({
|
||||
subscription: z.object({
|
||||
endpoint: z.string(),
|
||||
expirationTime: z.number().nullable(),
|
||||
keys: z.object({
|
||||
p256dh: z.string(),
|
||||
auth: z.string(),
|
||||
}),
|
||||
}),
|
||||
});
|
||||
|
||||
export default resolver.pipe(resolver.zod(Body), resolver.authorize(), async ({ subscription }, context) => {
|
||||
const customerId = context.session.userId;
|
||||
try {
|
||||
await db.notificationSubscription.create({
|
||||
data: {
|
||||
customerId,
|
||||
endpoint: subscription.endpoint,
|
||||
expirationTime: subscription.expirationTime,
|
||||
keys_p256dh: subscription.keys.p256dh,
|
||||
keys_auth: subscription.keys.auth,
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
if (error.code !== "P2002") {
|
||||
logger.error(error);
|
||||
// we might want to `throw error`;
|
||||
}
|
||||
}
|
||||
});
|
Reference in New Issue
Block a user