add support GCM
Main daploy / deploy (push) Successful in 44s

This commit is contained in:
2024-11-25 22:58:10 +02:00
parent 1f85f23792
commit 16a0fa76de
7 changed files with 70 additions and 35 deletions
+1
View File
@@ -26,6 +26,7 @@ declare module 'vue' {
ExamplesSection: typeof import('./src/components/TheWelcome/ExamplesSection.vue')['default'] ExamplesSection: typeof import('./src/components/TheWelcome/ExamplesSection.vue')['default']
InputText: typeof import('primevue/inputtext')['default'] InputText: typeof import('primevue/inputtext')['default']
ManagePlacementInstructions: typeof import('./src/components/manage/ManagePlacementInstructions.vue')['default'] ManagePlacementInstructions: typeof import('./src/components/manage/ManagePlacementInstructions.vue')['default']
ProgressSpinner: typeof import('primevue/progressspinner')['default']
QueryRender: typeof import('./src/components/QueryRender.vue')['default'] QueryRender: typeof import('./src/components/QueryRender.vue')['default']
RadioButton: typeof import('primevue/radiobutton')['default'] RadioButton: typeof import('primevue/radiobutton')['default']
ReadContactInfo: typeof import('./src/components/read/ReadContactInfo.vue')['default'] ReadContactInfo: typeof import('./src/components/read/ReadContactInfo.vue')['default']
+2 -1
View File
@@ -16,5 +16,6 @@
], ],
"theme_color": "#ffffff", "theme_color": "#ffffff",
"background_color": "#ffffff", "background_color": "#ffffff",
"display": "standalone" "display": "standalone",
"gcm_sender_id": "822536580006"
} }
+8 -3
View File
@@ -8,6 +8,12 @@ self.addEventListener('install', (event) => {
// of event.waitUntil(); // of event.waitUntil();
}) })
self.addEventListener('activate', (event) => {
event.waitUntil(
clients.claim(), // Привязка нового сервис-воркера к текущим клиентам
)
})
self.addEventListener('push', (event) => { self.addEventListener('push', (event) => {
const data = event.data.json() const data = event.data.json()
console.log('Push событие получено:', data.type) console.log('Push событие получено:', data.type)
@@ -77,10 +83,9 @@ self.addEventListener('notificationclick', (event) => {
if (clients.openWindow) { if (clients.openWindow) {
console.log('новое окно', urlToOpen) console.log('новое окно', urlToOpen)
return clients.openWindow(urlToOpen).then((client) => { return clients.openWindow(urlToOpen).then((client) => {
if (client) { if (!client) {
return client.focus() console.log('новое окно не открылось')
} }
console.log('новое окно не открылось')
}) })
} }
}) })
@@ -1,7 +1,8 @@
<template> <template>
<div class="flex items-center gap-2"> <div class="flex items-center gap-2">
<i class="pi pi-spin pi-spinner" v-if="isLoading"></i> <div v-if="isLoading" class="w-5 h-5">
<ProgressSpinner style="width: 100%; height: 100%" strokeWidth="8" fill="transparent" />
</div>
<RadioButton <RadioButton
v-else v-else
v-model="model" v-model="model"
@@ -10,6 +11,7 @@
:value="method" :value="method"
@change="$emit('change', $event)" @change="$emit('change', $event)"
/> />
<label :for="method">{{ label }}</label> <label :for="method">{{ label }}</label>
</div> </div>
</template> </template>
@@ -1,5 +1,5 @@
<template> <template>
<CreateMessageDeliveryOption :isLoading="isLoading" :label :method v-model="model" /> <CreateMessageDeliveryOption :isLoading :label :method v-model="model" />
<!-- Ошибка разрешений --> <!-- Ошибка разрешений -->
<p v-if="isError && model === method" class="text-red-500 mb-2"> <p v-if="isError && model === method" class="text-red-500 mb-2">
@@ -44,6 +44,7 @@ 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.subscribe({
userVisibleOnly: true, userVisibleOnly: true,
applicationServerKey: await applicationServerKeyPromise, applicationServerKey: await applicationServerKeyPromise,
@@ -8,10 +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(`${process.env.API_URL}/server_settings`, {
skip_setup: true, _id: "server_settings:message_delivery_method_web_push_vapid",
}).put({ type: "server_settings",
_id: "server_settings:message_delivery_method_web_push:vapid", name: "message_delivery_method_web_push_vapid",
vapid: { value: {
subject: process.env.VAPID_SUBJECT, subject: process.env.VAPID_SUBJECT,
keys: vapidKeys, keys: vapidKeys,
}, },
@@ -25,3 +25,14 @@ await new PouchDB(`${process.env.API_URL}/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,
}); });
if (process.env.GCM_API_KEY) {
await new PouchDB(`${process.env.API_URL}/public_settings`, {
skip_setup: true,
}).put({
_id: "server_settings:message_delivery_method_web_push_gcm_api_key",
type: "server_settings",
name: "message_delivery_method_web_push_gcm_api_key",
value: process.env.GCM_API_KEY,
});
}
@@ -5,44 +5,54 @@ if (!process.env.API_URL) {
throw new Error(`env API_URL is not set`); throw new Error(`env API_URL is not set`);
} }
const settings = await new PouchDB(`${process.env.API_URL}/server_settings`, { const {
rows: [
{
doc: { value: vapidDetails },
},
{ doc: gcmApiSettingsDoc },
],
} = await new PouchDB(`${process.env.API_URL}/server_settings`, {
skip_setup: true, skip_setup: true,
}).get("server_settings:message_delivery_method_web_push:vapid"); }).allDocs({
keys: [
"server_settings:message_delivery_method_web_push_vapid",
"public_settings:message_delivery_method_web_push_gcm_api_key",
],
include_docs: true,
});
webpush.setVapidDetails( webpush.setVapidDetails(
settings.vapid.subject, vapidDetails.subject,
settings.vapid.keys.publicKey, vapidDetails.keys.publicKey,
settings.vapid.keys.privateKey, vapidDetails.keys.privateKey,
); );
if (gcmApiSettingsDoc) {
console.log(gcmApiSettingsDoc.value);
webpush.setGCMAPIKey(gcmApiSettingsDoc.value);
}
// optionally provide an identifier that the push service uses to coalesce notifications
const topic = "chat-6ilhxu-13trvu";
const notification = { const notification = {
type: "notification", type: "notification",
notification: { notification: {
title: "test", title: "test",
options: { options: {
icon: "/images/qr-code-logo-200x200.jpg", icon: "/images/qr-code-logo-200x200.jpg",
body: "Test push message from DevTools.", body: "Test push message from server.",
tag: "01936062-d10f-7f2f-8ae3-dd7f9fbc5c7f", tag: "01936062-d10f-7f2f-8ae3-dd7f9fbc5c7f",
vibrate: [200, 100, 200, 100, 200, 100, 200], requireInteraction: true,
data: {
url: "http://localhost:5173/chat/6ilhxu/13trvu",
payload: { tag: "01936062-d10f-7f2f-8ae3-dd7f9fbc5c7f" },
},
},
},
};
const notification2 = {
type: "notification",
notification: {
title: "test",
options: {
icon: "/images/qr-code-logo-200x200.jpg",
body: "Test push message from DevTools.",
tag: "01936062-d10f-7f2f-8ae3-dd7f9fbc5c7f",
// requireInteraction: true,
// silent: false, // silent: false,
// vibrate: [200, 100, 200, 100, 200, 100, 200], // vibrate: [200, 100, 200, 100, 200, 100, 200],
// actions: [
// {
// action: "open_url",
// title: "Открыть",
// },
// ],
data: { data: {
url: "/chat/6ilhxu/13trvu", url: "/chat/6ilhxu/13trvu",
payload: { tag: "01936062-d10f-7f2f-8ae3-dd7f9fbc5c7f" }, payload: { tag: "01936062-d10f-7f2f-8ae3-dd7f9fbc5c7f" },
@@ -72,6 +82,10 @@ const result = await Promise.allSettled(
await webpush.sendNotification( await webpush.sendNotification(
doc.subscription, doc.subscription,
JSON.stringify(notification), JSON.stringify(notification),
{
urgency: "high",
topic,
},
); );
console.log("sent ", doc._id); console.log("sent ", doc._id);
}), }),