次は、AsterNET.ARIを使って、IVR(音声自動応答)に挑戦してみます。
1.まず、IVRで使用する音声データを用意します。形式は色々ありますが、Windows標準音声ファイル形式であるWAV形式が適当でしょう。ここでは、歯科予約IVRを想定して、以下の8種類のガイダンスメッセージを用意します。
-
「お電話ありがとうございます。アグリモ歯科です。」
-
「ご予約の日付を4桁で入力し、最後に#を入力してください。例えば、6月1日の場合は、0601#と入力してください。どうぞ。」
-
「ご予約の時間を2桁で入力し、最後に#を入力してください。例えば、17時の場合は、17#と入力してください。どうぞ。」
-
「ご予約内容の確認をさせていただきます。ご予約の日時は、」
-
「ですね。よろしければ1と#を、もう一度やり直す場合は2と#を、入力してください。」
-
「ご予約を賜りました。ご予約番号は、」
-
「です。ご来院をお待ちしております。有難うございました。」
-
「認識できません。もう一度、入力してください。」
2.FreePBXにログインして、メニュー「Admin」-「Sound Language」を選択します。
3.「Custom Language」をクリックします。
4.「+ Add New Custom Language」をクリックします。
5.「Language Code」欄に「ja」と入力し、「Browse」をクリックます。
6.音声ファイルを全部選択し、「開く」をクリックします。
7.音声ファイルのアップロードが終わったら、「Convert to」で「g722」と「ulaw」のみ選択し、右下の「Submit」をクリックします。(※「wav」は非選択にします。)
8.「OK」をクリックします。
9.音声ファイルの「WAV」形式が「g722」形式と「ulaw」形式にコンバートされます。
10.New Custom Language が登録されました。実際の保存場所は、/var/lib/asterisk/sounds/ja の中です。
11.Visual Studio を開いて、いよいよ本題、AsterNET.ARIに挑戦してみる。で使用したソースプログラム(program.cs)をIVR用に変更します。
12.「開始」をクリックして実行してみます。正常に接続できている場合は、コマンドプロンプト画面内に「Connection state is now True」と表示されます。
13.内線1000番へ電話を掛け、IVRが動作していることを確認できれば完了です。
【ソース(program.cs)】 ※このソースプログラムはサンプルです。完全動作するものではありません。
using System;
using AsterNET.ARI.Models;
namespace AsterNET.ARI.TestApplication
{
internal class Program
{
public static AriClient ActionClient;
public static Playback playback;
public static string ChannelID;
public static string dtmf_str;
public static string [] yoyaku_hiduke = new string [100];
public static string [] yoyaku_jikan = new string[100];
public static string sentaku;
public static int yoyaku_no = 1;
private static void Main(string[] args)
{
try
{
// Create a new Ari Connection
ActionClient = new AriClient(
new StasisEndpoint("192.168.24.200", 8088, "test_user", "test_password"),
"HelloWorld");
// Hook into required events
ActionClient.OnChannelDtmfReceivedEvent += ActionClientOnChannelDtmfReceivedEvent;
ActionClient.OnConnectionStateChanged += ActionClientOnConnectionStateChanged;
ActionClient.OnPlaybackFinishedEvent += ActionClient_OnPlaybackFinishedEvent;
ActionClient.OnPlaybackStartedEvent += ActionClient_OnPlaybackStartedEvent;
ActionClient.OnStasisStartEvent += c_OnStasisStartEvent;
ActionClient.OnUnhandledException += ActionClient_OnUnhandledException;
ActionClient.Connect();
Console.ReadKey();
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
Console.ReadKey();
}
}
private static void ActionClient_OnUnhandledException(object sender, Exception exception)
{
//Console.WriteLine("ActionClient_OnUnhandledException: " + exception.Message);
}
private static void ActionClient_OnPlaybackFinishedEvent(IAriClient sender, PlaybackFinishedEvent e)
{
// Play IVR Voices
switch(playback.Id)
{
case "onsei1":
playback = sender.Channels.Play(ChannelID, "sound:onsei2", "ja", 0, 0, "onsei2");
sender.Channels.Record(ChannelID, "recode_onsei1", "wav", 0, 10000, "overwrite", true, "#");
//playback = sender.Channels.Play(ChannelID, "sound:onsei8", "ja", 0, 0, "onsei1");
break;
case "onsei2":
playback = sender.Channels.Play(ChannelID, "sound:onsei3", "ja", 0, 0, "onsei3");
sender.Channels.Record(ChannelID, "recode_onsei2", "wav", 0, 10000, "overwrite", true, "#");
//playback = sender.Channels.Play(ChannelID, "sound:onsei8", "ja", 0, 0, "onsei2");
break;
case "onsei3":
playback = sender.Channels.Play(ChannelID, "sound:onsei4", "ja", 0, 0, "onsei4");
break;
case "onsei4":
playback = sender.Channels.Play(ChannelID, string.Format("sound:digits/{0}", yoyaku_hiduke[yoyaku_no].Substring(0, 2).ToString()), "ja", 0, 0, "yoyaku-hiduke1");
Console.WriteLine(string.Format("予約日時: {0}月{1}日の{2}時",
yoyaku_hiduke[yoyaku_no].Substring(0, 2),
yoyaku_hiduke[yoyaku_no].Substring(2, 2),
yoyaku_jikan[yoyaku_no]));
break;
case "yoyaku-hiduke1":
playback = sender.Channels.Play(ChannelID, string.Format("sound:digits/{0}", yoyaku_hiduke[yoyaku_no].Substring(2, 2).ToString()), "ja", 0, 0, "yoyaku-hiduke2");
break;
case "yoyaku-hiduke2":
playback = sender.Channels.Play(ChannelID, string.Format("sound:digits/{0}", yoyaku_jikan[yoyaku_no].Substring(0, 2).ToString()), "ja", 0, 0, "yoyaku-jikan");
break;
case "yoyaku-jikan":
playback = sender.Channels.Play(ChannelID, "sound:onsei5", "ja", 0, 0, "onsei5");
sender.Channels.Record(ChannelID, "recode_onsei3", "wav", 0, 10000, "overwrite", true, "#");
//playback = sender.Channels.Play(ChannelID, "sound:onsei8", "ja", 0, 0, "onsei1");
break;
case "onsei5":
playback = sender.Channels.Play(ChannelID, "sound:onsei6", "ja", 0, 0, "onsei6");
break;
case "onsei6":
playback = sender.Channels.Play(ChannelID, string.Format("sound:digits/{0}", yoyaku_no.ToString()), "ja", 0, 0, "yoyaku-bangou");
Console.WriteLine("選択: " + sentaku);
Console.WriteLine("予約番号: " + yoyaku_no);
yoyaku_no += 1;
break;
case "yoyaku-bangou":
playback = sender.Channels.Play(ChannelID, "sound:onsei7", "ja", 0, 0, "onsei7");
break;
case "onsei7":
sender.Channels.Hangup(ChannelID, "normal");
break;
//case "onsei8":
// break;
default:
break;
}
}
private static void ActionClient_OnPlaybackStartedEvent(IAriClient sender, PlaybackStartedEvent e)
{
Console.WriteLine("Playing playbackId: " + playback.Id);
}
private static void ActionClientOnConnectionStateChanged(object sender)
{
Console.WriteLine("Connection state is now {0}", ActionClient.Connected);
}
private static void ActionClientOnChannelDtmfReceivedEvent(IAriClient sender, ChannelDtmfReceivedEvent e)
{
// When DTMF received
switch (e.Digit)
{
case "*":
break;
case "#":
Console.WriteLine("Confirm dtmf_str: " + dtmf_str);
switch (playback.Id)
{
case "onsei3":
yoyaku_hiduke[yoyaku_no] = dtmf_str;
dtmf_str = "";
break;
case "onsei4":
yoyaku_jikan[yoyaku_no] = dtmf_str;
dtmf_str = "";
break;
case "onsei6":
sentaku = dtmf_str;
dtmf_str = "";
break;
}
break;
default:
//sender.Playbacks.Stop(playback.Id); //Stop playback
//sender.Channels.Play(e.Channel.Id, string.Format("sound:digits/{0}", e.Digit));
switch (playback.Id)
{
case "onsei3":
case "onsei4":
case "onsei6":
dtmf_str += e.Digit;
break;
}
break;
}
}
private static void c_OnStasisStartEvent(IAriClient sender, StasisStartEvent e)
{
try
{
dtmf_str = "";
yoyaku_hiduke[yoyaku_no] = "";
yoyaku_jikan[yoyaku_no] = "";
sentaku = "";
ChannelID = e.Channel.Id;
Console.WriteLine("\r\nChannelID: " + ChannelID);
// Answer the channel
sender.Channels.Answer(e.Channel.Id);
// Play IVR Voices
playback = sender.Channels.Play(e.Channel.Id, "sound:onsei1", "ja", 0, 0, "onsei1");
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
Console.ReadKey();
}
}
}
}













