OneSignalで特定のユーザーにWEBプッシュ通知を送る方法（PHP編）

[OneSignal](https://onesignal.com/)は無料で使いはじめることができるプッシュ通知配信サービスです。（WEBプッシュは3万ユーザーまで。モバイルは無制限で）
<img width="1343" alt="スクリーンショット 2019-11-26 11.41.10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72150/b5d4513f-4f23-dffb-7446-141ea9ac1624.png">
こちらを使うと驚くほどかんたんにプッシュ通知を送れました。今回はLaravelにてOneSignalを使ってWEBブラウザ向け（Chrome、Firefox）にプッシュ通知を配信する方法をまとめます。

# OneSignalでアプリを作成
<img width="728" alt="スクリーンショット 2019-11-26 11.43.06.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72150/7af0abd7-167b-5405-0393-c94164571833.png">
Website Push を選択。
<img width="844" alt="スクリーンショット 2019-11-26 11.43.51.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72150/61102a5b-2901-57ee-7892-7843c78d79ae.png">
SITE NAMEとSITE URLを入力。
<img width="1264" alt="スクリーンショット 2019-11-26 11.44.22.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72150/c1098082-4289-1af2-2ca9-30e274d8979f.png">
ローカルでテストする場合はSITE URLは「https://localhost 」など適宜変更してつくってください。
DEFAULT ICON URLはプッシュ通知の許可ダイアログででてくるアイコンです。
<img width="446" alt="スクリーンショット 2019-12-03 10.11.41.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72150/1e4aedbe-1ec1-5a4f-76f6-681e7ff31cc9.png">

Permission Prompt Setupは、最初にサイトを訪れた時にプッシュ通知の許可確認をとる方法を選べます。

<img width="1220" alt="スクリーンショット 2019-12-03 10.12.13.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72150/b6cc8c76-7cda-c1f8-be69-14a8eb4d8dc4.png">
Welcome Notificationでは許可された場合に送るプッシュ通知を設定。お礼のメッセージなどを。
ほかにもいろいろ設定はありますが、基本的にはこれだけで「SAVE」でOK。

<img width="1223" alt="スクリーンショット 2019-12-03 10.15.28.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72150/8f19d0bb-b273-03d2-2ff9-7214c6df0780.png">
次に、「DOWNLOAD ONESIGNAL SDK FILES」を押してファイルをダウンロードして、下記の2つのファイルをサイト直下にアップしてください。
<img width="447" alt="スクリーンショット 2019-12-03 10.17.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72150/6533d400-a047-0f79-a896-5cd795867ef4.png">
最後に、JavaScriptのコードを埋め込めば完了です。

# OneSignalでプッシュ通知を送る
これでプッシュ通知を送れるようになりました。OneSignalの管理画面からMessagesを開いてNEW PUSHをクリック。
<img width="715" alt="スクリーンショット 2019-12-03 10.18.50.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72150/17cc2852-7230-4f8c-fc76-8c05364beca4.png">
Send to Subscribed Usersで、購読している人に送れます。
<img width="1240" alt="スクリーンショット 2019-12-03 10.20.37.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72150/9147b83e-828a-2624-8f3f-59d1fd534882.png">

# 個別にプッシュ通知を送りたい
全体に送るものだけじゃなく、特定のユーザーにだけ通知を送りたいケースはよくあります。

アプリ側から下記のようにUserIdをセットすることができます。（下記の例はLaravelのbladeに書いています）

```javascript:
<script>
        var OneSignal = window.OneSignal || [];
        OneSignal.push(function () {
            OneSignal.init({
                appId: "ONESIGNALのAPP_ID",
            });

            @if(isset($loginUser))
            //onesignalにuser_idをセット
            OneSignal.on('subscriptionChange', function (isSubscribed) {
                if (isSubscribed == true) {
                    OneSignal.setExternalUserId('{{ $loginUser->id }}');
                    OneSignal.getExternalUserId().then(function (id) {
                    });
                } else if (isSubscribed == false) {
                    OneSignal.removeExternalUserId();
                }
            });
            @endif
        });
</script>
```

これでOneSignalのユーザーとアプリ側のユーザーを一致させます。

次にプッシュ通知を送りたいところで下記のようにして個別に送ることができます。headingsはタイトル、contentsは内容をいれます。

```php:SendPush.php
$fields = array(
            'app_id' => ONESIGNALのAPP_ID,
            'include_external_user_ids' => [$user_id],
            'url' => アプリのURL,
            'headings' => array('en' => $title),
            'contents' => array('en' => $body)
);

$fields = json_encode($fields);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://onesignal.com/api/v1/notifications");
curl_setopt($ch, CURLOPT_HTTPHEADER,
            array('Content-Type: application/json; charset=utf-8', 'Authorization: Basic '.ONESIGNALのAPP_ID));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

$response = curl_exec($ch);
curl_close($ch);
```

いかがだったでしょうか。OneSignalがあればこれだけかんたんにプッシュ通知を送ることができるようになります。ブラウザだけでなく、スマホアプリにも対応していますのでWEBもアプリもプッシュ通知はOneSignalさえあれば捗ります。