こんにちは。ミライ工事の青山です。

先日、バックエンドからiOSのモバイルアプリに向けてVOIP通知を送信する仕組みを作りました。

基本はOneSignalのドキュメント通りに進めていけば良いのですが、いくつかハマった箇所があったので簡単に手順をメモしておきます。

OneSignal Appの作成

OneSignalのAppを作成します。

弊社の場合、すでにPUSH通知用のAppが存在していましたが、それとは別にVOIP通知用のAppを作成しました。

(公式ドキュメントにもたしかそのようにするのがおすすめされていたと思います)

注意点としては、iOSへのVOIP用のOneSignal Appを作成する時はAPNsの証明書で.p12の証明書を指定する必要があります。

.p8の証明書ではだめなので要注意。

バックエンド側にAPIを実装する

Appが作成できたら、次にVOIP通知を送信するAPIを作っていきます。

APIは2つ作る必要があります。

OneSignalにデバイスのVOIP Tokenを登録し、PlayerIDを取得するAPI

まず1つ目は、OneSignalにデバイスのVOIP Tokenを登録し、PlayerIDを取得するAPIです。

curlで実行する場合のAPIの例は次のようになります。

curl --request POST \
     --url https://api.onesignal.com/apps/your-onesignal-app-id/users \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --data '
{
  "subscriptions": [
    {
      "type": "iOSPush",
      "token": "your-voip-token",
      "test_type": 1 //omit this on Production APNS environment
    }
  ]
}
'

urlのyour-onesignal-app-idの部分には、先ほど作成したOneSignal AppのApp IDを、

“your-voip-token”の部分にiOSから取得したvoip用のtokenを指定してください。

Production環境以外のテスト環境などで動かす場合は”test_type”に1を指定してください。

このAPIが正常に実行されると、次のようなレスポンスが返ってきます。

{"identity":{"onesignal_id":ONESIGNAL_ID},"subscriptions":[{"id":PLAYER_ID,"app_id":ONESIGNAL_APP_ID,"type":"iOSPush","token":USER_VOIP_TOKEN}]}

ここで大事なものが、subscriptionsの配列に含まれているPLAYER_IDになります。

このPLAYER_IDは次のAPIで実際にVOIP通知を送信する際に必要になります。

VOIP通知の送信API

次に実際にVOIP通知を送信するAPIを作っていきます。

curlで実行する場合のAPIの例は次のようになります。

curl --include \
     --request POST \
     --header "Content-Type: application/json; charset=utf-8" \
     --header "Authorization: Basic YOUR_REST_API_KEY" \
     --data-binary "{\"app_id\": \"YOUR_VOIP_APP_ID\",
\"contents\": {\"en\": \"English Message\"},
\"apns_push_type_override\": \"voip\",
\"include_player_ids\": [\"YOUR_PLAYER_ID\"]}" \
     https://onesignal.com/api/v1/notifications

ヘッダー情報にベーシック認証の鍵としてOneSignal AppのAPI Keyを指定する必要があります(YOUR_REST_API_KEYの部分)

contentsの”English Message”の部分には任意の文字列を指定してください。この文字列がOneSignalの管理画面のSent Messagesの一覧に表示されます。

include_player_idsのYOUR_PLAYER_IDには、先ほど実行したAPIのレスポンスで受け取ったPLAYER_IDを指定して下さい。

また、VOIP通知に任意のパラメーター(ユーザー名など)を含めたい場合は、下記のようにします。

curl --include \
--request POST \
--header "Content-Type: application/json; charset=utf-8" \
--header "Authorization: Basic YOUR_REST_API_KEY" \
--data-binary '{
    "app_id": "YOUR_VOIP_APP_ID",
    "contents": {
        "en": "English Message"
    },
    "apns_push_type_override": "voip",
    "include_player_ids": [
        "YOUR_PLAYER_ID"
    ],
    "data": {
        "call_from_user_name": "山田 太郎",
        "hoge_id": "9999",
        "fuga_id": "8888"
    }
}' \
https://onesignal.com/api/v1/notifications

これで、iOSアプリに対してVOIP通知が送信されます。

送信できているか確認する

OneSignalの管理画面から「Sent Messages」の一覧を開き、Statusが「Delivered」になっていて、Sentが1になっていることを確認してください。

StatusがDeliveredになっていてもSentが0になっている場合は送信できていません。

今回はこの現象が発生し、解決に少しだけ時間がかかりました。

うまく送信できていないときに確認すること

OneSignalの管理画面から、「Subscriptions」の一覧を開きます。

ここに「Never Subscribed」と出ている場合、その端末にはVOIP通知が一生届きません。

管理画面から削除してあげる必要があります。

テストで試行錯誤しながらターミナルから何度もcurlを実行していた場合など、誤ったパラメーターでVOIP送信のAPIを実行した履歴などがあった場合にこのようなことが起きるようです。

Never Subscribedになっている限り何度APIを実行しても端末に通知は届かないのでそのような時はScbscriptionsの一覧を確認してみるといいかもです。

以上、簡単ですがバックエンドからiOSアプリにVOIP通知を送信するための方法でした。