OneSignalを使って超簡単に、特定のユーザへのブラウザpushを作る

この記事は[エイチームブライズアドベントカレンダー](https://qiita.com/advent-calendar/2017/a-t-brides)3日目の記事です。

# はじめに
今回エイチームブライズのアドベントカレンダー2017に初投稿になります。
何を書こうかなーと悩んだんですが、最近使ってとても便利だったOneSignalについて書いてみようと思います。

# OneSignalとは
https://onesignal.com/

- 無料で使える
- A/Bテスト、ユーザープロパティ、自動配信などの機能もある
- iOS, Android, Web Push, Unityなどに対応
- 配信は１秒間に5,000プッシュまで可能
- SSL対応してないサイトでもプッシュ通知を送れる

# OneSignalを導入しブラウザプッシュを実現する
## OneSignalでアプリケーションの作成
Dashboardから 「Add a new app」を選択しアプリケーション名を登録。
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/200812/94a1df41-2529-248e-b1c7-be1e1a5212e8.png)

Website Push を選択。
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/200812/fbb768b2-91ec-539b-8797-1dbe6ff76d9b.png)

Safariへの通知は別途対応が必要みたい。
今回はGoogle Chrome & Mozilla Firefoxを選択。
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/200812/91ac660a-f4a2-4fac-6c04-b76e8db30c47.png)

対象となるWEBサイトのURLとプッシュ通知のデフォルトアイコン（任意）を設定する。
HTTPSに対応していない場合はチェックボックスにチェック。
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/200812/e8fc7bca-6743-6bfe-c3d7-38fd2a9beef2.png)

## テスト通知を送信
最初のテスト通知を送信する必要があり、その方法を選ぶ。
今回はWebsitePushを選択。
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/200812/71abbd92-7af6-6723-b785-e8aed480ddf9.png)

## SDKのインストールをする
SDKのインストール手順が表示されるのでその通りに実行する。
APPIDが後で必要になるのでメモしとく。
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/200812/aea55b1e-3ab1-53c5-5ed8-33aef0b53164.png)

manifest.json
OneSignalSDKWorker.js
OneSignalSDKUpdaterWorker.js
を https://documentation.onesignal.com/docs/web-push-sdk-setup-https から落としてきてウェブサイト上にあげておく。

```json:manifest.json
{
  "name": "YOUR_SITE_NAME",
  "short_name": "YOUR_SITE_NAME",
  "start_url": "/",
  "display": "standalone",
  "gcm_sender_id": "482941778795"
}
```
gcm_sender_idは変更しちゃダメだそう。
## head内にjsを埋める

```html:hoge.html
<head>
  <link rel="manifest" href="/manifest.json">
  <script src="https://cdn.onesignal.com/sdks/OneSignalSDK.js" async></script>
  <script>
    var OneSignal = window.OneSignal || [];
    OneSignal.push(["init", {
      appId: "ここにさっきのAPPID",
      autoRegister: false,
      notifyButton: {
        enable: true /* Set to false to hide */
      }
    }]);
  </script>
</head>
```
細かい設定については[ドキュメント](https://documentation.onesignal.com/docs)にかなり詳しく書いてあるので気になった方はどうぞ。
## ブラウザでアクセスして通知を許可する
この状態でhoge.htmlにアクセスすると右下に赤いベルのマークが表示されるので、そこをクリックして、ALLOWを選択し通知を許可します。
管理画面に戻り Check Subscribed Usersをクリックし、問題なければ完了ページが表示されます。
ここで問題が発生する場合は hoge.html でjsエラーが発生していることがあるので見てみてください。

## プッシュメッセージを送信
あとは管理画面にもどって「New Message」をクリックし、メッセージを作成し、プッシュすると無事にブラウザpushされます。
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/200812/ded63289-48b0-45cc-2c02-3a1a40108ceb.png)


# 特定のユーザにだけ通知を送りたい
上記でプッシュ通知の送信が実装できると、次は何かアクションを受けたときにシステムから自動で特定のユーザへメッセージを送りたくなります。
のでやってみます。
特定のユーザのみに通知を送るときは「sendTag」という機能をつかいます。

## javascriptで送信先IDの設定をする
先程のjsを少し変更します。

```html:hoge.html
<head>
  <link rel="manifest" href="/manifest.json">
  <script src="https://cdn.onesignal.com/sdks/OneSignalSDK.js" async></script>
  <script>
    var OneSignal = window.OneSignal || [];
    OneSignal.push(["init", {
      appId: "ここにさっきのAPPID",
      autoRegister: false,
      notifyButton: {
        enable: true /* Set to false to hide */
      }
    }]);
    OneSignal.push(['sendTag', 'customId', 1, function(tagsSent) {}]); // ここ追加
  </script>
</head>
```
そしてこのページにアクセスすると、アクセスしたブラウザはcustomIdが1のタグを持つことになります。
この後customId 1のタグに向けてプッシュ通知を送信することでこのブラウザのみに向けてプッシュ通知を送ることが可能になります。
ちなみにこのタグは上書きされます。
customId 1をセットした後で2をセットすると2で上書きされますのでご注意。
またタグは好きな名前で複数設定することも可能です。

## 送信先IDを指定して送る
今回はPHPでの送信を実装したいと思います。

```php:send_message.php
    $fields = array(
      'app_id' => "ここにさっきのAPPID",
      'contents' => array('en' => "プッシュ通知の本文"),
      'headings' => array('en' => "プッシュ通知のタイトル");
      'chrome_web_icon' => "アイコンを設定したい場合は画像のURL（任意）",
      'tags' => array(array("key" => "customId", "relation" => "=", "value" => "1"))
    );

    $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 ここにREST API KEY'));
    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);
```
とすることでcustomIdが１の人だけにプッシュ通知を送ることができます。
relationを > や < とすることでcustomIdが特定の値以上の人や以下の人に絞ってメッセージを配信することも可能です。

```php:send_message.php
'tags' => array(
             array("key" => "customId", "relation" => "=", "value" => "1"),
             array("operator" => "OR"),
             array("key" => "customId", "relation" => "=", "value" => "100")       
          )
 ```
またこのようにすることでcustomIdが1か100の人に送ることができます。
うん、とても便利。

# まとめ
OneSignalを使うとこんなにも簡単にブラウザプッシュが実装できます。
今回ご紹介しきれなかったoptionもたくさんあるのでぜひ[ドキュメント](https://documentation.onesignal.com/docs)をご覧ください。
無料でここまで様々な機能が提供されているのは本当にすごいなと感じました。

# お知らせ
エイチームブライズでは一緒に活躍してくれる優秀な人材を募集中です。
興味のある方はぜひとも[エイチームグループ採用ページ](http://www.a-tm.co.jp/recruit/)（[Webエンジニア詳細ページ](http://www.a-tm.co.jp/recruit/requirements/career/lifestylesupport-webengineer/)）よりお問い合わせ下さい。

# 明日
[エイチームブライズアドベントカレンダー](https://qiita.com/advent-calendar/2017/a-t-brides)3日目の記事は、いかがでしたでしょうか。
明日は @GakuYasui が「なにか」について書いてくれるようです。
きっとすごい記事を書いてくれるはずです。楽しみですね！