Eksperymentuję z powiadomieniami push wysyłanymi z aplikacji Node.js. Po niektórych samouczkach i przykładach mam teraz pracę Mini-Aplikacja.

To, co jest bardzo proste, gdy jest ładowany do przeglądarki, wystrzelono powiadomienie, a użytkownik widzi pojawienie się wiadomości.

Zasadniczo składa się z czterech plików: index.js, index.html, pracownik.js i klient.js.

Jako pierwszy eksperyment, chciałbym wdrożyć nieco bardziej wyrafinowane zachowanie.

Aplikacja powinna wystrzelić powiadomienie typu A, gdy zaczyna się (jak już działa), a następnie podpal powiadomienie typu B co 121 minut.

Czy to jest możliwe lub niemożliwe?

Jeśli jest to możliwe, jak mogę to zrobić?

W celach informacyjnych umieszczam tutaj dwa istotne pliki:

index.js :

const express = require('express'),
      webPush = require('web-push'),
      bodyParser = require('body-parser'),
      path = require('path');
const app = express();

app.use(express.static(path.join(__dirname, 'client')));
app.use(bodyParser.json());

const privateVapIdKey = process.env.privVapIdKey,
      publicVapIdKey = process.env.pubVapIdKey;

webPush.setVapidDetails(
    'mailto:myemail@example.com',
    publicVapIdKey,privateVapIdKey);

// Subscribe Route.
app.post('/subscribe',(req,res) => {
    const subscription = req.body; // Get Push Subscription Object.
    res.status(201).json({}); // Send 201. Resource created.

    // Do a lot of useful things ......
    .......
    // Create the PayLoad.
    const payload = JSON.stringify({
        title:'A big title!',
        ........
    });
    // Pass Object to sendNotification.
    webPush.sendNotification(subscription,payload).catch(err => console.error(err));
});

const port = 5003;

const PORT = process.env.PORT || port;
app.listen(PORT, () => console.log(`Listening on ${ PORT }`));

klient.js :

const publicVapIdKey = 'my-secret-3453754...pubVapIdKey';

// Chec for ServiceWorker.
if ('serviceWorker' in navigator) {
    send().catch(err => console.error(err));
}


// Register ServiceWorker, Register Push, Send Push.
async function send() {
    console.log("Registering ServiceWorker.");
    const register = await navigator.serviceWorker.register('/worker.js', {
        scope: "/"
    });
    console.log('ServiceWorker registered.');

    console.log("Registering Push.");
    //register.pushManager.uns
    const subscription = await register.pushManager.subscribe({
        userVisibleOnly: true,
        applicationServerKey: urlBase64ToUint8Array(publicVapIdKey)
    });
    console.log('Push registered.');

    console.log("Sending Push.");
    await fetch('/subscribe', {
        method: 'POST',
        body: JSON.stringify(subscription),
        headers: {
            'content-type': 'application/json'
        }
    });
    console.log('Push sent.');
}


function urlBase64ToUint8Array(base64String) {
    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;
}
0
Michel 3 czerwiec 2018, 12:05

3 odpowiedzi

Najlepsza odpowiedź

Prosty czas zdarzeń można osiągnąć za pomocą Settimeout i SetInterval:
https://nodejs.org/api /timers.html.
Pracują tak samo jak w ramach przeglądarki JavaScript.

Dla czegoś bardziej zaawansowanego, spróbuj Node-Cron

0
kosert 3 czerwiec 2018, 09:16

Aby móc wysyłać powiadomienia do punktu końcowego, potrzebujesz jej subskrypcji, więc musimy przechowywać subskrypcje klientów:

const subscriptions = [];

app.post('/subscribe',(req,res) => {
  const subscription = req.body;
  // FIXME: Validate subscription!!!
  subscriptions.push(subscription);
  res.status(201).json({});
  webPush.sendNotification(subscription, { title: "A" });
});

Teraz co 121 minut, przechodzimy przez wszystkie subskrypcje i dostarczamy naszą wiadomość B:

const MINS = 60 * 1000;

setInterval(() => {
  for(const subscription of subscriptions) {
     webPush.sendNotification(subscription, {title: "B" });
  }
}, 121 * MINS);

PS: Prawdopodobnie powinieneś również dodać punkt końcowy "wypisanie subskrypcji", jak w przeciwnym razie dostarczałbyś powiadomienia o martwe punkty końcowe nieco

0
Jonas Wilms 3 czerwiec 2018, 09:24

Jest to możliwe! , ale sugerowałbym, abyś użył Admin FCM W przypadku serwera strona bardziej najnowsza biblioteka niż Web-push i jest łatwiejsza do push powiadomienia.

//node.js serverside code 
const FCM = require("firebase-admin");
//fcm-push-notification.json is where all the configurations are
const serviceAccount = require("fcm-push-notification.json");
FCM.initializeApp({
    credential: SERVICE_ACCOUNT,
    databaseURL: DBURL
});
// In your Subscribe Route.
app.post('/subscribe',(req,res) => {
    FCM.messaging()
    .sendToDevice(
    DEVICE_TOKEN,
    {
        data: DATA,
        notification: {
            title: "A big title!",
            body: "HELLO PUSH!"
        }
    }
    )
    .then(res => {
        // do something here
    })
});

Oto pracownik serwisowy

// put firebase-messaging-sw.js service worker
// this is to get notified in the background when the tab is closed on not active 
(global => {
  importScripts("https://www.gstatic.com/firebasejs/4.8.1/firebase-app.js");
  importScripts(
    "https://www.gstatic.com/firebasejs/4.8.1/firebase-messaging.js"
  );
  firebase.initializeApp({
    messagingSenderId: SENDER_ID
  });
  const messaging = firebase.messaging();
  console.log("Service Worker started!");
  messaging.setBackgroundMessageHandler(payload => {
    console.log("Message received In background");
    // Customize notification here
    const notificationOptions = {
      body: "Background Message body.",
      icon: "/firebase-logo.png"
    };
    return global.registration.showNotification("TITLE", notificationOptions);
  });
})(self);

W twoim javascript.

//to get notified in forground just do this
import firebase from "firebase";

firebase.initializeApp(FCM_CONF);
let messaging = firebase.messaging();
messaging.usePublicVapidKey(VAPID_KEY);

messaging.onMessage(payload => {
    console.log("Message received from foreground ");
});

Wreszcie utwórz manifest.json

//create manifest.json with content like this
{
  "gcm_sender_id": SENDER_ID
}

I wystrzelić powiadomienie typu b typu b co 121 minut. Użyj czegoś takiego jak nr wieczoru

var later = require('later');
 var schedule = later.parse.text('every 121 min');

 var timer = later.setTimeout(() => {
  // fired every 121 minutes
    FCM.messaging()
    .sendToDevice(
    DEVICE_TOKEN,
    {
        data: DATA,
        notification: {
            title: "A big title!",
            body: "HELLO PUSH!"
        }
    }
    )
 }, schedule);
0
ShegaMike 3 czerwiec 2018, 09:30