次は、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)】 ※このソースプログラムはサンプルです。完全動作するものではありません。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 |
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(); } } } } |