2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

電話でテイクアウト可能なお店を聞ける電話

2
Last updated at Posted at 2020-05-22

なぜ作ったか

ハッカソンのサンプルに作りました。以下のストーリーは妄想です

今の世の中、安心して外を出歩くこともできず、Uber Eatsなどで出前を取る方も多かったのではないかと思います。
そして、テイクアウトのお店も増えてきました。スマートフォンがあれば、注文も調べることもできて、とても便利な世の中になりました。
しかし、スマートフォンを持っていないお年寄りはどうだったでしょうか?
調べることもできず、スーパーに買い出しをしにいかなければならなかったのではないでしょうか

こんなアプローチ

すごくシンプルに、電話かけて、市区町村と料理ジャンルをしゃべれば、テイクアウトできるオススメの1件の住所を教えてくれる。というもの。

ソリューション.png

準備物

  • ぐるなびのAPIキー

  • Twilioのアカウント

    • こちらで作成できます
    • 執筆時点(2020年5月22日)では、Twilioオンラインコンテストが行われており、初めてアカウントを作り、オンラインコンテストに参加する条件でポイントをもらうことができます
  • Google Cloud Platformのアカウント(手順は結構省きます)

    • こちら にアクセスしてください
    • プロジェクトを作成して、Cloud Natural Language APIを有効にする必要があります
    • APIキーの生成を行なってください

全体の流れ

TwilioStudioFlow.png
  1. 電話を着信します。
  2. 応答メッセージが流れ、市区町村、料理のジャンルを言います(今回は広島県限定)
  3. 音声認識した結果を、Googleの自然言語分析にかけて、市区町村、料理のジャンルの固有名詞を抜き出します
  4. ぐるなびのレストラン検索APIを利用して、対象のお店1件を取得します(テイクアウトでき、クレジットカードが使えるお店で検索します)
  5. 取得できたお店の名前を音声で読み上げます(一応、住所とTELも取得しています)

Twilioの基本的な使い方

  • 電話番号の取得については、こちら をご確認ください

自然言語解析で、ぐるなびを検索するためのワードを抽出するためのファンクションを作成する

Google Cloud PlatformのNatural Languageを利用するにあたり、こちら を見ていただくとよいと思います。

Twilio「Function」を設定する

Twilioの左側のメニューに「RUNTIME」Functionsというメニューがあります。
Functionsを選択してください。
TwilioFunctionNEW.png
そうすると、Functionsの詳細メニューが開きます。ベータってなんだろ・・・
TwilioFunctionConfigNew.png

設定をクリックしてください

そうすると、以下の画面が表示されます。

image.png

まず、Enable ACCOUNT_SID and AUTH_TOKENのチェックをONにしてください
image.png

次に、Functionsで利用する定数を入力します。

image.pngボタンを押すことにより、キーを追加できますので、以下を設定してください

  • ぐるなびAPIキー
    • Key
      • GNAVI_API_KEY
    • Value 値
      • ぐるなびさんから付与されたAPIキーを入力
  • ぐるなびAPIの都市コード(広島県決めうちしてます)
    • Key
      • GNAVI_PREF
    • Value 値
      • PREF34
  • Google Cloud Platformのnatural-languageのAPIキー
    • Key
      • GOOGLE_API_KEY
    • Value 値
      • Googleで取得したAPIキー

次にFunctionsで利用する追加のライブラリーの設定です。
FunctionsでHTTPリクエストを使いたい為、request-promiseを活用しています。

image.png

image.pngボタンを押すことにより、追加できますので、以下を設定してください

  • NAME
    • request-promise
  • VERSION
    • 4.2.2

最後にimage.pngボタンを押せば、設定は完了です

Twilio「Function」を作成する

次に管理をクリックします

TwilioFunctionConfigNew.png

以下の画面が表示されますので、

image.png

image.pngをクリックしてください。

以下のウィンドウが上がるので、+Blankを選択して、image.pngをクリックしてください。

image.png

こんなBlankな画面が表示されます。

image.png

自然言語解析処理のFunctionを作成する

  • FUNCTION NAME
    • NLS
  • PATH
    • /nls
  • ACCESS CONTROL
    • チェックを外す
  • EVENT
    • 何も指定しない
image.png

CODE部分には以下を貼り付けます。


const request = require('request-promise');
exports.handler = function(context, event, callback) {
    var options = { 
        method: 'POST',
        url: 'https://language.googleapis.com/v1/documents:analyzeEntities',
        qs: { key: context.GOOGLE_API_KEY },
        headers: { 
            'cache-control': 'no-cache',
            'content-type': 'application/json' 
        },
        json: { 
            document: { 
                type: 'PLAIN_TEXT', 
                content: event.text || '', 
                language: 'ja-JP' },
            encodingType: 'UTF8' },
    };

    request(options)
    .then((parsedBody) => {
        console.log(parsedBody);
        for (const entity in parsedBody.entities) {
            console.log(`${parsedBody.entities[entity].name}`);
        }
        //期待値としては、市区町村名、お店か料理のジャンルの順番でくる
        //エンティティが1つの場合、お店の名前か料理のジャンルの名前しかないという想定
        if (parsedBody.entities.length == 1) {
            callback(null, {freeword:parsedBody.entities[0].name});
        }else if (parsedBody.entities.length > 1){
            var freeword = '';
            var count = 0;
            for (const entity in parsedBody.entities) {
                if(count == 0){
                    freeword = `${parsedBody.entities[entity].name}`;
                }else{
                    freeword = freeword + ',' + `${parsedBody.entities[entity].name}`;
                }
                count++;
            }
            console.log(freeword);
            callback(null, {freeword: freeword});
        }
    })
    .catch((err) => {
        console.error(`problem with request: ${err.message}`);
        callback(err.message);
    });
};

最後にimage.pngボタンを押せば、設定は完了です

ぐるなびAPIのFunctionを作成する

以下のファンクションを新規で作成する

  • FUNCTION NAME
    • GNavi
  • PATH
    • /gnavi
  • ACCESS CONTROL
    • チェックを外す
  • EVENT
    • 何も指定しない
image.png CODE部分には以下を貼り付けます。
const request = require('request-promise');
exports.handler = function(context, event, callback) {
    //console.log(`text: ${event.text} `);
    var options = { 
        method: 'GET',
        url: 'https://api.gnavi.co.jp/RestSearchAPI/v3',
        qs: { keyid: context.GNAVI_API_KEY,takeout: '1', pref: context.GNAVI_PREF,hit_per_page: '1',card:'1',freeword: event.text},
        headers: { 
            'cache-control': 'no-cache',
            'content-type': 'application/json' 
        }
    };

    request(options)
    .then((parsedBody) => {
        console.log(`name: ${JSON.parse(parsedBody).rest[0].name},address: ${JSON.parse(parsedBody).rest[0].address},tel: ${JSON.parse(parsedBody).rest[0].tel}`);
        callback(null, {name:JSON.parse(parsedBody).rest[0].name, address:JSON.parse(parsedBody).rest[0].address, tel:JSON.parse(parsedBody).rest[0].tel});
       
    })
    .catch((err) => {
        console.error(`problem with request: ${err.message}`);
        callback(err.message);
    });

};

電話を受けて、自然言語解析、ぐるなび検索の一連の動作を作る

左側のメニューの「RUNTIME」にあるStudioをクリックします。
image.png

以下の画面が表示されるので、image.pngボタンを押します。

image.png

以下のウィンドウが表示されるので、好きな名前をつけてimage.pngボタンを押します。

image.png

以下の画面が表示されるので、Start from scratchを選択して、image.pngボタンを押します。

image.png

そうすると、まっさらなフローが立ち上がります。

image.png

右にあるメニューの中にVOICE Say/Playをクリックドラックしましょう

image.png

フローに以下のように表示されたと思います。

image.png

say_play_1と表示されているボックスをクリックし、以下の表示を確認してください。
image.png
WIDGET NAMEはお好みでいいですが、以下のように設定してください

  • WIDGET NAME
    • SayWelcome
  • TEXT TO SAY(自動音声で喋らせるワードです)
    • いらっしゃいませ、テイクアウトができるお店をお教えするサービスです

そのほかは以下のように設定しています。
image.png

image.pngボタンを押して忘れずに保存してください。

そして、TriggerにあるIncoming CallSayWelcomeとクリックドラッグで線を繋げます。以下の感じになるはずです。
image.png

次に電話から音声入力してもらい、テキストに変換する部分です。
右にあるメニューの中にVOICE Gather Input on Callをクリックドラックしましょう

image.png

これも同様に設定していきます。

image.png

WIDGET NAMEはお好みでいいですが、以下のように設定してください

  • WIDGET NAME
    • WhatAreYouLookingFor
  • TEXT TO SAY(自動音声で喋らせるワードです)
    • 市区町村、料理のジャンルを言ってください。

その他の設定は以下のようにしています。
image.png
image.pngボタンを押して忘れずに保存してください。

SayWelcomeAudio Completeから** WhatAreYouLookingFor**に接続します。

image.png

次に、Functionの呼び出しを設定します。右側メニューTOOLS & EXECUTE CODEからRun Functionをクリックドラックしてください

image.png

フローにfunction_1が配置されました。

image.png

function_1を選択して以下のように設定します。

  • WIDGET NAME
    • NLS
  • FUNCTION URL(Functionsで作成したFunction名を指定)
    • NLS

FunctionsParametersimage.png
をクリックして、以下のKey,Valueを入力します
image.png

  • Key
    • text
  • Value(** WhatAreYouLookingFor**で音声入力されたテキストデータを設定)
    • {{widgets.WhatAreYouLookingFor.SpeechResult}}

以下のように** WhatAreYouLookingForUser Said SomethingNLS**を接続します。
image.png
image.pngボタンを押して忘れずに保存してください。

もう一つFunctionの呼び出しを設定します。右側メニューTOOLS & EXECUTE CODEからRun Functionをクリックドラックしてください

image.png

function_2を選択して以下のように設定します。

  • WIDGET NAME
    • CallGNavi
  • FUNCTION URL(Functionsで作成したFunction名を指定)
    • GNavi
  • Key
    • text
  • Value(** NLS**で自然言語解析されたテキストデータを設定)
    • {{widgets.NLS.parsed.freeword}}

image.pngボタンを押して忘れずに保存してください。

NLSSuccessと** CallGNavi**を以下の図のように線を繋ぎます。

image.png

右にあるメニューの中にVOICE Say/Playをクリックドラックしましょう

image.png say_play_2と表示されているボックスをクリックし、以下の表示を確認してください。 image.png WIDGET NAMEはお好みでいいですが、以下のように設定してください
  • WIDGET NAME
    • END
  • TEXT TO SAY(自動音声で喋らせるワードです)
    • お店は{{widgets.CallGNavi.parsed.name}}でいかがでしょうか?

image.pngボタンを押して忘れずに保存してください。

** CallGNaviSuccess END**を以下の図のように線を繋ぎます。

image.png

これで完成したので、上部にあるimage.pngを押せば作業完了です。

電話番号とFlowを紐づける

右のメニューにある**#Phone Numbers**を選択します

image.png

保有している電話番号をクリックすると、以下の表示が出てきます。
A CALL COMES INを*Studio Flowに変更し、左のプルダウンのところを作成したFlowを設定します。

image.png

最後にimage.pngを押せば完成です。

あとは電話をかければ、自動的に作成したフローに接続されますので、試してみてください。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?