https://d226lax1qjow5r.cloudfront.net/blog/blogposts/build-a-voice-proxy-with-cloud-functions/voice-proxy_1200x600.png

クラウド機能でVoiceプロキシを構築する

最終更新日 July 26, 2021

所要時間:1 分

Voice Proxy(覆面通話)は、仲介電話番号を提供することで、ユーザーの個人情報を保護します。こうすることで、発信側も着信側もお互いの本当の電話番号を知ることができない。DeliverooやUberのようなデリバリーサービスやライドシェアサービスでは一般的な方法だが、中小企業の様々な場面でも重宝される。

このチュートリアルでは、私のお気に入りのユースケースのひとつであるバーチャル・ビジネスフォンを作ってみよう。

2つのコールの方向性をカバーする:

  1. Vonage番号でクライアントに電話をかけている場合:DTMFで相手先の番号を取得し、接続します。

  2. 誰かがあなたのVonage番号に電話しています。

これを機能させるために必要なのは、仮想Vonage番号と、ウェブフックを処理する小さなサーバーレス関数だけだ。

使うのは GoogleクラウドファンクションGoogleが提供するFaaS(Function-as-a-Service)を使用し、クラウドでのビルドを高速化します。

これらのイベント駆動型のサーバーレス機能では、マネージド・コンピューティング、自動スケーリング、100ミリ秒単位での従量課金が可能です。Google Cloudが運用インフラを処理する間、開発者はコードに集中することができます。

クラウドファンクションは、クラウドサービスをコードで素早く拡張するビルディングブロックと考えることができます。HTTP 経由で配信されるイベントや、他の Google Cloud Platform サービスによって発行されるイベントに応答して実行されるため、イベントベースのアーキテクチャ、データ処理、クラウドの自動化に最適です。

この例では、Google Cloud Functions のイベントベースアーキテクチャを利用して、Vonage Voice API からの HTTP リクエストをトリガーとする HTTP 関数を書いています。

前提条件

Vonage API Account

To complete this tutorial, you will need a Vonage API account. If you don’t have one already, you can sign up today and start building with free credit. Once you have an account, you can find your API Key and API Secret at the top of the Vonage API Dashboard.

This tutorial also uses a virtual phone number. To purchase one, go to Numbers > Buy Numbers and search for one that meets your needs.

Googleクラウドファンクションの設定

新しいGoogle Cloudプロジェクトを作成する

まず、新しいプロジェクトを作成します。これらのプロジェクトは、すべての Google Cloud サービスを作成、有効化、および使用するための基盤となります。

リソースの管理 リソースの管理ページを開き プロジェクトの作成.リソースの作成と管理の詳細については Google Cloud ガイド.

クラウド機能の作成

次に クラウド機能をクリックします。 関数の作成.

設定すべきフィールドがいくつかある:

  1. 関数に 名前.

  2. 地域を選択する 地域.私は europe-west-2ロンドンに近いからです。どれが一番自分に合っているかわからない場合は 利用可能な地域のリスト.

  3. 設定する トリガタイプHTTPに設定する。

  4. Allow unauthenticated invocations "と "Require HTTPS "にチェックを入れる。

完了したら、生成されたURLをコピーして 保存.

Create function config pageCreate function config page

次に ランタイム、ビルド、接続設定を展開し ランタイム環境変数.環境変数として2つの電話番号を設定する必要があります。どちらもE.164国際フォーマットです。例えば、447700900123(UK)または14155550101(US)です。

  • YOUR_VONAGE_NUMBERVonageバーチャルナンバーの一つです。お客様の Vonageダッシュボードまたは 購入する.

  • YOUR_PHONE_NUMBERテストに使用する個人の電話番号。

Set environment variablesSet environment variables

クリック 次へこれで設定は完了だ!

を選択してください。 インライン・エディターとして ソースコード最新のNode.jsを ランタイムそしてプラットフォームが警告するAPIを有効にする。

Cloud Functions Inline Editor warning about installing Cloud BuildCloud Functions Inline Editor warning about installing Cloud Build

インライン・コード・エディターには、Express.jsのリクエスト・オブジェクトとレスポンス・オブジェクトを使って生成された定型関数が表示されています。これを私たちの関数に置き換えてみましょう。関数名を変更した場合は エントリポイントも更新する必要があることに注意してください。

Voice対応Vonageアプリケーションの作成

A Vonage API アプリケーションは、Vonage エンドポイントに接続して Vonage API を使用するために必要なセキュリティ情報と設定情報を保持します。作成された各Vonageアプリケーションは複数の機能をサポートすることができますが、今はVoice機能だけが必要です。

を使用して作成してみましょう。 ボンテージダッシュボード.に移動します。 お客様のアプリケーション 新しいアプリケーションを作成する.

Voice機能をオンにして、生成されたクラウドファンクションのURLをフィールドに入力します。 Answer URLフィールドに入力します。私のはこんな感じです: https://europe-west2-my-proxy-calling-project.cloudfunctions.net/proxy-call.
今のところ、イベントウェブフックは実装しません。 http://example.com/eventを使用してください。

完了したら をクリックします。

Create Voice-enabled Vonage ApplicationCreate Voice-enabled Vonage Application

次のページでは、アカウントで利用可能なバーチャルナンバーのリストが表示されます。次のページで リンクボタンをクリックします。アプリケーションをテストするためにこの番号に電話をかけますので、まずはローカルの番号から始めましょう。また、リストが表示されない場合や適切な番号が見つからない場合は、次の方法もあります。 番号を買い足す.

Link virtual Vonage number to Vonage ApplicationLink virtual Vonage number to Vonage Application

ランタイム環境で設定した番号と異なる番号をリンクする場合は、クラウドコンソールUIの YOUR_VONAGE_NUMBERの値を更新してください。

コールフローの制御

これでVonageアプリケーションを設定したことになり、Vonageは誰かがあなたのリンクされたバーチャル番号に電話をかけるたびに、あなたのアプリケーションにGETリクエストを行います。 Answer URLに GET リクエストを行います。Vonage は コールコントロールオブジェクト(NCCO)が返されることを期待します。

NCCOは、1つ以上のアクションを含む有効なJSON配列として提示される。この例では、いくつかの異なるものを使用する:

  • その talk音声合成メッセージを通話中に再生するアクション

  • その inputDTMFトーン(ボタン押下)を検知してユーザー入力をキャプチャするアクション。DTMF入力

  • 発呼側と着呼側を接続する connect発呼側と着呼側を接続するアクション。

クラウド機能の構築

3つのケースがあるので、それに応じて3つの異なるNCCOを返す必要がある。

つのケースをカバーする必要がある:

  1. 誰かがあなたのVonage番号に電話している→あなたの電話番号に接続する

  2. Vonage番号に電話しています:

    2.1.まだDTMFペイロードを提供していない → DTMF入力をキャプチャする

    2.2.DTMFペイロードが利用可能→DTMFペイロード(宛先電話番号)にコールを接続

Google Cloud Consoleに戻り、定型コードを以下のように置き換えます。

// Get environment variables
const YOUR_VONAGE_NUMBER = process.env.YOUR_VONAGE_NUMBER;
const YOUR_PHONE_NUMBER = process.env.YOUR_PHONE_NUMBER;


exports.helloWorld = (req, res) => {
    // Check if there's DTMF payload in the request body
    if (req.body.dtmf) {
        // (2.2) Connect call to the number in the DTMF payload
    ])
    } else {
        // Check if you're the caller
        if (req.query.from === YOUR_PHONE_NUMBER) {
            // (2.1) Capture destination number via DTMF input
        } else {
            // (1) Connect caller to your phone number
        }
    }
};

それぞれのセクションを見てみよう。

1.電話を受ける:発信者を接続する

まず、他人があなたのバーチャル・ナンバーに電話をかけた場合、その電話はあなたの実際の電話番号につながるようにしたい。これは connectアクションと、オプションで talkアクションを使って実現します。

この場合、以下のNCCOを返す必要がある:

res.json([{
        action: 'talk',
        text: 'Please wait while we connect you.'
    },
    {
        action: 'connect',
        from: YOUR_VONAGE_NUMBER,
        endpoint: [{
            type: 'phone',
            number: YOUR_PHONE_NUMBER
        }]
    }
])

上記のスニペットは、このユースケースには十分すぎるほどですが、必要であれば、これらのアクションの両方をさらに設定することができます。その場合は NCCOリファレンスを参照してください。

2.電話をかける

次に、Vonage番号に電話をかけ、携帯電話のキーパッド(DTMF入力)を使って相手先の番号を入力し、入力した番号に接続された場合を処理する必要があります。

このシナリオは2段階ある。

2.1 DTMF入力をキャプチャする

まず、数字をキャプチャするアクションを含むNCCOを返す必要がある。 inputアクションを含むNCCOを返す必要がある。さらに talkアクションも追加しよう。

この talkアクションは前のステップと同じで、これもオプションです。

アクションは inputアクションは ['dtmf'].音声認識も可能です。 NCCOリファレンス.

また、デフォルトの DTMF入力設定を変更する必要があります。

  • timeOutは、発信者の最後のアクションの後、発信者のアクティビティが eventUrlに送られるまでの秒数である。デフォルトでは3秒だが、少し余裕を持たせるために最大値 10にして、少し余裕を持たせよう。

  • maxDigitsはユーザーが押すことのできる桁数で、デフォルトでは4桁です。 15の電話番号に対応します。 E.164国際フォーマットで、Vonageが電話番号に使用しているフォーマットです。例えば、イギリスの電話番号は447700900123のようになります。

  • submitOnHashキーを押した後、発信者のアクティビティを eventUrlに送信される。が押されなければ、結果は数秒後に送信される。 timeOut秒後に送信されます。デフォルトではFalseなので、必ず true.

res.json([{
        action: 'talk',
        text: 'Please enter a phone number in international format, omitting the leading plus sign. End with the pound key.'
    },
    {
        action: 'input',
        type: ['dtmf'],
        dtmf: {
            timeOut: 10,
            maxDigits: 15,
            submitOnHash: true
        },
        eventUrl: ["https://europe-west2-my-proxy-calling-project.cloudfunctions.net/proxy-call"]
    }
])

2.2 通話をDTMF入力に接続する

数字がキャプチャされると、VonageはリクエストボディにDTMFペイロードを持つエンドポイントに、デフォルトで別のリクエスト-POSTを行う。それから、2番目の connectアクションが返される必要がある。

res.json([{
        action: 'talk',
        text: 'Connecting'
    },
    {
        action: 'connect',
        from: YOUR_VONAGE_NUMBER,
        endpoint: [{
            type: 'phone',
            number: req.body.dtmf.digits
        }]
    }
])

この呼制御オブジェクトは、宛先番号を動的に設定することを除けば、最初の ものと似ている。 req.body.dtmf.digitsには DTMF ペイロードが含まれます。 Webhook リファレンスを参照してください。

完成品

最後に、すべての可動部分をまとめてみよう!これまで説明してきた3つのスニペットを最初の関数にはめ込むと、次のようなコードになる:

// Get environment variables
const YOUR_VONAGE_NUMBER = process.env.YOUR_VONAGE_NUMBER;
const YOUR_PHONE_NUMBER = process.env.YOUR_PHONE_NUMBER;

exports.helloWorld = (req, res) => {
    // Check if there's DTMF payload in the request body
    if (req.body.dtmf) {
        // (2.2) Connect call to the number in the DTMF payload
        res.json([{
                action: 'talk',
                text: 'Connecting'
            },
            {
                action: 'connect',
                from: YOUR_VONAGE_NUMBER,
                endpoint: [{
                    type: 'phone',
                    number: req.body.dtmf.digits
                }]
            }
        ])
    } else {
        // Check if you're the caller
        if (req.query.from === YOUR_PHONE_NUMBER) {
            // (2.1) Capture destination number via DTMF input
            res.json([{
                    action: 'talk',
                    text: 'Please enter a phone number in international format, omitting the leading plus sign. End with the pound key.'
                },
                {
                    action: 'input',
                    type: ['dtmf'],
                    dtmf: {
                        timeOut: 10,
                        maxDigits: 15,
                        submitOnHash: true
                    },
                    eventUrl: ["https://europe-west2-my-proxy-calling-project.cloudfunctions.net/proxy-call"]
                }
            ])
        } else {
            // (1) Connect caller to your phone number
            res.json([{
                    action: 'talk',
                    text: 'Please wait while we connect you'
                },
                {
                    action: 'connect',
                    from: YOUR_VONAGE_NUMBER,
                    endpoint: [{
                        type: 'phone',
                        number: YOUR_PHONE_NUMBER
                    }]
                }
            ])
        }
    }
};

準備ができたら をクリックします。.デプロイに1分ほどかかるかもしれませんが、我慢してください。)関数の横に緑色のチェックマークが表示されたら、テストする準備は完了です!

Function deployedFunction deployed

あなたの電話転送サービスは生きているので、それを呼び出します!さらに良い方法は、友人にバーチャル番号を鳴らしてもらうことです。

次はどこだ?

おめでとうございます!あなたはたった1つの小さなGoogle Cloud Functionでプロキシコールサービスを構築した!

さらに上を目指したいですか?通話録音を必要とするユースケースをお持ちですか?複数の番号でサービスを利用できますか?音声入力とDTMF入力の両方に対応していますか?

以下のリソースを見て、それをどのように拡大できるか考えてみてください。あなたの考えをぜひお聞かせください!

リソース

将来的には、ローカルで関数を開発し、テストしたいと思うかもしれません。クラウド関数 ローカル開発ガイドをご覧ください。

シェア:

https://a.storyblok.com/f/270183/372x373/36054b72d0/julia-biro.png
Julia Biroデベロッパー・アドボケイト

Juliaは、チュートリアル、ガイド、実用的なリソースを作成することで、仲間の開発者に力を与えることに尽力しています。アウトリーチと教育のバックグラウンドを持つ彼女は、テクノロジーをより身近なものにし、開発者の経験全体を向上させることを目指しています。地域のコミュニティイベントでもよく見かける。