ปัญหาอย่างหนึ่งเมื่อใช้ Web Push คือการเปิดใช้งานข้อความ Push นั้น "ยุ่งยาก" มาก หากต้องการทริกเกอร์ข้อความ Push แอปพลิเคชันจะต้องส่งคําขอ POST ไปยังบริการ Push ตามโปรโตคอล Web Push หากต้องการใช้ Push ในเบราว์เซอร์ทั้งหมด คุณต้องใช้ VAPID (หรือที่เรียกว่าคีย์เซิร์ฟเวอร์แอปพลิเคชัน) ซึ่งโดยทั่วไปจะต้องตั้งค่าส่วนหัวที่มีค่าที่พิสูจน์ว่าแอปพลิเคชันสามารถส่งข้อความถึงผู้ใช้ได้ หากต้องการส่งข้อมูลด้วยข้อความ Push ข้อมูลต้องเข้ารหัสและต้องเพิ่มส่วนหัวที่เฉพาะเจาะจงเพื่อให้เบราว์เซอร์ถอดรหัสข้อความได้อย่างถูกต้อง
ปัญหาหลักของการทริกเกอร์ Push คือหากพบปัญหา คุณจะวินิจฉัยปัญหาได้ยาก ปัญหานี้เริ่มดีขึ้นเมื่อเวลาผ่านไปและเบราว์เซอร์รองรับมากขึ้น แต่ก็ยังไม่ใช่เรื่องง่าย เราจึงขอแนะนำอย่างยิ่งให้ใช้ไลบรารีเพื่อจัดการการเข้ารหัส การจัดรูปแบบ และการเรียกใช้ข้อความ Push
หากต้องการทราบสิ่งที่ไลบรารีทํา เราจะอธิบายในส่วนถัดไป ในตอนนี้จะมาดูการจัดการการติดตามและใช้คลังเว็บ Push ที่มีอยู่เพื่อส่งคําขอ Push
ในส่วนนี้ เราจะใช้ไลบรารี Web Push ของ Node.js ภาษาอื่นๆ จะมีความแตกต่างกันบ้าง แต่ก็จะไม่แตกต่างกันมากนัก เรากำลังพิจารณา Node เนื่องจากเป็น JavaScript และควรเข้าถึงได้ง่ายที่สุดสำหรับผู้อ่าน
เราจะทำตามขั้นตอนต่อไปนี้
- ส่งการสมัครใช้บริการไปยังแบ็กเอนด์ของเราและบันทึก
- เรียกข้อมูลการติดตามที่บันทึกไว้และทริกเกอร์ข้อความ Push
บันทึกการติดตาม
การเก็บและค้นหา PushSubscription
จากฐานข้อมูลจะแตกต่างกันไปตามภาษาฝั่งเซิร์ฟเวอร์และฐานข้อมูลที่เลือก แต่คุณอาจดูตัวอย่างวิธีดำเนินการได้
ในหน้าเว็บเดโม ระบบจะส่ง PushSubscription
ไปยังแบ็กเอนด์ของเราด้วยการทำคำขอ POST ง่ายๆ ดังนี้
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.');
}
});
}
เซิร์ฟเวอร์ Express ในการแสดงตัวอย่างของเรามีโปรแกรมรับฟังคําขอที่ตรงกันสําหรับปลายทาง /api/save-subscription/
ดังนี้
app.post('/api/save-subscription/', function (req, res) {
ในเส้นทางนี้ เราจะตรวจสอบการสมัครใช้บริการเพื่อให้แน่ใจว่าคำขอถูกต้องและไม่มีข้อมูลขยะ
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;
};
หากการสมัครใช้บริการถูกต้อง เราจะต้องบันทึกการสมัครใช้บริการและแสดงผลการตอบกลับ JSON ที่เหมาะสม ดังนี้
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.',
},
}),
);
});
การสาธิตนี้ใช้ nedb เพื่อจัดเก็บการติดตาม ซึ่งเป็นฐานข้อมูลที่ทำงานบนไฟล์แบบง่าย แต่คุณใช้ฐานข้อมูลใดก็ได้ตามต้องการ เราใช้วิธีนี้เนื่องจากไม่ต้องตั้งค่าใดๆ สำหรับเวอร์ชันที่ใช้งานจริง คุณควรใช้สิ่งที่เชื่อถือได้มากกว่า (ฉันมักจะใช้ MySQL แบบเก่า)
function saveSubscriptionToDatabase(subscription) {
return new Promise(function (resolve, reject) {
db.insert(subscription, function (err, newDoc) {
if (err) {
reject(err);
return;
}
resolve(newDoc._id);
});
});
}
การส่งข้อความ Push
การส่งข้อความ Push นั้น ท้ายที่สุดแล้วเราต้องการเหตุการณ์บางอย่างเพื่อทริกเกอร์กระบวนการส่งข้อความไปยังผู้ใช้ แนวทางที่พบบ่อยคือการสร้างหน้าผู้ดูแลระบบที่ช่วยให้คุณกําหนดค่าและเรียกใช้ข้อความ Push ได้ แต่คุณอาจสร้างโปรแกรมให้ทำงานในเครื่องหรือใช้แนวทางอื่นๆ ที่อนุญาตให้เข้าถึงรายการ PushSubscription
และเรียกใช้โค้ดเพื่อทริกเกอร์ข้อความ Push ได้
เดโมของเรามีหน้า "ผู้ดูแลระบบ" ที่ช่วยให้คุณทริกเกอร์ Push ได้ เนื่องจากเป็นเพียงการสาธิต จึงถือเป็นหน้าสาธารณะ
เราจะอธิบายแต่ละขั้นตอนในการทำให้เดโมใช้งานได้ ขั้นตอนเหล่านี้จะเป็นขั้นตอนเบื้องต้นเพื่อให้ทุกคนทำตามได้ รวมถึงผู้ที่เพิ่งเริ่มใช้ Node
เมื่อเราพูดถึงการติดตามผู้ใช้ เราได้พูดถึงการเพิ่ม applicationServerKey
ลงในตัวเลือก
subscribe()
เราต้องใช้คีย์ส่วนตัวนี้ในแบ็กเอนด์
ในการสาธิต ระบบจะเพิ่มค่าเหล่านี้ลงในแอป Node ของเราดังนี้ (โค้ดน่าเบื่อนะ แต่เราแค่อยากให้คุณทราบว่าไม่ได้มีอะไรซับซ้อน)
const vapidKeys = {
publicKey:
'BEl62iUYgUivxIkv69yViEuiBIa-Ib9-SkvMeAtA3LFgDzkrxZJjSgSnfckjBJuBkr3qBUYIHBQFLXYp5Nksh8U',
privateKey: 'UUxI4O8-FbRouAevSmBQ6o18hgE4nSG3qwvJTfKc-ls',
};
ต่อไปเราต้องติดตั้งโมดูล web-push
สําหรับเซิร์ฟเวอร์ Node
npm install web-push --save
จากนั้นในสคริปต์ Node เราต้องใช้โมดูล web-push
ดังนี้
const webpush = require('web-push');
ตอนนี้เราเริ่มใช้โมดูล web-push
ได้แล้ว ก่อนอื่นเราต้องบอกโมดูล web-push
เกี่ยวกับกุญแจเซิร์ฟเวอร์แอปพลิเคชัน (โปรดทราบว่าคีย์เหล่านี้เรียกอีกอย่างว่าคีย์ VAPID เนื่องจากเป็นชื่อของข้อกำหนด)
const vapidKeys = {
publicKey:
'BEl62iUYgUivxIkv69yViEuiBIa-Ib9-SkvMeAtA3LFgDzkrxZJjSgSnfckjBJuBkr3qBUYIHBQFLXYp5Nksh8U',
privateKey: 'UUxI4O8-FbRouAevSmBQ6o18hgE4nSG3qwvJTfKc-ls',
};
webpush.setVapidDetails(
'mailto:web-push-book@gauntface.com',
vapidKeys.publicKey,
vapidKeys.privateKey,
);
โปรดทราบว่าเราได้ใส่สตริง "mailto:" ด้วย สตริงนี้ต้องเป็น URL หรืออีเมลรูปแบบ mailto ข้อมูลนี้จะส่งไปยังบริการ Push บนเว็บโดยเป็นส่วนหนึ่งของคำขอเรียกให้แสดง Push เหตุผลที่ดำเนินการเช่นนี้ก็เพื่อให้บริการ Push บนเว็บมีข้อมูลบางอย่างที่จะช่วยให้ติดต่อผู้ส่งได้หากจำเป็น
เท่านี้โมดูล web-push
ก็พร้อมใช้งานแล้ว ขั้นตอนถัดไปคือการทริกเกอร์ข้อความ Push
การสาธิตนี้ใช้แผงผู้ดูแลระบบจำลองเพื่อเรียกให้แสดงข้อความ Push
การคลิกปุ่ม "ทริกเกอร์ข้อความ Push" จะส่งคําขอ POST ไปยัง /api/trigger-push-msg/
ซึ่งเป็นสัญญาณให้แบ็กเอนด์ส่งข้อความ Push เราจึงสร้างเส้นทางใน Express สําหรับปลายทางนี้
app.post('/api/trigger-push-msg/', function (req, res) {
เมื่อได้รับคําขอนี้ เราจะดึงข้อมูลการติดตามจากฐานข้อมูลและเรียกใช้ข้อความ Push สําหรับการติดตามแต่ละรายการ
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;
});
จากนั้นฟังก์ชัน triggerPushMsg()
จะใช้ไลบรารี Web Push เพื่อส่งข้อความไปยังการสมัครใช้บริการที่ระบุ
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()
จะแสดงผลลัพธ์เป็นสัญญา หากส่งข้อความสำเร็จ สัญญาจะได้รับการแก้ไขและเราไม่จำเป็นต้องดำเนินการใดๆ หากสัญญาถูกปฏิเสธ คุณจะต้องตรวจสอบข้อผิดพลาด เนื่องจากข้อผิดพลาดจะแจ้งให้ทราบว่า PushSubscription
ยังคงใช้งานได้หรือไม่
หากต้องการระบุประเภทข้อผิดพลาดจากบริการ Push คุณควรดูที่รหัสสถานะ ข้อความแสดงข้อผิดพลาดจะแตกต่างกันไปตามบริการ Push และบางข้อความจะมีประโยชน์มากกว่าข้อความอื่นๆ
ในตัวอย่างนี้ ระบบจะตรวจสอบรหัสสถานะ 404
และ 410
ซึ่งเป็นรหัสสถานะ HTTP สำหรับ "ไม่พบ" และ "ไม่มีอีกแล้ว" หากเราได้รับรหัสใดรหัสหนึ่งเหล่านี้ หมายความว่าการสมัครใช้บริการหมดอายุแล้วหรือใช้งานไม่ได้อีกต่อไป ในกรณีเหล่านี้ เราจำเป็นต้องนำการติดตามออกจากฐานข้อมูล
ในกรณีที่เกิดข้อผิดพลาดอื่นๆ เราจะแค่ throw err
ซึ่งจะทำให้การคืนค่าของ Promise จาก
triggerPushMsg()
ปฏิเสธ
เราจะกล่าวถึงรหัสสถานะอื่นๆ บางส่วนในส่วนถัดไปเมื่อพูดถึงโปรโตคอล Push บนเว็บอย่างละเอียด
หลังจากวนดูการติดตามแล้ว เราจะต้องแสดงผลการตอบกลับ JSON
.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}'`
}
}));
});
เราได้อธิบายขั้นตอนการติดตั้งใช้งานหลักๆ ดังนี้
- สร้าง API เพื่อส่งการติดตามจากหน้าเว็บของเราไปยังแบ็กเอนด์ของเราเพื่อให้บันทึกการติดตามลงในฐานข้อมูลได้
- สร้าง API เพื่อทริกเกอร์การส่งข้อความ Push (ในกรณีนี้คือ API ที่เรียกใช้จากแผงการดูแลระบบจำลอง)
- เรียกข้อมูลการติดตามทั้งหมดจากแบ็กเอนด์ของเรา และส่งข้อความไปยังการติดตามแต่ละรายการด้วยไลบรารี Web Push รายการใดรายการหนึ่ง
ขั้นตอนการติดตั้งใช้งาน Push จะเหมือนกันไม่ว่าแบ็กเอนด์ของคุณจะเป็น Node, PHP, Python หรืออื่นๆ
ถัดไป ไลบรารี Push บนเว็บเหล่านี้ทําอะไรให้เราบ้าง
ขั้นตอนถัดไป
- ภาพรวมข้อความ Push บนเว็บ
- วิธีการทำงานของ Push
- การติดตามผู้ใช้
- UX ของสิทธิ์
- การส่งข้อความด้วยไลบรารี Web Push
- Web Push Protocol
- การจัดการเหตุการณ์ Push
- การแสดงการแจ้งเตือน
- ลักษณะการทํางานของการแจ้งเตือน
- รูปแบบการแจ้งเตือนที่พบบ่อย
- คำถามที่พบบ่อยเกี่ยวกับข้อความ Push
- ปัญหาที่พบได้ทั่วไปและการรายงานข้อบกพร่อง