ウェブプッシュを使用する

拡張機能では、任意の Push プロバイダを使用してプッシュ通知とメッセージを送信できます。Push API からの push は、受信するとすぐに Service Worker で処理されます。Service Worker が停止されている場合、Push は Service Worker を再開します。拡張機能で使用するプロセスは、オープンウェブで使用するプロセスとまったく同じです。

Push API を使用する権限を取得する

通常のウェブサイトで push サーバーを登録すると、アクセスを許可または拒否するための権限プロンプトがユーザーに表示されます。拡張機能を使用すると、このプロンプトは表示されません。拡張機能で Push API を使用するには、manifest.json で notifications 権限を設定する必要があります。

  {
    "manifest_version": 3,
    ...
    "permissions": ["notifications"]

この権限がない場合、registration.pushManager を操作すると、ユーザーが権限を拒否した場合と同じ結果がすぐにエラーになります。また、notifications 権限を指定すると、インストール時に権限に関する警告が表示されることに注意してください。また、ユーザーが新しい権限リクエストを承認するまで、既存のインストールでは拡張機能が無効になります。この処理方法について詳しくは、権限に関する警告ガイドをご覧ください。

push プロバイダと push サービス

manifest.json に権限を追加したら、バックエンドと拡張機能の間の接続を構成する必要があります。この接続は、push プロバイダと push サービスの 2 つの部分に分けられます。プロバイダとは、メッセージを push サービスに送信するために使用する SDK です。さまざまなオプションがあり、任意の Push プロバイダを Push API で使用できます(ただし、統合を容易にする SDK は提供されていない場合があります)。プロバイダの SDK で何が可能かをテストする必要があります。プッシュ サービスはエンドユーザーのデバイスが登録されているため、プッシュ プロバイダによってプッシュ メッセージが送信されたときにアラートを受け取れます。これは個々のブラウザにハードコードされているため、制御することはできません。Chrome の場合、Firebase Cloud Messaging は push サービスです。Chrome ユーザーに push されたメッセージは このユーザーを経由します

push プロバイダのセルフホスティング

すべての Push プロバイダが機能しますが、すべてのプロバイダが Service Worker で動作する SDK を提供しているわけではありません。実行に問題がある場合は、プロバイダにお問い合わせください。ただし、パブリック プロバイダを使用する必要はありません。web-push などのライブラリを使用すると、独自のバックエンドをホストできます。

このライブラリは、web-push-codelab.glitch.me を使用してテストできます。具体的には、ブラウザで push サブスクリプションを生成するには、Push サーバーの VAPID 公開鍵をコピーする必要があります。この公開鍵は実際には base64 でエンコードされたバイナリ値です。ブラウザのプッシュ マネージャーに登録するには、デコードして Uint8Array に変換する必要があります。このロジックを実行するためのライブラリがありますが、必要なのは以下だけです。

function urlB64ToUint8Array(base64String) {
  const padding = '='.repeat((4 - (base64String.length % 4)) % 4);
  const base64 = (base64String + padding).replace(/-/g, '+').replace(/_/g, '/');

  const rawData = atob(base64);
  const outputArray = new Uint8Array(rawData.length);

  for (let i = 0; i < rawData.length; ++i) {
    outputArray[i] = rawData.charCodeAt(i);
  }
  return outputArray;
}

指定された値がプッシュ マネージャーに渡されます。

const SERVER_PUBLIC_KEY = '_INSERT_VALUE_HERE_';
const applicationServerKey = urlB64ToUint8Array(SERVER_PUBLIC_KEY);

async function subscribe() {
  try {
    let subscription = await self.registration.pushManager.subscribe({
      userVisibleOnly: true,
      applicationServerKey
    });

    console.log(`Subscribed: ${JSON.stringify(subscription,0,2)}`);

    return subscription
  } catch (error) {
    console.error('Subscribe error: ', error);
  }
}

const subscription = await subscribe();

subscribe 関数は、Push サーバーのメタデータを含むオブジェクトである PushSubscription を返します。web-push-codelab.glitch.me を使用しているため、この値をページの push サブスクリプションの部分にコピーする必要があります。

PushSubscription を作成したら、拡張機能の Service Worker に push メッセージのリスナーを登録できます。

self.addEventListener('push', function (event) {
  console.log(`Push had this data/text: "${event.data.text()}"`);
});

リスナーを設定すると、web-push-codelab.glitch.me でメッセージを送信すると、メッセージが Service Worker のコンソールに記録されます。

ウェブプッシュはオープンウェブ標準であるため、Chrome のブログなど、ウェブプッシュの実装方法に関する既存のドキュメントが多数あります。ここで説明した例の完全なバージョンは、拡張機能のサンプル リポジトリにあります。

サイレントプッシュ

Manifest V3 が Chrome 88 に導入されて以来、Manifest V3 拡張機能でプッシュ通知を受信できるようになりました。しかし、これまでも、ウェブ通知のような、ユーザーに表示されるなんらかのプロンプトを通知に表示することが常に必要でした。これにより、ユーザーに不要な情報を表示せずにコマンドやデータの更新を拡張機能に push する場合、有用性が大幅に低下します。Chrome 121 以降、拡張機能で userVisibleOnlyfalse に設定できるようになりました。ユーザーに公開されていないサイレントのプッシュ通知を送信できるようになりました。これを使用するには、pushManager.subscribe を呼び出すときに userVisibleOnlyfalse に設定します。

let subscription = await self.registration.pushManager.subscribe({
  userVisibleOnly: false,
  applicationServerKey
});