1. סקירה כללית
הודעות פוש הן דרך פשוטה ויעילה לעודד משתמשים לחזור לאפליקציה. ב-Codelab הזה, תלמדו איך להוסיף התראות פוש לאפליקציית האינטרנט שלכם.
מה תלמדו
- איך מפעילים או מבטלים את ההרשמה של משתמש לקבלת הודעות פוש
- איך לטפל בהודעות פוש נכנסות
- איך מציגים התראה
- איך מגיבים לקליקים על התראות
מה תצטרכו
- Chrome מגרסה 52 ואילך
- Web Server for Chrome או שרת אינטרנט משלכם
- כלי לעריכת טקסט
- ידע בסיסי ב-HTML, CSS, JavaScript ובכלי פיתוח ל-Chrome
- קוד לדוגמה (ראו את השלב הראשון).
2. להגדרה
הורדת קוד לדוגמה
יש שתי דרכים להשיג את קוד לדוגמה של ה-Codelab הזה:
- משכפלים את מאגר Git:
git clone https://github.com/GoogleChrome/push-notifications.git
- מורידים את קובץ ה-ZIP:
אם מורידים את המקור כקובץ ZIP, אחרי שמחלצים אותו מקבלים תיקיית בסיס push-notifications-master.
התקנה ואימות של שרת האינטרנט
אפשר להשתמש בשרת אינטרנט משלכם, אבל ה-codelab הזה מיועד לעבודה עם אפליקציית שרת האינטרנט של Chrome. אם עדיין לא התקנתם את האפליקציה הזו, תוכלו להוריד אותה מחנות האינטרנט של Chrome:
אחרי שמתקינים את אפליקציית Web Server for Chrome, לוחצים על קיצור הדרך Apps בסרגל הסימניות:

בחלון Apps (אפליקציות), לוחצים על הסמל Web Server (שרת אינטרנט):

בשלב הבא תופיע תיבת הדו-שיח הזו, שבה אפשר להגדיר את שרת האינטרנט המקומי:

לוחצים על הלחצן בחירת תיקייה ובוחרים בתיקייה app בתוך התיקייה push-notifications שהורדתם. כך תוכלו להציג את העבודה שלכם באמצעות כתובת ה-URL שמופיעה בקטע כתובות URL של שרת אינטרנט בתיבת הדו-שיח.
בקטע Options (אפשרויות), מסמנים את התיבה לצד Automatically show index.html (הצגה אוטומטית של index.html), כמו שמוצג בהמשך:

לאחר מכן עוצרים ומפעילים מחדש את השרת על ידי העברת המתג Web Server: STARTED ימינה ואז שמאלה.

לוחצים על כתובת ה-URL של שרת האינטרנט כדי להיכנס לאתר בדפדפן האינטרנט. אמור להופיע דף שנראה כך – אבל יכול להיות שבגרסה שלכם כתובת ה-IP תהיה 127.0.0.1:8887:

עדכון תמיד של ה-service worker
במהלך הפיתוח, כדאי לוודא ש-service worker תמיד מעודכן וכולל את השינויים האחרונים.
כדי להגדיר את זה ב-Chrome:
- עוברים לכרטיסייה Push Codelab.
- פתיחת כלי הפיתוח: Ctrl-Shift-I ב-Windows וב-Linux, Cmd-Option-I ב-macOS.
- בוחרים בלוח Application (אפליקציה), לוחצים על הכרטיסייה Service Workers (ספקי שירות) ומסמנים את התיבה Update on Reload (עדכון בעת טעינה מחדש). כשהתיבה הזו מסומנת, קובץ השירות מתעדכן בכפייה בכל פעם שהדף נטען מחדש.

3. רישום קובץ שירות (service worker)
בספרייה app, שימו לב שיש קובץ ריק בשם sw.js. הקובץ הזה יהיה ה-service worker שלכם. בשלב הזה, אפשר להשאיר את השדה הזה ריק. תוסיפו לו קוד בהמשך.
קודם צריך לרשום את הקובץ הזה כ-service worker.
הדף app/index.html נטען scripts/main.js. אתם רושמים את ה-service worker בקובץ ה-JavaScript הזה.
מוסיפים את הקוד הבא אל scripts/main.js:
if ('serviceWorker' in navigator && 'PushManager' in window) {
console.log('Service Worker and Push are supported');
navigator.serviceWorker.register('sw.js')
.then(function(swReg) {
console.log('Service Worker is registered', swReg);
swRegistration = swReg;
})
.catch(function(error) {
console.error('Service Worker Error', error);
});
} else {
console.warn('Push messaging is not supported');
pushButton.textContent = 'Push Not Supported';
}
הקוד הזה בודק אם הדפדפן תומך ב-service workers ובשליחת הודעות Push. אם הם נתמכים, הקוד רושם את קובץ sw.js.
רוצים לנסות?
כדי לבדוק את השינויים, מרעננים את הכרטיסייה Push Codelab בדפדפן.
בודקים את המסוף בכלי הפיתוח ל-Chrome אם מופיע בו Service Worker is registered message, כמו בדוגמה הבאה:

קבלת מפתחות שרת של אפליקציות
כדי לעבוד עם ה-codelab הזה, צריך ליצור מפתחות של שרת האפליקציה. אפשר לעשות את זה באתר הנלווה: web-push-codelab.glitch.me
כאן אפשר ליצור זוג מפתחות פרטיים וציבוריים.

מעתיקים את המפתח הציבורי אל scripts/main.js ומחליפים את הערך <Your Public Key>:
const applicationServerPublicKey = '<Your Public Key>';
חשוב: אסור להוסיף את המפתח הפרטי לאפליקציית האינטרנט!
4. הגדרת מצב התחלתי
בשלב הזה, לחצן הפעלה של אפליקציית האינטרנט מושבת ואי אפשר ללחוץ עליו. הסיבה לכך היא שמומלץ להשבית את לחצן הדחיפה כברירת מחדל ולהפעיל אותו אחרי שמוודאים שהדפדפן תומך בהודעות דחיפה, ואחרי שבודקים אם המשתמש מנוי כרגע להודעות או לא.
תצטרכו ליצור שתי פונקציות ב-scripts/main.js:
-
initializeUI, כדי לבדוק אם המשתמש רשום כמנוי -
updateBtn, כדי להפעיל את הכפתור ולשנות את הטקסט בהתאם לשאלה אם המשתמש רשום למינוי או לא
מוסיפים פונקציה initializeUI ל-main.js כך:
function initializeUI() {
// Set the initial subscription value
swRegistration.pushManager.getSubscription()
.then(function(subscription) {
isSubscribed = !(subscription === null);
if (isSubscribed) {
console.log('User IS subscribed.');
} else {
console.log('User is NOT subscribed.');
}
updateBtn();
});
}
השיטה החדשה משתמשת ב-swRegistration מהשלב הקודם, מקבלת ממנו את המאפיין pushManager וקוראת את getSubscription().
pushManager. getSubscription() מחזירה הבטחה שמושלמת עם המינוי הנוכחי, אם קיים כזה. אחרת, הפונקציה מחזירה את הערך null. כך תוכלו לבדוק אם המשתמש כבר נרשם, להגדיר את הערך של isSubscribed ואז לקרוא ל-updateBtn() כדי לעדכן את הלחצן.
מוסיפים את הפונקציה updateBtn() אל main.js:
function updateBtn() {
if (isSubscribed) {
pushButton.textContent = 'Disable Push Messaging';
} else {
pushButton.textContent = 'Enable Push Messaging';
}
pushButton.disabled = false;
}
הפונקציה הזו מפעילה את הכפתור ומשנה את הטקסט שמופיע בו בהתאם למצב המינוי של המשתמש.
הדבר האחרון שצריך לעשות הוא להתקשר אל initializeUI() כש-Service Worker רשום ב-main.js:
navigator.serviceWorker.register('sw.js')
.then(function(swReg) {
console.log('Service Worker is registered', swReg);
swRegistration = swReg;
initializeUI();
})
רוצים לנסות?
מרעננים את הכרטיסייה Push Codelab. אפשר לראות שהלחצן Enable Push Messaging (הפעלת הודעות פוש) מופעל עכשיו (אפשר ללחוץ עליו) ומופיע User is NOT subscribed במסוף.

במהלך ההתקדמות בשאר שלבי ה-codelab הזה, תוכלו לראות את הטקסט של הלחצן משתנה בכל פעם שאתם נרשמים או מבטלים את המינוי.
5. רישום המשתמש
בשלב הזה, הכפתור Enable Push Messaging לא עושה הרבה. יחד נפתור את זה.
בפונקציה initializeUI(), מוסיפים מאזין לקליקים עבור הלחצן:
function initializeUI() {
pushButton.addEventListener('click', function() {
pushButton.disabled = true;
if (isSubscribed) {
// TODO: Unsubscribe user
} else {
subscribeUser();
}
});
// Set the initial subscription value
swRegistration.pushManager.getSubscription()
.then(function(subscription) {
isSubscribed = !(subscription === null);
updateSubscriptionOnServer(subscription);
if (isSubscribed) {
console.log('User IS subscribed.');
} else {
console.log('User is NOT subscribed.');
}
updateBtn();
});
}
כשהמשתמש לוחץ על הכפתור, משביתים אותו כדי לוודא שהמשתמש לא יוכל ללחוץ עליו פעם שנייה, כי יכול לעבור זמן עד שהמשתמש נרשם לקבלת הודעות פוש.
אחר כך מתקשרים אל subscribeUser() אם המשתמש לא מנוי כרגע. לשם כך, צריך להדביק את הקוד הבא ב-scripts/main.js:
function subscribeUser() {
const applicationServerKey = urlB64ToUint8Array(applicationServerPublicKey);
swRegistration.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: applicationServerKey
})
.then(function(subscription) {
console.log('User is subscribed.');
updateSubscriptionOnServer(subscription);
isSubscribed = true;
updateBtn();
})
.catch(function(error) {
console.error('Failed to subscribe the user: ', error);
updateBtn();
});
}
בואו נסביר מה הקוד הזה עושה ואיך הוא רושם את המשתמש לקבלת הודעות פוש.
קודם לוקחים את המפתח הציבורי של שרת האפליקציה, שהוא בקידוד Base64 בטוח לכתובות URL, וממירים אותו ל-UInt8Array, כי זה הקלט הצפוי של הקריאה subscribe(). הפונקציה urlB64ToUint8Array() נמצאת בראש scripts/main.js.
אחרי שממירים את הערך, מפעילים את השיטה subscribe() ב-pushManager של ה-service worker, ומעבירים את המפתח הציבורי של שרת האפליקציות ואת הערך userVisibleOnly: true.
const applicationServerKey = urlB64ToUint8Array(applicationServerPublicKey);
swRegistration.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: applicationServerKey
})
הפרמטר userVisibleOnly מבטיח שתציגו התראה בכל פעם שתישלח הודעת פוש. נכון לעכשיו, חובה לציין את הערך הזה והוא צריך להיות true.
הפעלת הפונקציה subscribe() מחזירה אובייקט promise שיתממש אחרי השלבים הבאים:
- המשתמש העניק הרשאה להצגת התראות.
- הדפדפן שלח בקשת רשת לשירות Push כדי לקבל את הנתונים שנדרשים ליצירת
PushSubscription.
אם הפעולות האלה יצליחו, ה-promise subscribe() יותאם עם PushSubscription. אם המשתמש לא מעניק הרשאה או אם יש בעיה כלשהי בהרשמת המשתמש, ההבטחה תידחה עם שגיאה. כך נראה שרשור ההבטחות ב-codelab:
swRegistration.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: applicationServerKey
})
.then(function(subscription) {
console.log('User is subscribed.');
updateSubscriptionOnServer(subscription);
isSubscribed = true;
updateBtn();
})
.catch(function(err) {
console.log('Failed to subscribe the user: ', err);
updateBtn();
});
במקרה כזה, תקבלו מינוי ותתייחסו למשתמש כמנוי, או שתקבלו שגיאה ותתעדו אותה במסוף. בשני התרחישים, קוראים ל-updateBtn() כדי לוודא שהכפתור מופעל מחדש ומוצג בו הטקסט המתאים.
באפליקציה אמיתית, הפונקציה updateSubscriptionOnServer() היא המקום שבו שולחים את נתוני המינוי לשרת עורפי, אבל ב-codelab פשוט מציגים את המינוי בממשק המשתמש. מוסיפים את הפונקציה הבאה ל-scripts/main.js:
function updateSubscriptionOnServer(subscription) {
// TODO: Send subscription to application server
const subscriptionJson = document.querySelector('.js-subscription-json');
const subscriptionDetails =
document.querySelector('.js-subscription-details');
if (subscription) {
subscriptionJson.textContent = JSON.stringify(subscription);
subscriptionDetails.classList.remove('is-invisible');
} else {
subscriptionDetails.classList.add('is-invisible');
}
}
רוצים לנסות?
עוברים לכרטיסייה Push Codelab, מרעננים את הדף ולוחצים על הלחצן. תופיע בקשת הרשאה כזו:

אם תעניקו את ההרשאה, תראו את User is subscribed מופיע ביומן במסוף. הטקסט של הלחצן ישתנה להשבתת הודעות פוש ותוכלו לראות את המינוי כנתוני JSON בתחתית הדף.

6. טיפול בדחיית הרשאה
דבר אחד שעדיין לא טיפלתם בו הוא מה קורה אם המשתמש חוסם את בקשת ההרשאה. צריך להתייחס לזה באופן ייחודי, כי אם המשתמש יחסום את ההרשאה, אפליקציית האינטרנט לא תוכל להציג שוב את בקשת ההרשאה ולא תוכל לרשום את המשתמש. צריך לפחות להשבית את לחצן הלחיצה כדי שהמשתמש יידע שאי אפשר להשתמש בו.
המקום המתאים לטפל בתרחיש הזה הוא בפונקציה updateBtn(). כל מה שצריך לעשות הוא לבדוק את הערך Notification.permission, כך:
function updateBtn() {
if (Notification.permission === 'denied') {
pushButton.textContent = 'Push Messaging Blocked';
pushButton.disabled = true;
updateSubscriptionOnServer(null);
return;
}
if (isSubscribed) {
pushButton.textContent = 'Disable Push Messaging';
} else {
pushButton.textContent = 'Enable Push Messaging';
}
pushButton.disabled = false;
}
אתם יודעים שאם ההרשאה היא denied, אי אפשר להוסיף את המשתמש למינוי ואין מה לעשות, ולכן הגישה הכי טובה היא להשבית את הלחצן באופן קבוע.
רוצים לנסות?
מכיוון שכבר הענקתם הרשאה לאפליקציית האינטרנט בשלב הקודם, אתם צריכים ללחוץ על i בתוך עיגול בסרגל כתובות ה-URL ולשנות את ההרשאה התראות לשימוש בהגדרת ברירת המחדל הגלובלית (בקשה).

אחרי שמשנים את ההגדרה הזו, מרעננים את הדף, לוחצים על הלחצן הפעלת הודעות פוש ובוחרים באפשרות חסימה בתיבת הדו-שיח של ההרשאות. הכפתור יושבת ויוצג בו הטקסט הודעות פוש חסומות.

בעקבות השינוי הזה, אפשר עכשיו לרשום את המשתמש למינוי, אחרי שטיפלתם בתרחישי ההרשאות האפשריים.
7. טיפול באירוע push
לפני שמסבירים איך לשלוח הודעת פוש מהקצה העורפי, צריך להבין מה קורה בפועל כשמשתמש רשום מקבל הודעת פוש.
כשמפעילים הודעת פוש, הדפדפן מקבל את הודעת הפוש, מזהה את ה-service worker שאליו היא מיועדת, מפעיל את ה-service worker ושולח אירוע פוש. צריך להאזין לאירוע הזה ולהציג התראה כתוצאה מכך.
מוסיפים את הקוד הבא לקובץ sw.js:
self.addEventListener('push', function(event) {
console.log('[Service Worker] Push Received.');
console.log(`[Service Worker] Push had this data: "${event.data.text()}"`);
const title = 'Push Codelab';
const options = {
body: 'Yay it works.',
icon: 'images/icon.png',
badge: 'images/badge.png'
};
event.waitUntil(self.registration.showNotification(title, options));
});
בואו נבחן את הקוד הזה. אתם מאזינים לאירועי push ב-service worker על ידי הוספת פונקציית event listener:
self.addEventListener('push', ... );
(אלא אם השתמשתם בעבר ב-Web Workers, סביר להניח ש-self חדש לכם. בקובץ service worker, self מפנה אל ה-service worker עצמו.)
כשמתקבלת הודעת פוש, מתבצעת קריאה ל-event listener, ואתם יוצרים התראה על ידי קריאה ל-showNotification() במאפיין registration של service worker. showNotification() מחייב title. אפשר גם להעביר לו אובייקט options כדי להגדיר הודעה בגוף, סמל ותג. (התג נמצא בשימוש רק ב-Android בזמן כתיבת המאמר הזה).
const title = 'Push Codelab';
const options = {
body: 'Yay it works.',
icon: 'images/icon.png',
badge: 'images/badge.png'
};
self.registration.showNotification(title, options);
הנושא האחרון שצריך להסביר לגבי הטיפול באירוע push הוא event.waitUntil(). השיטה הזו מקבלת אובייקט promise כדי לאפשר לדפדפן לשמור על פעילות של קובץ שירות (service worker) עד שאובייקט ה-promise שהועבר ימומש.
כדי להקל על ההבנה של הקוד שלמעלה, אפשר לשכתב אותו כך:
const notificationPromise = self.registration.showNotification(title, options);
event.waitUntil(notificationPromise);
אחרי שבדקתם את אירוע הדחיפה, בואו נבדוק אירוע דחיפה.
רוצים לנסות?
בעזרת טיפול באירועי Push ב-Service Worker, אפשר להפעיל אירוע Push מזויף כדי לבדוק מה קורה כשמתקבלת הודעה.
באפליקציית האינטרנט, נרשמים לקבלת הודעות פוש ומוודאים שרואים את User IS subscribed במסוף. בחלונית Application ב-DevTools, בכרטיסייה Service Workers, לוחצים על הלחצן Push:

אחרי שתלחצו על שליחה, תופיע התראה כזו:

הערה: אם השלב הזה לא עוזר, נסו לבטל את הרישום של קובץ השירות (service worker) באמצעות הקישור ביטול הרישום בחלונית Application (אפליקציה) בכלי הפיתוח, להמתין עד שקובץ השירות ייעצר ואז לטעון מחדש את הדף.
8. קליק על התראה
אם תלחצו על אחת מההתראות האלה, לא יקרה כלום. אפשר לטפל בקליקים על התראות על ידי האזנה לאירועי notificationclick ב-service worker.
כדי להתחיל, מוסיפים מאזין notificationclick ב-sw.js:
self.addEventListener('notificationclick', function(event) {
console.log('[Service Worker] Notification click received.');
event.notification.close();
event.waitUntil(
clients.openWindow('https://developers.google.com/web')
);
});
כשמשתמש לוחץ על ההתראה, מתבצעת קריאה ל-notificationclick event listener.
הקוד קודם סוגר את ההתראה שעליה לחצו:
event.notification.close();
לאחר מכן ייפתח חלון או כרטיסייה חדשים, וכתובת ה-URL https://developers.google.com/web תיטען. אפשר לשנות את ההגדרה הזו.
event.waitUntil(
clients.openWindow('https://developers.google.com/web/')
);
event.waitUntil() מוודא שהדפדפן לא יסיים את פעולת ה-service worker לפני שהחלון או הכרטיסייה החדשים יוצגו.
רוצים לנסות?
מנסים להפעיל שוב הודעת דחיפה בכלי הפיתוח ולוחצים על ההתראה. ההודעה תיסגר ותיפתח כרטיסייה חדשה.
9. שליחת הודעות פוש
ראיתם שאפליקציית האינטרנט שלכם יכולה להציג התראה באמצעות כלי הפיתוח, ובדקתם איך לסגור את ההתראה בלחיצה. השלב הבא הוא לשלוח הודעת פוש בפועל.
בדרך כלל, כדי לעשות את זה צריך לשלוח מינוי מדף אינטרנט אל ה-backend. הקצה העורפי יפעיל הודעת פוש על ידי ביצוע קריאה ל-API לנקודת הקצה במינוי.
הנושא הזה לא נכלל ב-codelab הזה, אבל אפשר להשתמש באתר הנלווה ( web-push-codelab.glitch.me) כדי להפעיל הודעת פוש בפועל. מדביקים את המינוי בתחתית הדף:

לאחר מכן מדביקים את הקישור הזה באזור הטקסט Subscription to Send To באתר הנלווה:

בקטע Text to Send (טקסט לשליחה), מוסיפים את המחרוזת שרוצים לשלוח עם הודעת הפוש.
לוחצים על הלחצן שליחת הודעת פוש.

אחרי כן אמורה להתקבל התראה. הטקסט שבו השתמשתם יתועד במסוף.

כך תוכלו לבדוק את השליחה והקבלה של נתונים, ולשנות את ההתראות בהתאם.
אפליקציית הליווי היא רק שרת צמתים שמשתמש בספריית ה-web-push כדי לשלוח הודעות. כדאי לעיין ב-web-push-libs org ב-GitHub כדי לראות אילו ספריות זמינות לשליחת הודעות פוש בשבילכם. הוא מטפל בהרבה פרטים כדי להפעיל הודעות פוש.
10. ביטול ההרשמה של המשתמש
הדבר היחיד שחסר הוא האפשרות לבטל את ההרשמה של משתמש לקבלת עדכונים. כדי לעשות את זה, צריך להתקשר אל unsubscribe() באמצעות PushSubscription.
חוזרים לקובץ scripts/main.js ומשנים את click listener ב-initializeUI() לקוד הבא:pushButton
pushButton.addEventListener('click', function() {
pushButton.disabled = true;
if (isSubscribed) {
unsubscribeUser();
} else {
subscribeUser();
}
});
שימו לב שאתם עומדים להפעיל פונקציה חדשה unsubscribeUser(). בפונקציה הזו מקבלים את המינוי הנוכחי ומפעילים עליו את unsubscribe(). מוסיפים את הקוד הבא אל scripts/main.js:
function unsubscribeUser() {
swRegistration.pushManager.getSubscription()
.then(function(subscription) {
if (subscription) {
return subscription.unsubscribe();
}
})
.catch(function(error) {
console.log('Error unsubscribing', error);
})
.then(function() {
updateSubscriptionOnServer(null);
console.log('User is unsubscribed.');
isSubscribed = false;
updateBtn();
});
}
בואו נסביר את הפונקציה הזו.
קודם כל, מקבלים את המינוי הנוכחי באמצעות קריאה ל-getSubscription():
swRegistration.pushManager.getSubscription()
הפונקציה מחזירה הבטחה שמושלמת עם PushSubscription אם הוא קיים, אחרת היא מחזירה null. אם יש מינוי, צריך להתקשר אל unsubscribe(), מה שהופך את PushSubscription ללא תקף.
swRegistration.pushManager.getSubscription()
.then(function(subscription) {
if (subscription) {
// TODO: Tell application server to delete subscription
return subscription.unsubscribe();
}
})
.catch(function(error) {
console.log('Error unsubscribing', error);
})
הקריאה ל-unsubscribe() מחזירה אובייקט promise, כי יכול להיות שיעבור זמן עד שהיא תושלם. מחזירים את ההבטחה הזו כדי ש-then() הבא בשרשרת יחכה עד ש-unsubscribe() יסיים. מוסיפים גם גורם מטפל בשגיאות למקרה שהקריאה ל-unsubscribe() תגרום לשגיאה. אחרי זה תוכלו לעדכן את ממשק המשתמש.
.then(function() {
updateSubscriptionOnServer(null);
console.log('User is unsubscribed.');
isSubscribed = false;
updateBtn();
})
רוצים לנסות?
אפשר ללחוץ על הפעלת הודעות פוש או על השבתת הודעות פוש באפליקציית האינטרנט, ויוצגו ביומנים פרטים על ההרשמה של המשתמש למינוי וביטול המינוי.

11. הסתיימה
כל הכבוד, סיימתם את ה-Codelab הזה!
ב-codelab הזה למדתם איך להוסיף התראות פוש לאפליקציית האינטרנט שלכם ולהתחיל להשתמש בהן. אם אתם רוצים לקבל מידע נוסף על האפשרויות של התראות באינטרנט, כדאי לעיין במסמכים האלה.
אם אתם רוצים להטמיע התראות פוש באתר שלכם, יכול להיות שתתעניינו בהוספת תמיכה בדפדפנים ישנים או בדפדפנים שלא עומדים בתקנים ומשתמשים ב-GCM. מידע נוסף זמין כאן.
קריאה נוספת
- התראה מאפליקציית אינטרנט: תיעוד בנושא יסודות האינטרנט.
- ספריות של הודעות פוש לאינטרנט: ספריות של הודעות פוש לאינטרנט, כולל Node.js, PHP, Java, Python, C ו-C#.