グループごとにプッシュ通知を送信する

Task

2018年11月08日 18:26

[プッシュ通知の許可を任意のタイミングで行えるようにする] の続きです。前回PHPとMySQLを使ってエンドポイントを保存することができたので複数のエンドポイントを呼び出して、呼び出されたものだけに対して通知を行えるようになったのでまとめ。 動きとしてはAさんのブログ記事が投稿をされたら、Aさんのブログを購読しているBさん、Cさんに対してプッシュ通知を送信する。 ブログの記事を管理する\_entryテーブル、購読者とブログ名を紐付ける\_subscribeテーブル、購読者と購読者のエンドポイントを管理する\_registerテーブルの3つを用意した。 基本的にService Worker側のコードは[最近流行りのWeb Push(プッシュ通知)を試してみる]をベースに一部を変更。 Service Workerはpushイベントを受け取って、エンドポイントごとに表示される内容を変えるためにnotifications.phpにクエリを投げるだけ。 ```javascript const getEndpoint = () => { return self.registration.pushManager.getSubscription().then(subscription => { if (subscription) { return subscription.endpoint; } throw new Error('User not subscribed'); }); } self.addEventListener('push', event => { event.waitUntil(getEndpoint().then(endpoint => { return fetch('./notifications.php?endpoint=' + endpoint); }).then(response => { if (response.status === 200) { return response.json(); } throw new Error('notification api response error') }).then(json => { return self.registration.showNotification(json.title, { icon: json.icon, body: json.body, data: { url: json.url } }); })); }); self.addEventListener('notificationclick', event => { event.notification.close(); clients.openWindow(event.notification.data.url); }, false); ``` Aさんの記事投稿と共に呼び出されるpush.phpで購読者のエンドポイントに通知を投げる。 ```php try { $pdo = new PDO('mysql:host=localhost;dbname=db_name;charset=utf8', 'root', 'password'); } catch (PDOException $e) { exit('データベース接続失敗'.$e->getMessage()); } $stmt = $pdo->query(" SELECT endpoint FROM _register JOIN _subscribe ON _register.member_id = _subscribe.subscriber_id JOIN _entry ON _subscribe.subscription_blog_id = _entry.blog_id WHERE entry_id = ( SELECT entry_id FROM _entry ORDER BY entry_id DESC LIMIT 1) "); while($result = $stmt->fetch(PDO::FETCH_ASSOC)) { $registration_ids[] = str_replace(FCM_API_URL, "", $result['endpoint']); } $pdo = null; ``` Bさん、CさんはService Workerでpushイベントを受け取るが、通知の内容が分からないので、notifications.phpに尋ねて結果をService Workerに返す。 ```php try { $pdo = new PDO('mysql:host=localhost;dbname=db_name;charset=utf8', 'root', 'password'); } catch (PDOException $e) { exit('データベース接続失敗'.$e->getMessage()); } $stmt = $pdo->query(" SELECT * FROM _register JOIN _subscribe ON _register.member_id = _subscribe.subscriber_id JOIN _entry ON _subscribe.subscription_blog_id = _entry.blog_id WHERE entry_id = ( SELECT entry_id FROM _entry ORDER BY entry_id DESC LIMIT 1) "); $result = $stmt->fetch(PDO::FETCH_ASSOC); echo('{ "title": "' . $result['blog_id'] . '", "icon": "./favicon.ico", "body": "' . $result['entry_title'] . '", "url": "https://' . $result['blog_id'] . '.' . $_SERVER["HTTP_HOST"] . '" }'); ``` SQLについては改善の余地がありそう。 [プッシュ通知の許可を任意のタイミングで行えるようにする]: https://hi97.hamazo.tv/e8239503.html [最近流行りのWeb Push(プッシュ通知)を試してみる]: https://qiita.com/kite_999/items/e53b1c60a10275988604
const content = document.getElementById('content'); content.innerHTML = marked(content.innerHTML.replace(/>/g, '>').replace(/</g, '

関連記事