https://a.storyblok.com/f/270183/159917/0930668b8e/nexmo-firebase-android-app-voice.png

Firebaseを使ってAndroidアプリで電話をかけたり受けたりする

最終更新日 May 20, 2021

所要時間:2 分

Nexmo In-App Voiceを使えばNexmo Stitch Android SDKとWebRTC技術を使って、簡単に電話をかけたり受けたりすることができます。このチュートリアルでは、発信と着信が可能なシンプルなAndroidアプリの作り方をご紹介します。この機能は、顧客がアプリから離れることなく、カスタマーサービスに電話をかけたり受けたりしたい場合に使用できます。

アプリを立ち上げて実行するには、次のようにします。 Firebase Functionsをホストするために NCCOをホストし JWTを返します。

このブログ記事に従うには、JavaScriptの知識があり、Kotlinを使ってAndroidアプリを構築できる必要がある。

始める前に

始める前に必要なものがいくつかある。

Firebase Functionを設定します。

まず、Firebaseファンクションプロジェクト用に新しいディレクトリを作成し、設定ファイルを格納します。

mkdir firebase-functions-nexmo-in-app-calling cd firebase-functions-nexmo-in-app-calling

新しいディレクトリが作成されたので、Firebase が提供する のセットアップ手順に従ってで提供されている手順に従い、新しいプロジェクトを作成します。

npm install -g firebase-tools firebase login firebase init functions

このプロジェクトでは、TypeScriptではなくJavaScriptを使うことにした。

私のように、コマンドラインからfirebaseのファンクションプロジェクトを作成できなかった場合は、以下のサイトを参照してください。 Firebaseコンソールにアクセスして新しいプロジェクトを作成し、コマンドラインから firebase use --addをコマンドラインから実行してください。

Firebase関数を編集する

Firebase Functions で使用するメソッドの最終バージョンは、Gitub のこのデモの にあります。要するに、3つのエンドポイントが必要です:

  1. NCCOをホストするアンサーURL

  2. Voice APIからイベントを取得するためのイベントURL。

  3. ユーザーがログインするためのJWTを返すURL

Firebaseの関数を編集するには、新しい関数の index.jsファイルを編集する必要があります。 functions/ディレクトリにあるファイルを編集する必要があります。 firebase init functions

まず、アンサーメソッドを見てみよう。

exports.answer = functions.https.onRequest((request, response) => {
  //use the `to` query parameter that Nexmo gives us to make a call.
  //if `to` is null, then we are receiving a call.
  var to = request.query.to
  var from = request.query.from

  var ncco = [];

  if (to) {
    ncco.push(
      {
        action: "talk",
        text: "Thank you for calling, you are now being connected."
      },
      {
        "action": "connect",
        "from": functions.config().nexmo.from_number,
        "endpoint": [
          {
            "type": "phone",
            "number": `${to}`
          }
        ]
      }
    )
  } else {
    ncco.push(
      {
        action: "talk",
        text: "You are being connected to the Customer."
      },
      {
        "action": "connect",
        "from": from,
        "endpoint": [
          {
            "type": "app",
            "user": "Customer"
          }
        ]
  
      })
  }
  response.json(ncco);
});

NexmoのVoice APIは1つのアプリケーションにつき1つの応答URLを使用するため、queryパラメータがnullの場合、着信コールを受け入れるためのNCCOを動的に表示することができます。 toを動的に表示できます。もし toクエリパラメータが でない場合でない場合は、発信のNCCOを表示します。

ユーザーにJWTを提供するためのエンドポイントは、非常に簡単です。私たちは Nexmo Nodeライブラリを使ってJWTを生成します。ライブラリを使用するには、パッケージをインストールする必要があります。

#package.jsonとindex.jsファイルがある/functionsディレクトリにいることを確認する npm install nexmo

ライブラリのインストール後、すべてが正しく動作していることを確認するには package.jsonファイルを検査することで、すべてが正しく動作していることを確認できる。以下のようになるはずだ:

"dependencies": {
    "firebase-admin": "~5.12.1",
    "firebase-functions": "^1.0.3",
    "nexmo": "^2.3.2"
  }

Nexmo Nodeライブラリがインストールされたら、jwtエンドポイントで次のように使用して、有効な user_jwt.

exports.jwt = functions.https.onRequest((request, response) => {
    response.json({
      user_jwt: Nexmo.generateJwt("private.key", {
        application_id: functions.config().nexmo.application_id,
        sub: "Customer",
        exp: new Date().getTime() + 86400,
        acl: adminAcl
      })
    });
});

Firebaseの関数ができたので、次はVonageのアプリケーションを作ってみよう。

Firebase関数をデプロイする

Firebase Functions が書き終わったので、Firebase プロジェクトをデプロイします。Functions をデプロイすると、Firebase がアンサーとイベントのエンドポイントの URL を教えてくれます。これらの URL を使って Vonage アプリケーションを作成します。

#このチュートリアルの最初に作成したfirebase-functions-nexmo-in-app-calling/ディレクトリにいることを確認する firebase deploy --only functions

関数[answer]:作成操作に成功しました。関数のURL(answer):https://your-project-name.cloudfunctions.net/answer ✔ functions[event]:作成操作に成功しました。関数URL(イベント):https://your-project-name.cloudfunctions.net/event ✔ functions[jwt]:functions[jwt]:作成に成功しました。関数URL(jwt):https://your-project-name.cloudfunctions.net/jwt

Vonageアプリケーションを設定します。

アプリケーションを作成するには、まずこのコマンドでVonage CLIをグローバルにインストールします:

npm install @vonage/cli -g

次に、Vonage API キーとシークレットを使って CLI を設定します。この情報は 開発者ダッシュボード.

vonage config:set --apiKey=VONAGE_API_KEY --apiSecret=VONAGE_API_SECRET

では、前のセクションでFirebaseが提供してくれたアンサーとイベントURLを使います。

# Ensure you're in the firebase-functions-nexmo-in-app-calling/ directory we created at the beginning of this tutorial
vonage apps:create 
✔ Application Name … ruling_narwhal
✔ Select App Capabilities › Voice
✔ Create voice webhooks? … yes
✔ Answer Webhook - URL … https://your-project-name.cloudfunctions.net/answer
✔ Answer Webhook - Method › POST
✔ Event Webhook - URL … https://your-project-name.cloudfunctions.net/event
✔ Event Webhook - Method › POST
✔ Allow use of data for AI training? Read data collection disclosure - https://help.nexmo.com/hc/en-us/articles/4401914566036 … no
Creating Application... done
Application Name: ruling_narwhal

秘密鍵は作成したfunctionsディレクトリに保存されます。鍵はプロジェクトと同じ名前になります。

アプリケーションIDを記録し、秘密鍵を "functions "ディレクトリに保存する。その際 your_private_key_name.key.nexmo-appファイルを .gitignore.

ベストプラクティスに従って、Firebase CLI経由でFirebaseの環境変数を保存します。Firebaseのドキュメントに に環境設定の概要があります。

ここで、firebase CLIを使って、VonageのアプリケーションIDをfirebase configに保存する必要がある。

firebase functions:config:set nexmo.application_id="aaaaaa-bbbb-cccc-dddd-0123456789ab"

注意:Firebaseは設定変数のキーを小文字にすることを要求しているので、変数名にはスネークケースを使用する。

お望みであれば、Vonage アプリケーションの .nexmo-appファイルにある秘密鍵文字列をアップロードすることもできます。 your_private_key_name.keyとしてアップロードすることもできます。

電話番号とユーザーをアプリケーションにリンク

さて、関数が書けたので、ユーザーがその番号から発信し、誰かがその番号にダイヤルするたびにAndroidアプリで着信を受け取れるように、番号を購入する必要があります。また、その番号をVonageアプリにリンクさせる必要があります。

Vonageから電話番号をレンタルするには、次のコマンドを使用します(国コードをあなたのコードに置き換えてください)。例えば、アメリカにいる場合は、次のように置き換えます。 GBUS:

vonage numbers:search US vonage numbers:buy [NUMBER] [COUNTRYCODE]

その番号をアプリにリンクさせる:

vonage apps:link --number=VONAGE_NUMBER APP_ID

Androidプロジェクトのセットアップ

Androidアプリの完成したプロジェクトをご覧になりたい方は、GitHubでソースコードをご覧いただけます。 GitHubのソースコードをご覧ください。

まずは必要なライブラリを追加します。ここではNexmo Stitch Android SDK、Retrofit、そしてRetrofitのMoshi Converterを使います。

dependencies {
  implementation 'com.nexmo:stitch:1.8.0'
  implementation 'com.squareup.retrofit2:retrofit:2.4.0'
  implementation "com.squareup.retrofit2:converter-moshi:2.4.0"
}

私たちは レトロフィットを使って GETFirebase CLI が提供してくれた Firebase 関数の JWT エンドポイントにリクエストします。

//FirebaseFunctionService.kt
interface FirebaseFunctionService {
    @GET("jwt")
    fun getJWT(): Call<UserJWT>
}


//RetrofitClient.kt
var retrofitClient = Retrofit.Builder()
        .baseUrl("https://your-project-name.cloudfunctions.net/")
        .addConverterFactory(MoshiConverterFactory.create())
        .build()

var retrofitService = retrofitClient.create<FirebaseFunctionService>(FirebaseFunctionService::class.java)

ログインアクティビティの追加

Retrofitをセットアップしたら、それを使ってJWT Firebase関数のエンドポイントからJWTを取得します。 LoginActivity.ここでは ハッピーパスユーザーJWTを取得し、それを使ってNexmo Stitch Android SDKにログインしたときのハッピーパスを示します。 このアクティビティのレイアウトはGitHubにあります。.

class LoginActivity : BaseActivity(), RequestHandler<User>, Callback<UserJWT> {
    override fun onCreate(savedInstanceState: Bundle?) {
        ...
        loginBtn.setOnClickListener {
            login()
        }
    }

    private fun login() {
        showProgress(true)
        retrofitService.getJWT().enqueue(this)
    }

    //Successfully retrieved a JWT from the Firebase Function endpoint
    override fun onResponse(call: Call<UserJWT>?, response: Response<UserJWT>?) {
        val jwt = response?.body()?.user_jwt
        client.login(jwt, this)
    }

    //User successfully logged in with the Nexmo Stitch SDK
    override fun onSuccess(result: User?) {
        goToCallActivity()
    }

}

コールアクティビティの追加

電話番号の入力、電話の開始、終了のためのシンプルなレイアウトを追加します。 このアクティビティのレイアウトはGitHubにあります。.前回と同じように、電話をかけたり受けたりする幸せな経路を示します。

class CallActivity : BaseActivity(), RequestHandler<Call> {
    private var currentCall: Call? = null
    private lateinit var client: ConversationClient

    override fun onCreate(savedInstanceState: Bundle?) {
        ...
        client = Stitch.getInstance(this).conversationClient

        attachIncomingCallListener()
        callControlBtn.setOnClickListener { callPhone() }
    }

    private fun attachIncomingCallListener() {
        //Listen for incoming calls
        client.callEvent().add({ incomingCall ->
            logAndShow("answering Call")
            //Answer an incoming call
            incomingCall.answer(object : RequestHandler<Void> {
                override fun onError(apiError: NexmoAPIError) {
                    logAndShow("Error answer: " + apiError.message)
                }

                override fun onSuccess(result: Void) {
                    currentCall = incomingCall
                    attachCallStateListener(incomingCall)
                    showHangupButton()
                }
            })
        })
    }

    private fun attachCallStateListener(incomingCall: Call) {
        //Listen for incoming member events in a call
        val callEventListener = ResultListener<CallEvent> { message ->
            logAndShow("callEvent : state: " + message.state + " .content:" + message.toString())
        }
        incomingCall.event().add(callEventListener)
    }


    private fun callPhone() {
        val phoneNumber = phoneNumberInput.text.toString()

        client.callPhone(phoneNumber, object : RequestHandler<Call> {
            override fun onError(apiError: NexmoAPIError) {
                logAndShow("Cannot initiate call: " + apiError.message)
            }

            override fun onSuccess(result: Call) {
                currentCall = result
                showHangupButton()

                when (result.callState) {
                    Call.CALL_STATE.STARTED -> logAndShow("Started")
                    Call.CALL_STATE.RINGING -> logAndShow("Ringing")
                    Call.CALL_STATE.ANSWERED -> logAndShow("Answered")
                    else -> logAndShow("Error attaching call listener")
                }

            }
        })
    }

}

ご覧のように、Nexmo Stitch SDKは電話の発信と応答という大変な仕事をこなしてくれます。

どのように機能するのか?

電話を受ける

ユーザーが前節で購入した番号に電話をかけると、NexmoはNCCOをアンサーURLの https://your-project-name.cloudfunctions.net/answer.NCCOは次のように表示される:

[  
   {  
      "action":"talk",
      "text":"You are being connected to the Customer."
   },
   {  
      "action":"connect",
      "endpoint":[  
         {  
            "type":"app",
            "user":"Customer"
         }
      ]
   }
]

このNCCOは、Stitch SDKを使ってアプリ内に作成した "Customer "ユーザーに電話をかけます。のCall Listenerをアタッチすることで、アプリが呼び出しに応答する処理を行います。 attachIncomingCallListener()簡単のため、ここでは自動的に電話に出ることにしますが、ユーザーが電話に出たり、電話に出なかったりできるように、UIとロジックを実装することもできます。 reject()を実装することができます。

電話をかける

ユーザーが電話をかけることを選択した場合、それを callPhone()メソッドで処理します。例えば、私たちのメソッドがこのように呼び出されたとします:

client.callPhone("14155550100", callback)

では client.callPhone(phoneNumber, callback)メソッドメソッドは、Stitch APIを使用して、以下のクエリパラメータであなたの回答URL にリクエストします。 GETを使用し、以下のクエリパラメータで https://your-project-name.cloudfunctions.net/answer にリクエストします:

?from=16625461410\ &to=14155550100\ &conversation_uuid=CON-4e977dab-2abc-42b5-bf64-d468d4763e54\ &uuid=0666edbe58077d826944a7c1913da2b0

この toパラメータを使って、Nexmoにどの電話番号に電話をかけるかを伝えるNCCOを動的に返すことができます。Stitch APIは以下のようなNCCOレスポンスを見ることになる:

[  
   {  
      "action":"talk",
      "text":"Thank you for calling, you are now being connected."
   },
   {  
      "action":"connect",
      "from":"12013753230",
      "endpoint":[  
         {  
            "type":"phone",
            "number":"14155550100"
         }
      ]
   }
]

この場合 fromとして設定した番号です。 nexmo.from_numberに設定した番号です。の値は number配列の endpoint配列のkeyの値は、ユーザーが電話をかけたい番号です。

自分で試してみる

このサンプルプロジェクトのリポジトリには Firebase Functions と Android Sample app の両方のソースコードが含まれています。プロジェクトをクローンして確認してください!

次はどうする?

で電話をかけたり受けたりする方法を学びました。 Nexmo In-App Voiceでの電話のかけ方と受け方アプリ内メッセージング アプリ内メッセージング.

Nexmo Stitch Android SDKの詳細については、以下のドキュメントをご覧ください。 SDKドキュメント.

私たちの Voice APIは、単に通話を接続したり受信したりするだけでなく、他の可能性も提供しています!通話の録音、音声ストリームの再生など、詳しくはドキュメントをご覧ください。

シェア:

https://a.storyblok.com/f/270183/150x150/a3d03a85fd/placeholder.svg
Chris Guzmanヴォネージの卒業生

クリスはNexmoのデベロッパー・アドボケイトとして、デベロッパーがグローバル・コミュニケーション・プラットフォームを使えるようにサポートしている。カンファレンスに出席していないときは、世界中を歩き回っている。