درس تطبيقي حول الترميز: إنشاء عميل للإشعارات الفورية

Kate Jeffreys
Kate Jeffreys
Kayce Basques
Kayce Basques

يوضّح لك هذا الدرس التطبيقي حول الترميز خطوة بخطوة كيفية إنشاء برنامج للإشعارات الفورية. في نهاية الدرس التطبيقي حول الترميز، سيكون لديك برنامج عميل يمكنه:

  • يتم الاشتراك في خدمة الإشعارات الفورية للمستخدم.
  • يتلقّى هذا الإذن الرسائل الفورية ويعرضها كإشعارات.
  • لإلغاء اشتراك المستخدم في الإشعارات الفورية

يركّز هذا الدرس التطبيقي حول الترميز على مساعدتك في التعلّم من خلال الممارسة، ولا يتناول المفاهيم كثيرًا. يمكنك الاطّلاع على طريقة عمل الإشعارات الفورية للتعرّف على مفاهيم الإشعارات الفورية.

رمز الخادم لهذا الدرس التطبيقي حول الترميز مكتمل. ستنفّذ العميل فقط في هذا الدرس التطبيقي حول الترميز. للتعرّف على كيفية تنفيذ خادم إشعارات فورية، يمكنك الاطّلاع على الدرس التطبيقي حول الترميز: إنشاء خادم إشعارات فورية.

توافُق المتصفح

من المعروف أنّ هذا الدرس التطبيقي حول الترميز يعمل مع مجموعات أنظمة التشغيل والمتصفّحات التالية:

  • ‫Windows: متصفّح Chrome وEdge
  • نظام التشغيل macOS: متصفّح Chrome وFirefox
  • ‫Android: متصفّح Chrome وFirefox

من المعروف أنّ هذا الدرس التطبيقي حول الترميز لا يعمل مع أنظمة التشغيل التالية (أو مجموعات أنظمة التشغيل والمتصفّحات):

  • نظام التشغيل macOS: ‏ Brave وEdge وSafari
  • iOS

الإعداد

إعداد المصادقة

قبل أن تتمكّن من تشغيل الإشعارات الفورية، عليك إعداد الخادم والعميل باستخدام مفاتيح المصادقة. يُرجى الاطّلاع على مقالة توقيع طلبات بروتوكول الإشعارات الفورية على الويب لمعرفة السبب. عادةً ما يتم تخزين البيانات السرية في ملف .env، مثل هذا الملف.

VAPID_PUBLIC_KEY="BKiwTvD9HA…"
VAPID_PRIVATE_KEY="4mXG9jBUaU…"
VAPID_SUBJECT="mailto:test@test.test"
  1. فتح "public/index.js"
  2. استبدِل VAPID_PUBLIC_KEY_VALUE_HERE بقيمة مفتاحك العام.

تسجيل مشغّل خدمات

يحتاج العميل إلى مشغّل خدمات لتلقّي الإشعارات وعرضها. من الأفضل تسجيل مشغّل الخدمات في أقرب وقت ممكن. يمكنك الاطّلاع على تلقّي الرسائل الفورية وعرضها كإشعارات لمزيد من المعلومات.

  1. استبدِل التعليق // TODO add startup logic here بالرمز التالي:

    if ('serviceWorker' in navigator && 'PushManager' in window) {
      navigator.serviceWorker.register('./service-worker.js').then(serviceWorkerRegistration => {
        console.info('Service worker was registered.');
        console.info({serviceWorkerRegistration});
      }).catch(error => {
        console.error('An error occurred while registering the service worker.');
        console.error(error);
      });
      subscribeButton.disabled = false;
    } else {
      console.error('Browser does not support service workers or push messages.');
    }
    
    subscribeButton.addEventListener('click', subscribeButtonHandler);
    unsubscribeButton.addEventListener('click', unsubscribeButtonHandler);
    
  2. في Chrome، افتح وحدة تحكّم "أدوات مطوّري البرامج".

  3. من المفترض أن تظهر لك الرسالة Service worker was registered. مسجَّلة في وحدة التحكّم.

طلب إذن إرسال الإشعارات الفورية

يجب ألا تطلب أبدًا إذنًا لإرسال إشعارات فورية عند تحميل الصفحة. بدلاً من ذلك، يجب أن تسأل واجهة المستخدم عما إذا كان يريد تلقّي إشعارات فورية. بعد أن يؤكّد المستخدمون موافقتهم صراحةً (من خلال النقر على زر مثلاً)، يمكنك بدء العملية الرسمية للحصول على إذن إرسال الإشعارات الفورية من المتصفّح.

  1. في public/index.js، استبدِل التعليق // TODO في subscribeButtonHandler() بالرمز التالي:

    // Prevent the user from clicking the subscribe button multiple times.
    subscribeButton.disabled = true;
    const result = await Notification.requestPermission();
    if (result === 'denied') {
      console.error('The user explicitly denied the permission request.');
      return;
    }
    if (result === 'granted') {
      console.info('The user accepted the permission request.');
    }
    
  2. ارجع إلى علامة تبويب التطبيق وانقر على Subscribe to push (الاشتراك في الإشعارات الفورية). سيسألك المتصفح أو نظام التشغيل عما إذا كنت تريد السماح للموقع الإلكتروني بإرسال إشعارات فورية إليك.

  3. اختَر السماح (أو العبارة المكافئة التي يستخدمها المتصفّح أو نظام التشغيل). في وحدة التحكّم، من المفترض أن تظهر لك رسالة تشير إلى ما إذا تم قبول الطلب أو رفضه.

الاشتراك في الإشعارات الفورية

تتضمن عملية الاشتراك التفاعل مع خدمة ويب يتحكّم فيها مورّد المتصفّح، وتُعرف باسم خدمة الإشعارات الفورية. بعد الحصول على معلومات الاشتراك في الإشعارات الفورية، يجب إرسالها إلى خادم ليخزّنها في قاعدة بيانات على المدى الطويل.

  1. أضِف الرمز المميّز التالي إلى subscribeButtonHandler():

    subscribeButton.disabled = true;
    const result = await Notification.requestPermission();
    if (result === 'denied') {
      console.error('The user explicitly denied the permission request.');
      return;
    }
    if (result === 'granted') {
      console.info('The user accepted the permission request.');
    }
    const registration = await navigator.serviceWorker.getRegistration();
    const subscribed = await registration.pushManager.getSubscription();
    if (subscribed) {
      console.info('User is already subscribed.');
      notifyMeButton.disabled = false;
      unsubscribeButton.disabled = false;
      return;
    }
    const subscription = await registration.pushManager.subscribe({
      userVisibleOnly: true,
      applicationServerKey: urlB64ToUint8Array(VAPID_PUBLIC_KEY)
    });
    notifyMeButton.disabled = false;
    fetch('/add-subscription', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(subscription)
    });
    

يجب أن يكون الخيار userVisibleOnly هو true. قد يكون من الممكن يومًا ما إرسال الرسائل بدون عرض إشعارات مرئية للمستخدم (الإشعارات الفورية الصامتة)، ولكن المتصفّحات لا تسمح بهذه الميزة بسبب مخاوف متعلقة بالخصوصية.

تعتمد قيمة applicationServerKey على دالة خدمية تحوّل سلسلة base64 إلى Uint8Array. تُستخدَم هذه القيمة للمصادقة بين الخادم وخدمة الإشعارات الفورية.

إلغاء الاشتراك في الإشعارات الفورية

بعد أن يشترك المستخدم في الإشعارات الفورية، يجب أن توفّر واجهة المستخدم طريقة لإلغاء الاشتراك في حال غيّر المستخدم رأيه ولم يعُد يريد تلقّي الإشعارات الفورية.

  • استبدِل التعليق // TODO في unsubscribeButtonHandler() بالرمز التالي:
const registration = await navigator.serviceWorker.getRegistration();
const subscription = await registration.pushManager.getSubscription();
fetch('/remove-subscription', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({endpoint: subscription.endpoint})
});
const unsubscribed = await subscription.unsubscribe();
if (unsubscribed) {
  console.info('Successfully unsubscribed from push notifications.');
  unsubscribeButton.disabled = true;
  subscribeButton.disabled = false;
  notifyMeButton.disabled = true;
}

تلقّي رسالة فورية وعرضها كإشعار

كما ذكرنا سابقًا، تحتاج إلى مشغّل خدمات للتعامل مع استلام وعرض الرسائل التي تم إرسالها إلى العميل من الخادم الخاص بك. يمكنك الاطّلاع على تلقّي الرسائل الفورية وعرضها كإشعارات لمزيد من التفاصيل.

  1. افتح public/service-worker.js واستبدِل التعليق // TODO في معالج الأحداث push الخاص بـ Service Worker بالرمز التالي:

    let data = event.data.json();
    const image = 'logo.png';
    const options = {
      body: data.options.body,
      icon: image
    }
    self.registration.showNotification(
      data.title,
      options
    );
    
  2. ارجع إلى علامة تبويب التطبيق.

  3. انقر على إرسال إشعار إليّ. من المفترض أن تتلقّى إشعارًا فوريًا.

  4. افتح عنوان URL لعلامة تبويب تطبيقك في المتصفّحات المتوافقة الأخرى. اتّبِع خطوات سير عمل الاشتراك، ثم انقر على إرسال إشعار إلى الجميع. من المفترض أن تتلقّى الإشعار الفوري نفسه في كلّ منها.

يمكنك تخصيص الإشعار بطرق عديدة. يمكنك الاطّلاع على مَعلمات ServiceWorkerRegistration.showNotification() لمزيد من المعلومات.

فتح عنوان URL عندما ينقر مستخدم على إشعار

في الواقع، من المحتمل أن تستخدم الإشعار كطريقة لإعادة جذب المستخدم وحثه على زيارة موقعك. لإجراء ذلك، عليك ضبط مشغّل الخدمات بشكل أكبر.

  1. استبدِل التعليق // TODO في معالج الأحداث notificationclick الخاص ببرنامج الخدمة بالرمز التالي:

    event.notification.close();
    event.waitUntil(self.clients.openWindow('https://web.dev'));
    
  2. ارجع إلى علامة تبويب التطبيق، وأرسل لنفسك إشعارًا آخر، ثم انقر فوق الإشعار. من المفترض أن يفتح المتصفّح علامة تبويب جديدة ويحمّل https://web.dev.

الخطوات التالية