指南

如何為你的 App 加入通知:App 內、電郵同推播

要為網頁 App 加入通知,首先從 App 內通知開始:喺資料庫建立通知表,再加一個鈴鐺圖示顯示未讀項目。當用戶離開時仍然需要知道嘅事,就加入電郵,使用電郵服務供應商發送;只有當即時提醒真係重要時,才加入網頁推播,因為它需要 Service Worker、用戶權限,而喺 iPhone 上仲要將 App 儲存到主畫面。不論用咗邊啲渠道,都應該喺伺服器上一個地方統一建立所有通知,並讓用戶自己選擇想收到咩。

本指南會比較各種渠道、展示一個簡單嘅架構,並提供可以俾 AI App 生成工具使用嘅提示詞。

主要渠道比較

渠道何時送達用戶設定工夫運作成本最適合
App 內(鈴鐺、Toast 提示)用戶正在使用你嘅 App 時低除咗資料庫,冇其他費用活動、提及、狀態變更
電郵用戶隨時查看電郵時中:服務供應商、網域設定按電郵收費,視乎供應商收據、摘要,以及重要嘅資訊
網頁推播瀏覽器或已安裝嘅網頁 App 中,即使網站已關閉中至高通常發送免費有時限性嘅提醒
SMS幾乎一定會收到中;受同意規則約束每則訊息收費預約提醒、緊急通知
即時通訊工具(Slack、Teams)用戶喺工作期間低至中通常免費內部工具同團隊提醒

大部分 App 只需要 App 內通知加電郵。只有時間非常重要時,例如預約提醒或訂單已準備好,才值得加入推播同 SMS。

通知系統如何組合

保持簡單同集中處理:

  1. 發生某件事。 有人留言、付款失敗、預約係聽日。
  2. 你嘅伺服器呼叫一個函式,例如 notify(user, type, data)。
  3. 該函式檢查用戶嘅偏好設定,並將一行資料寫入 notifications 表(用於鈴鐺)。
  4. 然後發送到用戶為該類型開啟嘅其他渠道:電郵透過你嘅電郵服務供應商,推播則透過 Push API。
  5. 前端顯示未讀通知,並在用戶打開時標示為已讀。

只設一個入口,就可以新增渠道、修改內容,或者尊重用戶偏好,而唔使喺程式碼入面到處搵。

要儲存咩

通知表通常需要:用戶 ID、類型(例如 comment_reply)、簡短標題同內容、連往相關頁面嘅連結、建立時間,以及已讀時間。另外用一個偏好設定表,記錄每位用戶每種類型想使用邊啲渠道。

點樣顯示新通知

  • 載入頁面時取得,並每 30 至 60 秒輪詢一次。 簡單而可靠。
  • 用 WebSocket 或 server-sent events 做即時更新。 感覺即時,但會多出運作部件。除非即時更新真係重要,否則先用輪詢。

電郵通知

電郵需要發送服務供應商同已驗證嘅網域;詳情見如何從你嘅 App 發送電郵。針對通知方面:

  • 由伺服器發送。 絕對唔好喺瀏覽器入面放供應商金鑰。
  • 將頻繁發生嘅事件合併。 「3 則新留言」一封電郵,好過三封分開。
  • 低優先度嘅活動可以提供每日或每週摘要。
  • 非必要嘅電郵要附上取消訂閱或偏好設定連結。 宣傳電郵嘅規定因國家而異,請查清楚適用於你嘅規則。

網頁推播通知

網頁推播令你嘅網站可以發送似 App 通知一樣嘅提醒。按 MDN Push API 文件所述,運作方式如下:

  1. 你嘅網站註冊一個 Service Worker,即瀏覽器可以喺背景執行嘅腳本。
  2. 用戶同意之後,Service Worker 透過 PushManager.subscribe() 訂閱。瀏覽器會回傳一個 subscription,包含端點同加密金鑰。
  3. 你嘅伺服器儲存該 subscription,並於有事發生時向該端點發送訊息,通常會用 VAPID 金鑰簽署(即一對識別你伺服器嘅金鑰)。
  4. 瀏覽器啟動你嘅 Service Worker,即使你嘅頁面冇開啟,都會顯示通知。

MDN 亦提醒,端點應該保密,因為只要知道端點,就足以向該用戶發送訊息。

iPhone 同 iPad

WebKit 喺 iOS 同 iPadOS 16.4 開始支援網頁 App 嘅 Web Push,其公告列出兩項條件:網站必須加入主畫面,而權限必須由用戶操作觸發要求,例如輕按「訂閱」按鈕。所以喺 iPhone 上,推播只會送達已安裝你網頁 App 嘅用戶。安裝網頁 App 代表甚麼,可參閱原生 App 與漸進式網頁 App。

如何妥善地請求權限

唔好喺首次到訪時就要求權限。先解釋好處(「上課前一小時提醒你」),然後等用戶按一個按鈕,才顯示瀏覽器嘅權限提示。如果有人拒絕,瀏覽器可能唔再允許你再次要求,所以過早彈出提示,可能會永久失去佢。

排定時間嘅通知需要觸發器

「24 小時前提醒」或「每週一發送每週摘要」需要有排程執行嘅機制。呢個屬於背景工作問題,詳見如何執行背景工作。常見做法係由外部排程器每幾分鐘呼叫一個受保護嘅端點,然後該端點發送所有到期嘅通知。

俾 AI 生成工具嘅提示詞

先由 App 內通知開始:

加入 App 內通知。建立一個 notifications 表(user、type、title、body、link、created_at、read_at)。新增一個伺服器函式 notify(userId, type, data),所有功能都會呼叫佢。喺標題列顯示一個帶未讀數字嘅鈴鐺圖示,點擊後下拉顯示最新 20 則,並加入「全部標示為已讀」按鈕。每 60 秒輪詢一次新通知。

然後是偏好設定同電郵:

加入通知設定:每種類型(留言回覆、提及、帳單)讓用戶選擇 App 內、電郵、兩者或無。notify() 必須遵從呢啲設定。透過 [PROVIDER] 發送電郵,使用只喺伺服器上嘅機密 [ENV_NAME]。將留言電郵分組,令同一位用戶每 15 分鐘最多只收到一封。

如果需要推播,再加入:

加入可選嘅網頁推播。註冊一個 Service Worker,生成 VAPID 金鑰,並將私鑰儲存為機密。喺設定中加入「啟用通知」按鈕,只有按下時先要求權限。按用戶及裝置儲存每個 subscription,用戶選擇開啟時由 notify() 發送推播,並刪除推播服務回報為已過期嘅 subscription。

常見錯誤

  • 通知散落喺程式碼各處。 每個功能各自以不同方式發送電郵,偏好設定就會被忽略。應該用一個 notify() 函式。
  • 頁面一載入就要求推播權限。 大部分人會拒絕,而你可能冇第二次機會。
  • 冇偏好設定。 無法關閉煩人提醒嘅用戶,會關閉全部,或者直接離開。
  • 喺瀏覽器發送。 電郵同推播金鑰只應該放喺伺服器。
  • 唔清理失效嘅推播 subscription。 過期嘅 subscription 會越積越多,浪費發送。
  • 通知內容有敏感資料。 鎖定畫面會顯示內容。「你有一則新訊息」比訊息本身更安全。
  • 冇記錄發出咗乜嘢。 當用戶話「我冇收到電郵」,附有供應商訊息 ID 嘅紀錄可以幫你查明原因。

檢查清單

  • 全部功能都使用一個伺服器端 notify() 函式
  • 通知表包括已讀狀態,而鈴鐺會顯示未讀數字
  • 每種類型嘅渠道偏好設定,由 notify() 遵從
  • 電郵由伺服器發送,使用已驗證嘅網域;頻繁事件有摘要或合併
  • 推播權限只會喺用戶操作之後,連同說明先要求
  • 已喺桌面同 iPhone(已加入主畫面)測試推播
  • 已移除失效嘅推播 subscription
  • 推播或電郵預覽冇敏感內容
  • 定時提醒有可靠嘅觸發機制

Mythex 中嘅通知

Mythex 唔包括為你所建 App 而設嘅內置電郵或推播服務,所以你需要自行使用電郵服務供應商,並生成自己嘅推播金鑰,儲存為專案機密。App 內通知部分只需要專案嘅資料庫,而你要求時 Mythex 會加入。用上述嘅提示詞去建立,並喺 Preview 測試鈴鐺同電郵;推播則要喺已發布嘅網址測試,因為 Service Worker 同推播都需要真正嘅 HTTPS 地址。文件中嘅從 App 發送電郵食譜有一個起步提示詞。Mythex 暫時未有文件說明排程工作,所以定時提醒要按如何執行背景工作所述,靠外部觸發器規劃。

常見問題

為網頁 App 加入最容易嘅通知係咩?

App 內通知:喺資料庫建立一個通知表,再加一個鈴鐺圖示顯示未讀通知。呢種做法唔需要第三方服務。電郵係下一步,需要電郵服務供應商。

網頁 App 可以向 iPhone 發送推播通知嗎?

可以,但有限制。WebKit 喺 iOS 同 iPadOS 16.4 開始支援 Home Screen 網頁 App 嘅 Web Push,所以用戶必須先將你嘅網頁 App 加入主畫面,而權限亦必須喺用戶輕按一下之後(例如按「訂閱」按鈕)先要求。

網站關閉時推播通知仍然可以運作嗎?

可以。Push API 會將訊息傳送到你網站嘅 Service Worker,當訊息到達時瀏覽器會啟動佢,所以頁面唔需要保持開啟。但用戶必須事先授予權限。

點樣避免通知令用戶煩厭?

只通知用戶真正關心嘅事,將短時間內大量嘅通知合併成一則,讓用戶喺設定中按類型選擇渠道,並且喺用戶明白推播有咩用處之後先要求權限。

Mythex · Pricing · 用 AI 建造任何嘢 · 網站及應用程式範本 · Mythex 比較 · AI 應用程式開發詞彙表 · 免費 AI 應用程式開發工具 · English

English አማርኛ العربية Български বাংলা Bosanski Català Čeština Dansk Deutsch Ελληνικά Español Español (España) Eesti فارسی Suomi Français Français (Canada) ગુજરાતી हिन्दी Hrvatski Magyar Հայերեն Bahasa Indonesia Íslenska Italiano 日本語 ქართული Қазақ тілі ಕನ್ನಡ 한국어 Lietuvių Latviešu Македонски മലയാളം Монгол मराठी Bahasa Melayu မြန်မာ Norsk bokmål Nederlands ਪੰਜਾਬੀ Polski Português (Brasil) Português (Portugal) Română Русский Slovenčina Slovenščina Soomaali Shqip Srpski Svenska Kiswahili தமிழ் తెలుగు ไทย Tagalog Türkçe Українська اردو Tiếng Việt 简体中文 繁體中文(台灣)