--- title: Google Service Worker Notifications tags: Templates, Talk description: View the slide with "Slide Mode". --- # Google Service Worker Notifications (通知篇)! >製作Tinn >參考:Google各位大大 >[範例參考詳解](https://jonny-huang.github.io/angular/training/21_pwa3/) --- ### Service Workger Notificatoins 分成 push(推送) 與 Notifications(通知) #### 本邊先來介紹一下 Notification(通知的部分) - 通知則是瀏覽器上的程式與使用者間的溝通。 - 推送指的是伺服器的後端與瀏覽器上的程式之間的溝通 --- ## 環境需求 - production開發環境 - 使用https(可有可無) - 零食餅乾....... --- ### 瀏覽器通知設定(google chrome為例) <img src="https://i.imgur.com/KWrRJIR.png"> 由此可見瀏覽器通知設定的選項對應至 [Notification API](https://developer.mozilla.org/en-US/docs/Web/API/Notification)的permission屬性 | permission | description | | -------- | -------- | | default | 尚未給予權限 (因此不會顯示通知) | | granted | 允許接收網站的通知 | | denied | 拒絕接收網站的通知 | --- ### 判斷權限 透過Notification API 可以知道我們可以透過 Notification.requestPermission 檢查權限並於瀏覽器上產生一個允許通知的請求視窗。 <img src="https://i.imgur.com/4HVhe0E.png"> 選取允許後 permission變更為 granted了 <img src="https://i.imgur.com/4vlns6u.png"> **請求通知視窗僅**requestPermission.permission**的屬性為**default**才會啟用 若是選取 允許(granted)或是封鎖(denied)後續請求視窗皆不會再次出現** **若是使用者已選取拒絕、因此可透過Notification.permission判斷權限來確認任狀態並顯示更改通知的視窗** 我們開啟檔案寫入 **requestPermission** 方法 ```javascript= if ('serviceWorker' in navigator) { navigator.serviceWorker.register('./sw.js') .then(reg => { // registration worked console.log('[Service Worker] Registration succeeded. Scope is ' + reg.scope); if ('Notification' in window) { console.log('Notification permission default status:', Notification.permission); Notification.requestPermission(function (status) { console.log('Notification permission status:', status); }); } }).catch(error => { // registration failed console.log('[Service Worker] Registration failed with ' + error); }); } ``` ### 顯示通知 處理完權限問題後、我們來實作於畫面上顯示訊息 我們可以透過 ```​ServiceWorkerRegistration.showNotification(title, [options]);```方法來呈現 下面是常用的屬性選擇 | option | description | | -------- | -------- | | icon | 圖標url | | body | 內文 | | image | 圖片 | | data | 夾帶資料;可於使用者點擊時依照不同的參數去實現不同功能| | actions | 選單操作 action:識別名稱 ,title:標題, icon:圖標 | | requireInteraction | false(預設):自動關閉(Chrome 大約20秒後)。 true:訊息一直顯示,直到點擊或是按關閉按鈕才消失。 | [詳細完整請點這裡](https://developer.mozilla.org/en-US/docs/Web/API/Notification) 捲起袖子把畫面顯示出來吧 內容如下: ```javascript= if ('serviceWorker' in navigator) { navigator.serviceWorker.register('service-worker.js').then(registration => { // 注册成功 //console.log('ServiceWorker registration successful with scope: ', registration.scope) if ('Notification' in window) { Notification.requestPermission(status => { console.log('Notification permission status:', status) if (Notification.permission === 'granted') { navigator.serviceWorker.getRegistration().then(reg => { const options = setNotificationOptions(); reg.showNotification('來寫laravel', options) //console.log('成功發出客戶端通知') }) } }) } }).catch(err => { // 注册失败 console.log('ServiceWorker registration failed: ', err) }) } function setNotificationOptions() { const options = { icon: 'https://img.icons8.com/cotton/2x/settings.png', body: '歡迎來寫laravel喔!!!!!!!', image: 'https://www.imgglobalinfotech.com/blog/wp-content/uploads/2019/03/6-reasons-why-to-choose-laravel-framework-for-web-development-blog-image858204-768x427.png', // vibrate: [100, 50, 200], // 震動 僅支援震動的裝置 requireInteraction: true, // 一值停留 data: { link: 'https://www.laravel-dojo.com/', link_ok: 'https://laravel.tw/', link_ng: 'https://learnku.com/articles/5099/why-dont-i-want-to-use-laravel', }, actions: [{ action: 'yes', title: '參加', icon: 'https://img.icons8.com/cotton/2x/settings.png', }, { action: 'no', title: '不參加', icon: 'https://img.icons8.com/cotton/2x/settings.png', }, ], } return options } ``` --- ## 通知顯示時點選參加按鈕 <img src="https://i.imgur.com/cQADZph.gif"> --- ## 通知顯示時點選不參加按鈕 <img src="https://i.imgur.com/JDKemPz.gif"> --- ## 通知顯示時點選收合時 <img src="https://i.imgur.com/TkY2XRz.gif"> --- ## 通知顯示時點選圖片時 <img src="https://i.imgur.com/BTehTpO.gif"> --- ### 以上為呈現的結果 、並且將按鈕事件(跳頁)加上去 ## **事件監聽的部分必須寫在 ```sw.js```中 以下為範例** ```javascript= self.addEventListener('notificationclick', function(event) { const notification = event.notification; const action = event.action; const link = notification.data.link; const link_ok = notification.data.link_ok; const link_ng = notification.data.link_ng; switch (action) { case 'yes': if (link_ok) { clients.openWindow(link_ok); } break; case 'no': if (link_ng) { clients.openWindow(link_ng); } break; case 'close': break; default: if (link) { clients.openWindow(link); } break; } notification.close(); console.log('notificationclick action is', action); }); ``` --- # :100: :muscle: :tada: ## 完成囉下篇再來介紹 push(推送) --- ### Thank you! :sheep: