早くやってみましょう:DialogflowとVoximplantの音声ボット

音声ボットは、顧客と通信するための便利な機能であり、これからも変わりません。 何かを自動化できる場合は、緊急に行う必要があるためです。 注文と注文に関する情報の確認、顧客からのフィードバックの記録、音声認識と認識された内容に応じたアクションなど ちなみに、後者については-2018年に認識のあるボットを作成するのがさらに簡単になりました:Voximplantは音声の認識と転写に非常に優れており、Good CorporationのDialogflowツールはテキストをよく分析します。 以下に、指定された都市の天気を伝えるデモボットをすばやく収集する方法を示します。











「デモ」ボットはなぜですか?



原理だから。 この記事では、Dialogflow + Voximplantでボット作成する原理を示します。 したがって、たとえば、ボットとの対話は簡単になります。



ボット: -こんにちは、Habrauser! モスクワや他の都市の天気はどうですか。

Habrauser: -ロンドンの天気はどうですか?

ボット: -今日ロンドンの街で-曇り。



Voximplantを使用すると、電話番号を借りたり、音声を認識して文字起こししたり、Dialogflowやopenweathermap.orgサービスとやり取りしたりできます。 ユーザーの応答から書き起こされた文字列をDialogflowに送信します。その後、NLP(Natural Language Processing)がJSONに返されます。JSONには主格の都市名が含まれます。 openweathermap.orgに都市の名前を付けます。openweathermap.orgは、その都市の天気がどのようなものかを教えてくれます。



シークレットエージェントNLPを作成する



Dialogflowは、Googleが所有する強力なNLPサービスです。 このサービスは無料ですが、使用するにはGoogleアカウントが必要です。 https://dialogflow.com/にアクセスして登録します。 サービスは「エージェント」の概念を使用します-実際、エージェントはボットです。 デフォルトでは、新しいアカウントにはエージェントがありません。 サービスには事前構築エージェントがありますが、すぐに追加することはできません。 したがって、インストール済みのエージェントにアクセスするためだけに新しいエージェントを作成します。 松葉杖のように聞こえますが、信じてください、これです。











エージェントの名前を入力します。他のパラメーターはデフォルトで残すことができます。 Googleプロジェクトフィールドは、Firebaseのプロジェクトを意味します(Firebaseプロジェクトがない場合は、新しいプロジェクトが作成されます)。 [作成]をクリックしてDialogflowコンソールに入ります。これはサービスのメイン画面の名前です。 左側には垂直メニューがあり、[エージェントの事前構築]をクリックし、天気エージェントを見つけて[インポート]をクリックします。 完了しました。アカ​​ウントに天気エージェントが追加されました。



デフォルトでは、エージェントは英語のみをサポートしているため、エージェントを編集に使用します(同時に必要に応じて名前を変更できます)。[言語]タブに移動し、ロシア語を追加して[保存]をクリックします。



現在、エージェントは言語を選択できます。 悲しいかな、エージェントはロシア語で「箱から出して」通信する方法を知りませんが、何も教えません。 「ru」をクリックしてロシア語をアクティブにし、「Intents」で失敗します。









表示されるインテントリストで、一番上の天気を選択します。 新しい画面には、ユーザーのセクションが表示されます。ユーザーのレプリカがあるはずです。バリエーションが多いほど良いです。 今のところ、「モスクワの天気はどうですか」というフレーズで管理します。 入力すると、Dialogflowはほぼ即座に都市名を強調表示し、返されたJSONで対応を割り当てます! 必ずコードでこれを使用してください。 また、この画面では、コンテキスト/会話トピックの名前-天気を見ることができます。









これで、エージェントの動作をDialogflowサービス(右上隅、今すぐ試す)で確認するか、cURLを介してリクエストを行うことができます。 ドキュメントを少なくするために、ここでcURLと返されたJSONの例を見ることができます。



リクエスト:



curl 'https://api.dialogflow.com/v1/query?v=20170712&query=%D0%BA%D0%B0%D0%BA%D0%B0%D1%8F%20%D0%BF%D0%BE%D0%B3%D0%BE%D0%B4%D0%B0%20%D0%B2%20%D0%9C%D0%BE%D1%81%D0%BA%D0%B2%D0%B5%3F&lang=ru&sessionId=e2c9fe05-6219-4317-ae96-2dbb6a429df4&timezone=Europe/Moscow' -H 'Authorization:Bearer d146627e5ef843fc9757028t410faa80'
      
      





クエリテキストはURIエンコードする必要があり、ヘッダーでキーを渡す必要があることに注意してください(キーはエージェント設定で見つけることができます)。 コンテキストがリクエストで指定されている場合、コンテキストを「ミックス」しないように、後続のすべてのリクエストに一意のセッション番号を設定することをお勧めします。



リクエストへの応答:



ダイアログフロー応答
{
"id": "bd0e979f-6c70-49f5-8f33-54a75b7f5a0d",
"timestamp": "2018-02-09T09:58:17.638Z",
"lang": "ru",
"result": {
"source": "agent",
"resolvedQuery": " ?",
"action": "weather",
"actionIncomplete": false,
"parameters": {
"date-time": "",
"geo-city": ""
},
"contexts": [
{
"name": "weather",
"parameters": {
"date-time.original": "",
"geo-city": "",
"date-time": "",
"geo-city.original": "?"
},
"lifespan": 2
}
],
"metadata": {
"intentId": "f1b75ecb-a35f-4a26-88fb-5a8049b92b02",
"webhookUsed": "false",
"webhookForSlotFillingUsed": "false",
"intentName": "weather"
},
"fulfillment": {
"speech": "",
"messages": []
},
"score": 1.0
},
"status": {
"code": 200,
"errorType": "success",
"webhookTimedOut": false
},
"sessionId": "e2c9fe05-6219-4317-ae96-2dbb6a429df4"
}




このリクエストは、クラウドシナリオから次のようになります。



 const sessionId = () => Math.floor(100000 * Math.random()); Net.httpRequest("https://api.dialogflow.com/v1/query?v=20150910&contexts=weather&query=" + encodeURI(userSpeech) + "&lang=ru&sessionId=" + sessionId() + "&timezone=Europe/Moscow", (e) => { //   JSON    }, { headers: ["Authorization: bearer d146627e5ef843fc9757028t410faa80"]});
      
      





天気を尋ねる



都市がわかったので、天気をリクエストできます。 私は非常にシンプルなopenweathermap.org APIを使用しました。 登録してAPIキーを取得し、次の形式のリクエストを作成できます。



 curl 'https://api.openweathermap.org/data/2.5/weather?q={CITY NAME}&lang=ru&appid={API_KEY}'
      
      





答えから、「曇り」/「曇り」/「小雪」など、説明フィールドから天気の最も単純な説明を取得します。



openweathermapレスポンス
{
"coord": {
"lon": 37.62,
"lat": 55.75
},
"weather": [{
"id": 600,
"main": "Snow",
"description": " ",
"icon": "13d"
}],
"base": "stations",
"main": {
"temp": 266.65,
"pressure": 1026,
"humidity": 85,
"temp_min": 266.15,
"temp_max": 267.15
},
"visibility": 6000,
"wind": {
"speed": 4,
"deg": 130
},
"clouds": {
"all": 90
},
"dt": 1518168600,
"sys": {
"type": 1,
"id": 7325,
"message": 0.0263,
"country": "RU",
"sunrise": 1518152808,
"sunset": 1518186090
},
"id": 524901,
"name": "Moscow",
"cod": 200
}




天気がわかれば、この情報を呼び出しに統合できます。



すべて一緒に今..!



これらのすべてのステップをJavascriptスクリプトに反映するときが来ました。 それで、私たちは何をしたいのですか?



  1. ユーザーはレンタル番号に電話をかけます。
  2. ユーザーは「Hello、Habrauser! モスクワや他の都市の天気はどうですか。」
  3. 「{CITY NAME}の天気はどうですか」と尋ねられた場合、クラウドはリクエストを認識し、Dialogflowの結果の行でリクエストを行います。
  4. 回答を受け取った後、応答にテーマ天気の存在と、回答が都市であるかどうかを確認します。 何かがうまくいかなかった場合、ロボットはそれについて話し、再び天気について質問するように求めます。
  5. Dialogflowからの回答に都市がある場合、クラウドはopenweathermap.orgに変わり、この都市をリクエストに置き換えます。
  6. 天気に関する応答を受け取った後、ユーザーに「今日の街{都市名}-曇り/曇り/小雪」を告げて電話を切ります。


次のコードはこのロジックを提供します。



Voximplant JSシナリオ
require(Modules.ASR);
let mycall = null;
VoxEngine.addEventListener(AppEvents.CallAlerting, (e) => {
mycall = e.call;
mycall.addEventListener(CallEvents.Connected, handleCallConnected);
mycall.answer();
});
function handleCallConnected() {
mycall.say(", ! , .", Language.RU_RUSSIAN_FEMALE);
myasr = VoxEngine.createASR({
lang: ASRLanguage.RUSSIAN_RU
});
mycall.addEventListener(CallEvents.PlaybackFinished, function onWelcomeFinished() {
mycall.sendMediaTo(myasr);
mycall.removeEventListener(CallEvents.PlaybackFinished, onWelcomeFinished);
});
mycall.addEventListener(CallEvents.Disconnected, VoxEngine.terminate);
myasr.addEventListener(ASREvents.Result, (e) => {
recognitionEnded();
const userSpeech = e.text;
const sessionId = () => Math.floor(100000 * Math.random());
Net.httpRequest("https://api.dialogflow.com/v1/query?v=20150910&contexts=weather&query=" +
encodeURI(userSpeech) +
"&lang=ru&sessionId=" + sessionId() + "&timezone=Europe/Moscow", (e) => {
const res = JSON.parse(e.text);
if (!res.result || res.result.action !== "weather"){
mycall.say("- . .", Language.RU_RUSSIAN_FEMALE);
mycall.addEventListener(CallEvents.PlaybackFinished, firstPlaybackFinished);
}
else if (!res.result.parameters || !res.result.parameters["geo-city"] ){
mycall.say(" .", Language.RU_RUSSIAN_FEMALE);
mycall.addEventListener(CallEvents.PlaybackFinished, firstPlaybackFinished);
}
else {
const city = res.result.parameters["geo-city"];
Net.httpRequest("https://api.openweathermap.org/data/2.5/weather?q=" +
city +
"&lang=ru&appid=a9fa46a8d49e57dbb4ba2d60cb934782", (e) => {
const weather = e.text;
const weatherDescription = JSON.parse(weather);
mycall.say(" " + city + " - " + weatherDescription.weather[0].description, Language.RU_RUSSIAN_FEMALE);
mycall.addEventListener(CallEvents.PlaybackFinished, () => {
VoxEngine.terminate();
});
});
}
},
{ headers: ["Authorization: bearer d546027e5ef843ec9757018e410f4a87"]});
});
}
function recognitionEnded(){
myasr.stop();
}
function firstPlaybackFinished() {
mycall.removeEventListener(CallEvents.PlaybackFinished, firstPlaybackFinished);
handleCallConnected();
}




Voximplantコントロールパネルで「アプリケーション」を作成し 、作成したスクリプトとレンタル番号を添付するだけです(詳細については、 当社のWebサイトをご覧ください)。



All Articles