This commit is contained in:
@@ -59,6 +59,7 @@ import { getUserChatSettingsDocument } from '@/api/userChatSettings'
|
|||||||
import type { UserChatSettingsDocument } from '@hereconnect/types'
|
import type { UserChatSettingsDocument } from '@hereconnect/types'
|
||||||
import { isNotFoundError } from '@/api/PouchDB'
|
import { isNotFoundError } from '@/api/PouchDB'
|
||||||
import { saveUserChatSettings } from '@/api/userChatSettings'
|
import { saveUserChatSettings } from '@/api/userChatSettings'
|
||||||
|
import { getQrCodeDocument } from '@/api/qrCode'
|
||||||
|
|
||||||
// Проверки iOS и запуска из главного экрана
|
// Проверки iOS и запуска из главного экрана
|
||||||
const isIOS = computed(
|
const isIOS = computed(
|
||||||
@@ -95,18 +96,16 @@ async function requestNotificationPermission() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const registration = await navigator.serviceWorker.ready
|
const registration = await navigator.serviceWorker.ready
|
||||||
let subscription: PushSubscription | null = null
|
const subscription = await registration.pushManager
|
||||||
|
.subscribe(await subscribeOptionsPromise)
|
||||||
try {
|
.catch(async (error) => {
|
||||||
subscription = await registration.pushManager.subscribe(await subscribeOptionsPromise)
|
const oldSubscription = await registration.pushManager.getSubscription()
|
||||||
} catch (error) {
|
if (!oldSubscription) {
|
||||||
subscription = await registration.pushManager.getSubscription()
|
|
||||||
if (!subscription) {
|
|
||||||
throw error
|
throw error
|
||||||
}
|
}
|
||||||
await subscription.unsubscribe()
|
await oldSubscription.unsubscribe()
|
||||||
subscription = await registration.pushManager.subscribe(await subscribeOptionsPromise)
|
return registration.pushManager.subscribe(await subscribeOptionsPromise)
|
||||||
}
|
})
|
||||||
|
|
||||||
return saveWebPushSubscription(subscription)
|
return saveWebPushSubscription(subscription)
|
||||||
}
|
}
|
||||||
@@ -161,7 +160,12 @@ const { isPending, isError, error, mutate } = useMutation({
|
|||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
if (!isNotFoundError(error)) throw error
|
if (!isNotFoundError(error)) throw error
|
||||||
})
|
})
|
||||||
if (chatSettingsDocument && chatSettingsDocument.is_push_notification_enabled) {
|
if (
|
||||||
|
(chatSettingsDocument && chatSettingsDocument.is_push_notification_enabled) ||
|
||||||
|
(!chatSettingsDocument &&
|
||||||
|
user_chat_role === 'owner' &&
|
||||||
|
(await getQrCodeDocument(qr_code_uri)).messageDeliveryMethod === 'webPush')
|
||||||
|
) {
|
||||||
const [subscription, subscriptionDocument] = await Promise.all([
|
const [subscription, subscriptionDocument] = await Promise.all([
|
||||||
getPushSubscription(),
|
getPushSubscription(),
|
||||||
getWebPushSubscriptionDocument().catch((error) => {
|
getWebPushSubscriptionDocument().catch((error) => {
|
||||||
|
|||||||
@@ -78,7 +78,10 @@ async function requestNotificationPermission() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const applicationServerKeyPromise = getVapidPublicKey()
|
const subscribeOptionsPromise = getVapidPublicKey().then((applicationServerKey) => ({
|
||||||
|
userVisibleOnly: true,
|
||||||
|
applicationServerKey,
|
||||||
|
}))
|
||||||
|
|
||||||
const permission = await Notification.requestPermission()
|
const permission = await Notification.requestPermission()
|
||||||
if (permission !== 'granted') {
|
if (permission !== 'granted') {
|
||||||
@@ -87,9 +90,15 @@ async function requestNotificationPermission() {
|
|||||||
|
|
||||||
const registration = await navigator.serviceWorker.ready
|
const registration = await navigator.serviceWorker.ready
|
||||||
|
|
||||||
const subscription = await registration.pushManager.subscribe({
|
const subscription = await registration.pushManager
|
||||||
userVisibleOnly: true,
|
.subscribe(await subscribeOptionsPromise)
|
||||||
applicationServerKey: await applicationServerKeyPromise,
|
.catch(async (error) => {
|
||||||
|
const oldSubscription = await registration.pushManager.getSubscription()
|
||||||
|
if (!oldSubscription) {
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
await oldSubscription.unsubscribe()
|
||||||
|
return registration.pushManager.subscribe(await subscribeOptionsPromise)
|
||||||
})
|
})
|
||||||
|
|
||||||
const webPushSubscriptionDoc = await saveWebPushSubscription(subscription)
|
const webPushSubscriptionDoc = await saveWebPushSubscription(subscription)
|
||||||
|
|||||||
@@ -2,7 +2,13 @@
|
|||||||
"name": "@hereconnect/types",
|
"name": "@hereconnect/types",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"main": "index.ts",
|
"main": "index.ts",
|
||||||
"types": "index.ts",
|
"types": "./dist/index.d.ts",
|
||||||
|
"exports": {
|
||||||
|
".": {
|
||||||
|
"import": "./dist/index.d.ts",
|
||||||
|
"default": "./dist/index.d.ts"
|
||||||
|
}
|
||||||
|
},
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "tsc"
|
"build": "tsc"
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import webpush from "web-push";
|
import webpush from "web-push";
|
||||||
import PouchDB from "./PouchDB";
|
import PouchDB from "./PouchDB";
|
||||||
|
import { ServerSettingsDocument } from "@hereconnect/types";
|
||||||
|
|
||||||
if (!process.env.VAPID_SUBJECT) {
|
if (!process.env.VAPID_SUBJECT) {
|
||||||
throw new Error("VAPID_SUBJECT env is empty!");
|
throw new Error("VAPID_SUBJECT env is empty!");
|
||||||
@@ -7,7 +8,10 @@ if (!process.env.VAPID_SUBJECT) {
|
|||||||
|
|
||||||
const vapidKeys = webpush.generateVAPIDKeys();
|
const vapidKeys = webpush.generateVAPIDKeys();
|
||||||
|
|
||||||
await new PouchDB(`${process.env.API_URL}/server_settings`, {
|
await new PouchDB<ServerSettingsDocument>(
|
||||||
|
`${process.env.API_URL}/server_settings`,
|
||||||
|
{ skip_setup: true },
|
||||||
|
).put({
|
||||||
_id: "server_settings:message_delivery_method_web_push_vapid",
|
_id: "server_settings:message_delivery_method_web_push_vapid",
|
||||||
type: "server_settings",
|
type: "server_settings",
|
||||||
name: "message_delivery_method_web_push_vapid",
|
name: "message_delivery_method_web_push_vapid",
|
||||||
@@ -15,6 +19,7 @@ await new PouchDB(`${process.env.API_URL}/server_settings`, {
|
|||||||
subject: process.env.VAPID_SUBJECT,
|
subject: process.env.VAPID_SUBJECT,
|
||||||
keys: vapidKeys,
|
keys: vapidKeys,
|
||||||
},
|
},
|
||||||
|
created_at: new Date().toISOString(),
|
||||||
});
|
});
|
||||||
|
|
||||||
await new PouchDB(`${process.env.API_URL}/public_settings`, {
|
await new PouchDB(`${process.env.API_URL}/public_settings`, {
|
||||||
@@ -24,6 +29,7 @@ await new PouchDB(`${process.env.API_URL}/public_settings`, {
|
|||||||
type: "public_settings",
|
type: "public_settings",
|
||||||
name: "message_delivery_method_web_push_vapid_public_key",
|
name: "message_delivery_method_web_push_vapid_public_key",
|
||||||
value: vapidKeys.publicKey,
|
value: vapidKeys.publicKey,
|
||||||
|
created_at: new Date().toISOString(),
|
||||||
});
|
});
|
||||||
|
|
||||||
if (process.env.GCM_API_KEY) {
|
if (process.env.GCM_API_KEY) {
|
||||||
@@ -34,5 +40,6 @@ if (process.env.GCM_API_KEY) {
|
|||||||
type: "server_settings",
|
type: "server_settings",
|
||||||
name: "message_delivery_method_web_push_gcm_api_key",
|
name: "message_delivery_method_web_push_gcm_api_key",
|
||||||
value: process.env.GCM_API_KEY,
|
value: process.env.GCM_API_KEY,
|
||||||
|
created_at: new Date().toISOString(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ const start = async () => {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
if (msgDoc.from === "guest") {
|
if (msgDoc.from === "guest") {
|
||||||
|
console.log("FROM GUEST");
|
||||||
// send message to owner
|
// send message to owner
|
||||||
const qrDoc = await qrDb.get(`qr_code:${msgDoc.qr_code_uri}`);
|
const qrDoc = await qrDb.get(`qr_code:${msgDoc.qr_code_uri}`);
|
||||||
if (qrDoc.messageDeliveryMethod !== "webPush") {
|
if (qrDoc.messageDeliveryMethod !== "webPush") {
|
||||||
@@ -69,19 +70,37 @@ const start = async () => {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { rows } = await webPushSubscriptionsDb.allDocs({
|
const [{ rows: pushSubscriptionRows }, { rows: userChatSettingsRows }] =
|
||||||
|
await Promise.all([
|
||||||
|
webPushSubscriptionsDb.allDocs({
|
||||||
startkey: `web_push_subscription:${qrDoc.user_uuid}:`,
|
startkey: `web_push_subscription:${qrDoc.user_uuid}:`,
|
||||||
endkey: `web_push_subscription:${qrDoc.user_uuid}:\uffff`,
|
endkey: `web_push_subscription:${qrDoc.user_uuid}:\uffff`,
|
||||||
include_docs: true,
|
include_docs: true,
|
||||||
});
|
}),
|
||||||
|
|
||||||
if (rows.length === 0) {
|
userChatSettingsDb.allDocs({
|
||||||
console.log("NO SUBSCRIPTIONS");
|
startkey: `user_chat_settings:${msgDoc.qr_code_uri}:${msgDoc.chat}:owner:`,
|
||||||
} else {
|
endkey: `user_chat_settings:${msgDoc.qr_code_uri}:${msgDoc.chat}:owner:\uffff`,
|
||||||
console.log(`sending to ${rows.length} devices`);
|
include_docs: true,
|
||||||
|
}),
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (
|
||||||
|
userChatSettingsRows.some(
|
||||||
|
(row) => row.doc!.is_push_notification_enabled === false,
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
console.log("push notifications is disabled");
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const row of rows) {
|
if (pushSubscriptionRows.length === 0) {
|
||||||
|
console.log("NO SUBSCRIPTIONS");
|
||||||
|
} else {
|
||||||
|
console.log(`sending to ${pushSubscriptionRows.length} devices`);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const row of pushSubscriptionRows) {
|
||||||
try {
|
try {
|
||||||
const subscription = row.doc!.subscription;
|
const subscription = row.doc!.subscription;
|
||||||
const topic = `chat-${msgDoc.qr_code_uri}-${msgDoc.chat}`;
|
const topic = `chat-${msgDoc.qr_code_uri}-${msgDoc.chat}`;
|
||||||
@@ -138,10 +157,11 @@ const start = async () => {
|
|||||||
);
|
);
|
||||||
for (const { doc: userChatSettingDoc } of userChatSettingsRows) {
|
for (const { doc: userChatSettingDoc } of userChatSettingsRows) {
|
||||||
if (!userChatSettingDoc) {
|
if (!userChatSettingDoc) {
|
||||||
|
console.log("push notification has not been configured");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!userChatSettingDoc.is_push_notification_enabled) {
|
if (!userChatSettingDoc.is_push_notification_enabled) {
|
||||||
console.log("PUSH NOTIFICATION DISABLED");
|
console.log("push notification is disabled");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,56 +173,56 @@ const start = async () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (subscriptionRows.length === 0) {
|
if (subscriptionRows.length === 0) {
|
||||||
console.log("NO SUBSCRIPTIONS");
|
console.log("no subscriptions");
|
||||||
} else {
|
} else {
|
||||||
console.log(`sending to ${subscriptionRows.length} devices`);
|
console.log(`sending to ${subscriptionRows.length} devices`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// for (const row of subscriptionRows) {
|
for (const row of subscriptionRows) {
|
||||||
// try {
|
try {
|
||||||
// const subscription = row.doc!.subscription;
|
const subscription = row.doc!.subscription;
|
||||||
// const topic = `chat-${msgDoc.qr_code_uri}-${msgDoc.chat}`;
|
const topic = `chat-${msgDoc.qr_code_uri}-${msgDoc.chat}`;
|
||||||
// const timestamp = new Date(msgDoc.created_at).getTime();
|
const timestamp = new Date(msgDoc.created_at).getTime();
|
||||||
// const tag = `${topic}-${(timestamp - new Date(qrDoc.created_at).getTime()).toString(36)}`;
|
const tag = `${topic}-${(timestamp - new Date(qrDoc.created_at).getTime()).toString(36)}`;
|
||||||
//
|
|
||||||
// const title = limitStringLengthWithEllipsis(
|
const title = limitStringLengthWithEllipsis(
|
||||||
// `${qrDoc.name}: новое сообщение`,
|
`Новое сообщение`,
|
||||||
// 53,
|
53,
|
||||||
// );
|
);
|
||||||
// const body = limitStringLengthWithEllipsis(msgDoc.body, 470);
|
const body = limitStringLengthWithEllipsis(msgDoc.body, 470);
|
||||||
//
|
|
||||||
// const options: NotificationOptions & { timestamp: number } = {
|
const options: NotificationOptions & { timestamp: number } = {
|
||||||
// icon: "/images/qr-code-logo-200x200.jpg",
|
icon: "/images/qr-code-logo-200x200.jpg",
|
||||||
// body,
|
body,
|
||||||
// tag,
|
tag,
|
||||||
// requireInteraction: true,
|
requireInteraction: true,
|
||||||
// timestamp,
|
timestamp,
|
||||||
// data: {
|
data: {
|
||||||
// url: `/manage/${msgDoc.qr_code_uri}/chat/${msgDoc.chat}`,
|
url: `/manage/${msgDoc.qr_code_uri}/chat/${msgDoc.chat}`,
|
||||||
// payload: { tag },
|
payload: { tag },
|
||||||
// },
|
},
|
||||||
// } as const;
|
} as const;
|
||||||
//
|
|
||||||
// await webpush.sendNotification(
|
await webpush.sendNotification(
|
||||||
// subscription,
|
subscription,
|
||||||
// JSON.stringify({
|
JSON.stringify({
|
||||||
// type: "notification",
|
type: "notification",
|
||||||
// notification: {
|
notification: {
|
||||||
// title,
|
title,
|
||||||
// options,
|
options,
|
||||||
// },
|
},
|
||||||
// }),
|
}),
|
||||||
// {
|
{
|
||||||
// urgency: "high",
|
urgency: "high",
|
||||||
// topic,
|
topic,
|
||||||
// },
|
},
|
||||||
// );
|
);
|
||||||
// } catch (error) {
|
} catch (error) {
|
||||||
// console.error(
|
console.error(
|
||||||
// `Error sending notification to ${row.id} - ${JSON.stringify(error)}`,
|
`Error sending notification to ${row.id} - ${JSON.stringify(error)}`,
|
||||||
// );
|
);
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"target": "ES2020",
|
"target": "ESNext",
|
||||||
"module": "ESNext",
|
"module": "ESNext",
|
||||||
"outDir": "./dist",
|
"outDir": "./dist",
|
||||||
"rootDir": "./src",
|
"rootDir": "./src",
|
||||||
|
|||||||
Reference in New Issue
Block a user