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

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"
  • فتح "public/index.js"
  • استبدِل VAPID_PUBLIC_KEY_VALUE_HERE بقيمة مفتاحك العام.

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

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

  • استبدِل التعليق // TODO add startup logic here بالرمز التالي:
// 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);
  • اضغط على Control+Shift+J (أو Command+Option+J على أجهزة Mac) لفتح "أدوات مطوّلي البرامج".
  • انقر على علامة التبويب وحدة التحكم. من المفترض أن تظهر لك الرسالة Service worker was registered. التي تم تسجيلها في "وحدة التحكّم".

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

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

  • في public/index.js، استبدِل التعليق // TODO في subscribeButtonHandler() بالرمز التالي:
// TODO
// 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.');
}
  • ارجع إلى علامة تبويب التطبيق وانقر على الاشتراك في الإشعارات الفورية. من المحتمل أن يسألك المتصفّح أو نظام التشغيل عمّا إذا كنت تريد السماح للموقع الإلكتروني بإرسال إشعارات فورية إليك. انقر على سماح (أو أي عبارة مكافئة يستخدمها المتصفّح أو نظام التشغيل). في وحدة التحكّم، من المفترض أن تظهر رسالة تشير إلى ما إذا تم قبول الطلب أو رفضه.

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

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

  • أضِف الرمز المميز التالي إلى 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() بالرمز التالي:
// TODO
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;
}

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

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

  • افتح public/service-worker.js واستبدِل التعليق // TODO في معالج الأحداث push الخاص ببرنامج عامل الخدمة بالرمز التالي:
// TODO
let data = event.data.json();
const image = 'logo.png';
const options = {
  body: data.options.body,
  icon: image
}
self.registration.showNotification(
  data.title, 
  options
);
  • ارجع إلى علامة تبويب التطبيق.
  • انقر على إرسال إشعار إليّ. من المفترض أن تتلقّى إشعارًا فوريًا.
  • جرِّب فتح عنوان URL لعلامة تبويب تطبيقك على متصفّحات أخرى (أو حتى على أجهزة أخرى)، واتّبِع خطوات الاشتراك، ثم انقر على إرسال إشعار إلى الجميع. من المفترض أن تتلقّى الإشعار الفوري نفسه على جميع المتصفّحات التي اشتركت فيها. يمكنك الرجوع إلى مقالة توافق المتصفّح للاطّلاع على قائمة بمجموعات المتصفّح/نظام التشغيل التي من المعروف أنّها تعمل أو لا تعمل.

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

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

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

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

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