NuxtでPWA対応WebアプリにOneSignalからプッシュ通知を送る

前回、[Nuxt v2とFirebase(CloudFirestore)でPWA対応Webアプリ開発](https://qiita.com/_takeshi_24/items/3ee051e1db1b3e8da106)で、Nuxt v2を使ってPWA対応のWebアプリケーションを作りました。

今回[OneSignal](https://onesignal.com)というサービスを利用して、このPWA対応Webアプリにプッシュ通知を送ります。

NuxtにはOneSignal用のモジュールが用意されているので、これを使うと簡単にプッシュ通知が送れるようになります。

# インストールや設定
## OneSignalにアプリを追加する
- まずは[OneSignal](https://onesignal.com)のサイトからSignUpして、アカウントを作成してください。

- 「Add a New App」でアプリケーション名を入力します。ここでは「pwa-sample」とします。
<img width="559" alt="Add a New App" src="https://qiita-image-store.s3.amazonaws.com/0/3003/ccda5cb1-748a-79c8-ad93-83ae1d7b20c4.png">

- 今回はWebアプリケーションなので、「Web Push」を選択します。
<img width="859" alt="Web Push" src="https://qiita-image-store.s3.amazonaws.com/0/3003/4bbcf525-f66f-efe2-333d-f39b2089def9.png">

- Webアプリケーションのサイト情報を入力します。
<img width="1173" alt="サイト情報入力" src="https://qiita-image-store.s3.amazonaws.com/0/3003/dcf34167-6db3-e9db-4275-e3a3d05ecf33.png">

- 「ADD A PROMPT」より通知を追加します。
<img width="1173" alt="ADD A PROMPT" src="https://qiita-image-store.s3.amazonaws.com/0/3003/9ed8d1b4-9f40-fbdc-d8cf-8730d639aa57.png">

- 今回は「SLIDE PROMPT」を選択します。
<img width="1182" alt="SLIDE PROMPT" src="https://qiita-image-store.s3.amazonaws.com/0/3003/a984a022-8bde-cfad-5b7a-b9c0572d5269.png">

- アプリを保存すると、APP IDが発行されますので、「appId」をメモしておきます。
<img width="1174" alt="APP ID" src="https://qiita-image-store.s3.amazonaws.com/0/3003/690d11ee-41e8-ef7f-f22e-de478b507fa6.png">


## NuxtのOneSignalモジュールの設定
- まずはonesignalモジュールをインストールします。

```shell-session
$ yarn add @nuxtjs/onesignal --save
```

- nuxt.config.jsのmodules内「@nuxtjs/pwa」の前に「@nuxtjs/onesignal」を追加します。

```js:/nuxt.config.js
  modules: [
    // Doc: https://github.com/nuxt-community/axios-module#usage
    '@nuxtjs/dotenv',
    '@nuxtjs/axios',
    '@nuxtjs/onesignal',
    '@nuxtjs/pwa'
  ],
```

- nuxt.config.jsにOneSignalの設定を追加します。
appIdは先ほどOneSignalで取得したアプリのappIdを設定します。

```js:/nuxt.config.js
 oneSignal: {
    init: {
      appId: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
      allowLocalhostAsSecureOrigin: true,
      welcomeNotification: {
        disable: true
      }
    }
  },
```

# 通知を送る
## OneSignalのコンソールからメッセージ送信
- まずはここまでで、FirebaseのHostingにデプロイしてみましょう。
generateして、deployする手順は「[Nuxt v2とFirebase(CloudFirestore)でPWA対応Webアプリ開発](https://qiita.com/_takeshi_24/items/3ee051e1db1b3e8da106)」を参考にしてください。

- ブラウザでデプロイしたサイトを開くと、早速ブラウザから通知の許可が求められますので、許可します。
<img width="320" alt="通知許可" src="https://qiita-image-store.s3.amazonaws.com/0/3003/b65e488c-3c0b-2059-5499-49f1c7a67327.png">

- OneSignalのコンソールの「MESSAGES」から「NEW PUSH」を選択します。
<img width="1440" alt="NEW PUSH" src="https://qiita-image-store.s3.amazonaws.com/0/3003/a4e06052-f089-1706-18be-226ce59843c3.png">

- Send to Subscribed Usersを選択します。
<img width="1173" alt="送信先" src="https://qiita-image-store.s3.amazonaws.com/0/3003/e97f2656-9e42-6e37-63c2-cfcbb0a08707.png">

- 通知のタイトルのメッセージを入力します。
<img width="402" alt="通知内容編集" src="https://qiita-image-store.s3.amazonaws.com/0/3003/c3320c6f-588d-a0fc-2fb0-f06749a083e1.png">

- 通知タイミングを選択します。今回はテストのためすぐに送ります。
<img width="1174" alt="通知タイミング選択" src="https://qiita-image-store.s3.amazonaws.com/0/3003/c727a853-8200-13c3-b9fd-9f3261f72ab8.png">

- 「Confirm」で内容を確認し、「SEND MESSAGE」をクリックします。
<img width="603" alt="SEND MESSAGE" src="https://qiita-image-store.s3.amazonaws.com/0/3003/713c50ac-91d2-defc-46a0-8f960832a514.png">

- 通知が送信されます。PCのブラウザやスマホの画面にも通知が表示されます。
<img width="420" alt="通知スクリーンショット" src="https://qiita-image-store.s3.amazonaws.com/0/3003/faa25fc9-a051-c8ac-de0c-f8854e8c8039.jpeg">

## 特定のユーザーのみに通知を送りたい
例えばチャットWebアプリケーションなどで、メッセージを受信したときに特定のユーザーだけ通知を受け取りたいケースがあると思います。
OneSignalの通知APIを使うと、コンソールを使わなくても、特定のユーザーだけに通知を送ることができます。

### OneSignalのtagを利用して特定のユーザーに通知
#### 通知を受ける側
Nuxtのpages内のcreated()などでOneSignalのtagを設定します。
以下の例ではtagの名前を「id」とし、値に「100」を設定しています。

この例では固定の「100」をidとして設定していますが、this.currentUser.uidのようにFirebase AuthenticationのUIDなどを設定することで、ユーザーの識別が可能です。

```js
this.$OneSignal.push(['sendTag', 'id', 100, function(tagsSent) {}])
```

#### 通知を送る
OneSignalのnotificationのAPIを呼び出すことで、通知を送ることができます。
通知を送る側はNode.jsでもなんでも良いのですが、今回はNuxtのフロント側JavaScriptだけで完結するため、axiosからAPIを呼び出します。

```js
    var params = {
      method: 'post',
      url: 'https://onesignal.com/api/v1/notifications',
      headers: {
        'Content-Type': 'application/json',
        Authorization: 'Basic yyyyyyyyyyyyyyyyyyyyyyyyy'
      },
      data: {
        app_id: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx',
        headings: {
          en: 'notification test',
          ja: 'id:100の人に通知です'
        },
        contents: {
          en: 'This is notification test',
          ja: 'id:100の人に通知です'
        },
        tags: [{ key: 'id', relation: '=', value: 100 }]
      }
    }
    axios(params)
```
- headersのAuthorizationにOneSignalの認証キーを設定します。
OneSignalのコンソール画面右上の「Account & API KEYS」より「REST API Keys」を参照し、アプリのAPI Keyをコピペします。
<img width="1204" alt="スクリーンショット 2018-10-28 9.48.57.png" src="https://qiita-image-store.s3.amazonaws.com/0/3003/1ddf2f73-c6b4-c8ee-ea94-0fc024a43a08.png">

- dataのapp_idには先ほど「OneSignalにアプリを追加する」で取得したappIdを設定します。

- dataのtagsに「通知を受ける側」で設定したkey:'id'、値が100を設定します。

通知を送りたいタイミングで上記の処理を呼び出すと、id=100のユーザーだけに通知を送ることができます。

#まとめ
[Nuxt v2とFirebase(CloudFirestore)でPWA対応Webアプリ開発](https://qiita.com/_takeshi_24/items/3ee051e1db1b3e8da106)のリアルタイムチャットに続き、通知を送る処理を実装しました。

NuxtのPWA対応に続き、OneSignalを使った通知も、onesignalモジュールを使うことで簡単に実装できました。