Web push kitaplıklarıyla mesaj gönderme

Matt Gaunt

Web push ile çalışırken yaşanan sorunlardan biri, push mesajı tetikleme işleminin son derece biraz tereddüt eder. Bir uygulamanın push mesajı tetiklemek için push mesajına POST isteğinde bulunması gerekir. web push sonrası hizmet protokolüne bakın. Tüm reklam öğelerinde VAPID kullanmanız gerekir. (diğer adıyla uygulama sunucusu anahtarları) için bir değer atanabilir uygulamanız bir kullanıcıya mesaj gönderebilir. Push mesajıyla veri göndermek için verilerin şu şekilde olması gerekir: şifrelenmiş ve belirli üstbilgiler Tarayıcının iletinin şifresini doğru şekilde çözebilmesi için eklenmesi gerekir.

Push tetiklemeyle ilgili temel sorun, bir sorunla karşılaşırsanız bunu teşhis etmenin zor olmasıdır. düşünmesi gerekir. Bu durum, zaman içinde ve daha kapsamlı tarayıcı desteğiyle iyileşiyor, ancak kolay değil. Örneğin, Bu nedenle, şifreleme, biçimlendirme ve push mesajınızın tetiklenmesini sağlar.

Kütüphanelerin neler yaptığı konusunda gerçekten bilgi edinmek istiyorsanız göreceğiz. Şimdilik abonelikleri yönetmeye ve mevcut web push kitaplığını kullanarak push isteklerinde bulunun.

Bu bölümde webpush düğümünü kullanacağız. kitaplığı'nda bulabilirsiniz. Diğer dillerde farklılıklar olacaktır birbirlerine benzemeyecektir. Düğüm'e bakıyoruz çünkü JavaScript'i ve erişilebilir hale getirebilirsiniz.

Aşağıdaki adımları inceleyeceğiz:

  1. Arka ucumuza abonelik gönderip kaydedin.
  2. Kayıtlı abonelikleri alın ve bir push mesajı tetikleyin.

Abonelikler kaydediliyor

PushSubscription'ların veritabanından kaydedilmesi ve sorgulanması seçenekleriniz vardır, ancak yine de web sitenizin sunucu veya bir örnek verelim.

Demo web sayfasında PushSubscription, basit bir POST isteği yapılarak arka ucumuza gönderilir:

function sendSubscriptionToBackEnd(subscription) {
  return fetch('/api/save-subscription/', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify(subscription),
  })
    .then(function (response) {
      if (!response.ok) {
        throw new Error('Bad status code from server.');
      }

      return response.json();
    })
    .then(function (responseData) {
      if (!(responseData.data && responseData.data.success)) {
        throw new Error('Bad response from server.');
      }
    });
}

Demomuzdaki Ekspres sunucusunda /api/save-subscription/ uç nokta:

app.post('/api/save-subscription/', function (req, res) {

Bu rotada aboneliği, yalnızca isteğin tamam olduğundan ve dolu olmadığından emin olmak için doğrularız çöp:

const isValidSaveRequest = (req, res) => {
  // Check the request body has at least an endpoint.
  if (!req.body || !req.body.endpoint) {
    // Not a valid subscription.
    res.status(400);
    res.setHeader('Content-Type', 'application/json');
    res.send(
      JSON.stringify({
        error: {
          id: 'no-endpoint',
          message: 'Subscription must have an endpoint.',
        },
      }),
    );
    return false;
  }
  return true;
};
.

Abonelik geçerliyse kaydedip uygun bir JSON yanıtı:

return saveSubscriptionToDatabase(req.body)
  .then(function (subscriptionId) {
    res.setHeader('Content-Type', 'application/json');
    res.send(JSON.stringify({data: {success: true}}));
  })
  .catch(function (err) {
    res.status(500);
    res.setHeader('Content-Type', 'application/json');
    res.send(
      JSON.stringify({
        error: {
          id: 'unable-to-save-subscription',
          message:
            'The subscription was received but we were unable to save it to our database.',
        },
      }),
    );
  });

Bu demo, abonelikleri depolamak için nedb yöntemini kullanır. Bu basit bir dosya tabanlı veritabanıdır ancak dilediğiniz veritabanını kullanabilirsiniz. Bunu yalnızca kurulum gerektirmez. Üretim için daha güvenilir bir platform kullanmak istersiniz. (Genelde iyi bir eski MySQL'i kullanmaya devam edin.)

function saveSubscriptionToDatabase(subscription) {
  return new Promise(function (resolve, reject) {
    db.insert(subscription, function (err, newDoc) {
      if (err) {
        reject(err);
        return;
      }

      resolve(newDoc._id);
    });
  });
}

Push mesajı gönderme

Push mesajı göndermek söz konusu olduğunda, nihayetinde gönderme sürecini tetiklemek için ve kullanıcılara mesaj göndermeye devam ediyor. Yaygın bir yaklaşım, bir yönetici sayfası oluşturmaktır: push mesajını yapılandırıp tetikleyin. Fakat yerel olarak veya herhangi bir yerde çalışacak şekilde PushSubscription listesine erişip kodu çalıştırmanıza olanak tanıyan diğer bir yaklaşımdır. push mesajını tetikleyin.

Demomuzda "yönetici beğenisi" vardır aktarmanızı sağlayan bir sayfadır. Bu sadece bir demo olduğundan herkese açık sayfa.

Demonun çalışması için gereken her adımı anlatacağım. Bunlar bebek olacak adımları uygulayın.

Kullanıcı aboneliğinden bahsettiğimizde, applicationServerKey subscribe() seçenek. Arka uçta bu özel anahtara ihtiyacımız olacak.

Demoda, bu değerler Node uygulamamıza aşağıdaki şekilde ekleniyor (sıkıcı kod biliyorum ama sadece istiyorum unutmayın):

const vapidKeys = {
  publicKey:
    'BEl62iUYgUivxIkv69yViEuiBIa-Ib9-SkvMeAtA3LFgDzkrxZJjSgSnfckjBJuBkr3qBUYIHBQFLXYp5Nksh8U',
  privateKey: 'UUxI4O8-FbRouAevSmBQ6o18hgE4nSG3qwvJTfKc-ls',
};

Şimdi, Node sunucumuz için web-push modülünü yüklememiz gerekiyor:

npm install web-push --save

Ardından, Node komut dosyamızda web-push modülünün kullanılmasını zorunlu kılarız Örneğin:

const webpush = require('web-push');

Artık web-push modülünü kullanmaya başlayabiliriz. Öncelikle web-push modülüne, Google'ın uygulama sunucusu anahtarlarımıza da bakabilirsiniz. (VAPID anahtarı olarak da anıldığını unutmayın, çünkü bakın.)

const vapidKeys = {
  publicKey:
    'BEl62iUYgUivxIkv69yViEuiBIa-Ib9-SkvMeAtA3LFgDzkrxZJjSgSnfckjBJuBkr3qBUYIHBQFLXYp5Nksh8U',
  privateKey: 'UUxI4O8-FbRouAevSmBQ6o18hgE4nSG3qwvJTfKc-ls',
};

webpush.setVapidDetails(
  'mailto:web-push-book@gauntface.com',
  vapidKeys.publicKey,
  vapidKeys.privateKey,
);

Ayrıca, bir "mailto:" dize. Bu dizenin bir URL veya mailto olması gerekir e-posta adresi. Bu bilgiler aslında bu paketin bir parçası olarak web push hizmetine aktarma isteğini işlemesi gerekir. Bunun nedeni, bir web push hizmetinin Google tarafından sağlayan bazı bilgiler vardır.

Artık web-push modülü kullanıma hazır ve sonraki adım bir push mesajı tetiklemektir.

Demo, push mesajlarını tetiklemek için rol amaçlı yönetici panelini kullanır.

Yönetici sayfasının ekran görüntüsü.

"Push Mesajını Tetikleyici"yi tıklama düğmesi, /api/trigger-push-msg/ adresine bir POST isteği gönderir, Bu, arka ucumuzun push mesajları göndermesi için bir sinyaldir. Böylece, rotayı ifade eder:

app.post('/api/trigger-push-msg/', function (req, res) {

Bu istek alındığında, veritabanından abonelikleri alırız ve her biri için bir push mesajı tetikleriz.

return getSubscriptionsFromDatabase().then(function (subscriptions) {
  let promiseChain = Promise.resolve();

  for (let i = 0; i < subscriptions.length; i++) {
    const subscription = subscriptions[i];
    promiseChain = promiseChain.then(() => {
      return triggerPushMsg(subscription, dataToSend);
    });
  }

  return promiseChain;
});

Böylece triggerPushMsg() işlevi, web aktarma kitaplığını kullanarak sağlanan aboneliktir.

const triggerPushMsg = function (subscription, dataToSend) {
  return webpush.sendNotification(subscription, dataToSend).catch((err) => {
    if (err.statusCode === 404 || err.statusCode === 410) {
      console.log('Subscription has expired or is no longer valid: ', err);
      return deleteSubscriptionFromDatabase(subscription._id);
    } else {
      throw err;
    }
  });
};

webpush.sendNotification() numaralı telefona yapılan arama, bir söz verecektir. Öğe vaat edilen mesaj başarıyla gönderildiğinden ve hiçbir şey yapmamız gerekmez. Vaat reddedilirse, PushSubscription öğesinin hâlâ kayıtlı olup olmadığı konusunda sizi bilgilendirir geçerli olup olmadığını kontrol edin.

Push hizmetinden gelen hatanın türünü belirlemek için durum koduna bakmak en iyisidir. Hata mesajları push hizmetleri arasında farklılık gösterir ve bazıları diğerlerine göre daha faydalıdır.

Bu örnekte, Google Etiket Yöneticisi'nin HTTP durum kodları olan 404 ve 410 "Bulunamadı" ve "Gitti". Bunlardan birini alırsak aboneliğin süresi dolmuş demektir. veya artık geçerli değil. Bu senaryolarda abonelikleri veritabanımızdan kaldırmamız gerekir.

Başka bir hata olması durumunda yalnızca throw err. Böylece, triggerPushMsg() ret.

Bir sonraki bölümde, web push bildirimlerini incelediğimizde diğer durum kodlarından bazılarını ele alacağız. daha ayrıntılı değineceğiz.

Abonelikler arasında döngü oluşturduktan sonra bir JSON yanıtı döndürmemiz gerekir.

.then(() => {
res.setHeader('Content-Type', 'application/json');
    res.send(JSON.stringify({ data: { success: true } }));
})
.catch(function(err) {
res.status(500);
res.setHeader('Content-Type', 'application/json');
res.send(JSON.stringify({
    error: {
    id: 'unable-to-send-messages',
    message: `We were unable to send messages to all subscriptions : ` +
        `'${err.message}'`
    }
}));
});

Temel uygulama adımlarını ele aldık:

  1. Web sayfamızdan arka ucumuza abonelik göndermek için bir API oluşturun Böylece verileri bir veritabanına kaydedebilir.
  2. Push mesajlarının gönderilmesini tetikleyecek bir API oluşturun (bu örnekte görünen yönetici panelinden çağrılan API) girin.
  3. Tüm abonelikleri arka ucumuzdan al ve web push'u kullanarak her aboneliğe mesaj gönderin. kitaplıklar.

Arka ucunuzdan (Düğüm, PHP, Python vb.) bağımsız olarak, push uygulama adımları şunlardır: aynı olmasını sağlar.

Sonraki soruda, bu web aktarma kitaplıkları bize tam olarak ne yapacak?

Yakında gidilecek yerler

Kod laboratuvarları