ИТ развој

Web Push Notifications - How to Create an Independent Service

Веб-пуш известувања - Како да креирате независна услуга

Вовед

Веб-пуш известувањата станаа суштинска алатка за ангажирање на корисниците над традиционалните граници на веб-локации и апликации. Бизнисите и програмерите обично се потпираат на услуги од трети страни, како што се OneSignal или Firebase Cloud Messaging, за да се справат со сложеноста на испраќањето известувања. Сепак, овие надворешни услуги често воведуваат зависности, грижи за приватноста или ограничувања во прилагодувањето.

Оваа објава на блог претставува детално, чекор-по-чекор упатство за создавање на независна услуга за веб-пуш известувања користејќи ја библиотеката minishlink/web-push. Ќе ја користиме оваа PHP библиотека за да интегрираме веб-пуш известувања директно во рамките CodeIgniter 4 (CI4) и Laravel, овозможувајќи целосно автономна, приспособлива и систем за известување фокусиран на приватноста.

До крајот на овој водич, ќе разберете како да изградите и да управувате со сигурна независна услуга за пуш известувања што не се потпира на никакви надворешни провајдери или платформи како OneSignal, давајќи ви целосна контрола над вашата инфраструктура за известувања.

Зошто да изберете независна услуга за веб-пуш известувања?

Пред да се нурнеме во имплементацијата, да разгледаме зошто изградбата на независна услуга за известување е примамлива опција:

  • Нула зависност од услуги од трети страни: Избегнете прекини, промени во цените или промени во политиката што можат да ги нарушат вашите известувања.
  • Целосна контрола на приватноста на податоците: Претплатата на корисниците и податоците за известувањата остануваат на вашите сопствени сервери, намалувајќи го изложеноста на податоците од трети страни.
  • Приспособливост: Прилагодете ја вашата логика за известување, закажувањето и форматирањето на содржината точно на вашите деловни потреби без ограничувања.
  • Ефикасност на трошоците: Без потпирање на платени нивоа или модели на цени базирани на корисници вообичаени со надворешни услуги.
  • Лесна интеграција со постоечката инфраструктура на backend: Директно интегрирајте се со вашите бази на податоци и логика во Laravel или CI4, рационализирајќи го развојот и одржувањето.

Додека услугите како OneSignal го поедноставуваат процесот за почетници или мали тимови, тимовите кои ја ценат приватноста, независноста и напредните прилагодувања ќе најдат самостојно хостирано решение супериорно.

Започнување: Градење на сопствената услуга со minishlink/web-push

PHP библиотеката minishlink/web-push е камен-темелник на нашата независна услуга. Тоа е зрела, добро документирана алатка која се справува со сложеноста на протоколот за веб-пуш, вклучувајќи VAPID автентикација, шифрирање на корисни оптоварувања и управување со претплата.

Чекор 1: Поставување на вашата развојна средина

Прво, уверете се дека имате работна PHP околина со инсталиран Composer и или Laravel или CodeIgniter 4 правилно конфигурирани.

  • PHP 7.4 или повисока.
  • Composer за управување со зависности.
  • Laravel 8+ или CodeIgniter 4 инсталиран во вашата папка со проекти.

Продолжете да ја инсталирате библиотеката преку Composer:

composer require minishlink/web-push

Чекор 2: Генерирање на VAPID клучови

VAPID (Voluntary Application Server Identification) клучевите се суштински акредитиви за автентикација на вашиот сервер со услугите за пуш на прелистувачите, овозможувајќи доверливи и безбедни пуш пораки.

Генерирајте ги вашите VAPID клучеви користејќи го вградениот помошник во пакетот:

php vendor/bin/web-push generate:vapid

Командата излегува јавен и приватен пар клуч. Овие клучеви мора да бидат безбедно складирани; јавниот клуч ќе се сподели со клиентите, а приватниот клуч останува доверлив на вашиот сервер.

Чекор 3: Имплементирајте складирање на претплата на страна на серверот

За да испратите известувања, мора да ги складирате деталите за претплатата на клиентот, кои вклучуваат URL-адреса на крајна точка и криптографски клучеви генерирани во прелистувачот на клиентот.

  • Пример за шема на база на податоци:
CREATE TABLE subscriptions (
  id INT AUTO_INCREMENT PRIMARY KEY,
  endpoint TEXT NOT NULL,
  public_key VARCHAR(255),
  auth_token VARCHAR(255),
  content_encoding VARCHAR(50),
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

Складирајте објекти за претплата откако клиентите ќе се претплатат на frontend.

Чекор 4: Претплата од страна на клиентот во JavaScript

На frontend, имплементирајте логика за претплата користејќи ги Push API и Service Workers. Клучниот аспект овде е да се користи јавниот VAPID клуч за да се претплати прелистувачот на вашата услуга за пуш.

Примерок код:

const publicVapidKey = '';

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

async function send() {
  const register = await navigator.serviceWorker.register('/worker.js', {
    scope: '/'
  });

  const subscription = await register.pushManager.subscribe({
    userVisibleOnly: true,
    applicationServerKey: urlBase64ToUint8Array(publicVapidKey)
  });

  await fetch('/save-subscription', {
    method: 'POST',
    body: JSON.stringify(subscription),
    headers: {
      'content-type': 'application/json'
    }
  });

  console.log('Push subscription saved.');
}

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;
}

Овој JavaScript се справува со регистрацијата на работникот за услуги, претплатата на услугата за пуш и го испраќа објектот за претплата до backend рутата /save-subscription која ќе ја имплементирате понатаму.

Чекор 5: Backend крајна точка за зачувување на претплата

Во Laravel или CI4, креирајте API крајна точка која прима JSON за претплата од frontend и го складира во вашата база на податоци за претплати.

Пример за Laravel:

Route::post('/save-subscription', function (Request $request) {
    $data = $request->all();

    // Validate and sanitize input as needed
    DB::table('subscriptions')->updateOrInsert(
        ['endpoint' => $data['endpoint']],
        [
            'public_key' => $data['keys']['p256dh'],
            'auth_token' => $data['keys']['auth'],
            'content_encoding' => $request->header('Content-Encoding', 'aes128gcm')
        ]
    );

    return response()->json(['success' => true]);
});

Пример за CodeIgniter 4:

public function saveSubscription()
{
    $data = json_decode($this->request->getBody(), true);

    $db = \Config\Database::connect();
    $builder = $db->table('subscriptions');

    $existing = $builder->getWhere(['endpoint' => $data['endpoint']])->getRow();

    if ($existing) {
        $builder->where('id', $existing->id)->update([
            'public_key' => $data['keys']['p256dh'],
            'auth_token' => $data['keys']['auth'],
            'content_encoding' => $this->request->getHeaderLine('Content-Encoding') ?? 'aes128gcm',
        ]);
    } else {
        $builder->insert([
            'endpoint' => $data['endpoint'],
            'public_key' => $data['keys']['p256dh'],
            'auth_token' => $data['keys']['auth'],
            'content_encoding' => $this->request->getHeaderLine('Content-Encoding') ?? 'aes128gcm',
        ]);
    }

    return $this->response->setJSON(['success' => true]);
}

Чекор 6: Испраќање пуш известувања

Користете ја класата WebPush од библиотеката за да испраќате известувања до складираните претплати.

Пример за Laravel код за испраќање известување:

use Minishlink\WebPush\WebPush;
use Minishlink\WebPush\Subscription;

$vapid = [
  'VAPID' => [
    'subject' => 'mailto:[email protected]',
    'publicKey' => env('VAPID_PUBLIC_KEY'),
    'privateKey' => env('VAPID_PRIVATE_KEY'),
  ],
];

$webPush = new WebPush($vapid);

$subscriptions = DB::table('subscriptions')->get();

foreach ($subscriptions as $sub) {
    $subscription = Subscription::create([
        'endpoint' => $sub->endpoint,
        'publicKey' => $sub->public_key,
        'authToken' => $sub->auth_token,
        'contentEncoding' => $sub->content_encoding,
    ]);

    $report = $webPush->sendOneNotification(
        $subscription,
        json_encode([
            'title' => 'Hello',
            'body' => 'This is a test push notification',
            'icon' => '/icon.png',
        ])
    );

    if ($report->isSuccess()) {
        // Success handling (optional)
    } else {
        // Optional: remove expired subscriptions here
    }
}

CodeIgniter 4 Слична логика:

use Minishlink\WebPush\WebPush;
use Minishlink\WebPush\Subscription;

$vapid = [
  'VAPID' => [
    'subject' => 'mailto:[email protected]',
    'publicKey' => $_ENV['VAPID_PUBLIC_KEY'],
    'privateKey' => $_ENV['VAPID_PRIVATE_KEY'],
  ],
];

$webPush = new WebPush($vapid);

$db = \Config\Database::connect();
$subscriptions = $db->table('subscriptions')->get()->getResult();

foreach ($subscriptions as $sub) {
    $subscription = Subscription::create([
        'endpoint' => $sub->endpoint,
        'publicKey' => $sub->public_key,
        'authToken' => $sub->auth_token,
        'contentEncoding' => $sub->content_encoding,
    ]);

    $report = $webPush->sendOneNotification(
        $subscription,
        json_encode([
            'title' => 'Hello',
            'body' => 'This is a test push notification',
            'icon' => '/icon.png',
        ])
    );

    if ($report->isSuccess()) {
        // Handle success if needed
    } else {
        // Handle failures (e.g. remove invalid subscriptions)
    }
}

Чекор 7: Ракување со истечени или неважечки претплати

Протоколот за веб-пуш враќа повратни информации ако претплатата повеќе не е валидна. Важно е да ги отстраните таквите претплати од вашата база на податоци за да избегнете непотребни повторни обиди.

Проверете ги извештаите од sendOneNotification или процесот на сериско испраќање и избришете ги истечените крајни точки.

Напредни совети и најдобри практики

  • Користете сериско испраќање со методот WebPush::sendNotification за ефикасно ракување со повеќе известувања.
  • Имплементирајте логика за повторување и следење на неуспесите при пуш.
  • Обезбедете ги вашите крајни точки — заштитете ги рутите за зачувување на претплата и испраќање пуш со автентикација.
  • Подобрете ги вашите корисни оптоварувања со богати податоци и можности за интеракција како што се дејства и слики.
  • Следете го GDPR: осигурете се дека управувањето со претплатата ја почитува приватноста и согласноста на корисникот.

Заклучок

Создавањето независна услуга за веб-пуш известувања користејќи ја библиотеката minishlink/web-push ги овластува програмерите и бизнисите целосно да го контролираат нивниот систем за известување без да се потпираат на надворешни провајдери како OneSignal. Овој пристап ја подобрува приватноста, приспособувањето и економичноста.

Со следење на упатството чекор-по-чекор, можете да имплементирате робустен систем за пуш известувања во рамките на Laravel и CodeIgniter 4. Овој систем ви овозможува директно да управувате со претплати, да испраќате персонализирани известувања и да ги избегнувате ризиците поврзани со зависности од трети страни.

Изградбата на сопствена инфраструктура за пуш известувања е инвестиција во долгорочна доверливост и флексибилност, совршено усогласувајќи се со модерните цели за веб-развој на ангажирање на корисниците и заштита на приватноста.

Портрет на автор на блогот

Mihajlo

Јас сум Михајло — развивач воден од љубопитност, дисциплина и постојаната желба да создадам нешто значајно. Споделувам увиди, упатства и бесплатни услуги за да им помогнам на другите да ја поедностават својата работа и да растат во светот на софтверот и вештачката интелигенција кој постојано се развива.