はじめに
Twilioは、電話をAPIで制御できる素晴らしいプラットフォームです。
とても便利なプラットフォームなのですが、
ユーザと対話させつつ外部システムと連携させたコールフローを作ろうと思ったら、
自分でサーバを用意し、Twilioが提供するヘルパーライブラリを学んでプログラムを書く必要がありました。
本記事では、プログラムを書かないでも手軽にコールフローが作れる方法を紹介します。
コールフロー
AWSインスタンスを操作するシンプルなヘルプデスクのコールフローを作ってみます。
下図のようなコールフローです。
フローを作る
フローが簡単に作れるところを見てもらいたいので、3分クッキング方式で、最初に使う部品(ノード)を全てキャンバスに置いてから、フローにしていきます。
このようにGUIで部品と部品をつないでいくだけでフローは出来上がりです。あとは部品の設定をすれば完成です。
各部品の役割は次の通りです。
部品 | 名前 | 説明 |
---|---|---|
Voice In | Twilioから着信を受付けます | |
Call | TwilioにTwiMLを返します | |
Command | リモートサーバにSSHログインしてコマンドを実行し、結果を返します | |
Switch | 条件分岐を作ります | |
Change | 変数を設定・加工します | |
Link | 離れているノードを接続します | |
inject | 起動時処理をおこないます |
完成したフロー
設定が完了したフロー全体がこちらです。
- 部品の設定内容については、後述のAppendixを見てください。
フローを公開する
設定を終えたフローをFrontOpsでデプロイすると、すぐにTwilioからの着信を受けて動かすことができます。
構成は以下のようになります。
- 設定の中で、Ngrokを使ってURLを取得し、Twilioのコールバックに指定しています。
- Ngrokは、NATやファイヤーウォール下にあるローカルアプリをインターネットに公開できるサービスです。FrontOpsに組み込まれていて、URL取得とTwilioのコールバック設定が簡単におこなえます。
動作概要
- ユーザが電話すると、Twilioがコールバック設定したURLにリクエストを投げます。
- FrontOpsはリクエストを受けると、コールフローのVoice Inノードからフローを開始します。
- コールフローの各ノードの間をmsgオブジェクトが受け渡しされていきます。
- Callノードでは、生成したTwiMLをTwilioにレスポンスとして戻し、Twilioからの次のリクエストを待ちます。
まとめ
PC一台で、簡単にコールフローを作って動かすことができました。
- プログラムを書かないでコールフローを作成することができました
- PC上で作成したコールフローを、そのままTwilioと連携させて動作させることができました
最後に
FrontOpsを使ってコールフローを作ると、Twilioの電話APIを使う敷居がだいぶさがったのではないでしょうか
今回のコールフローの中で、リモートサーバにSSHログインしてコマンド実行を組み込んでいますが、このことについて、ちょっと考えてみてください。
これができるということは、・・・つまり、なんでもできるということです。
例えば今回の例では、認証番号を決め打ちにしましたが、
サーバ内のテキストファイルをgrep
してチェックしたり、
LDAPを検索してチェックしたりも自由自在です。
インフラエンジニアの方など、
コマンドライン操作は得意だけど、プログラミングが得意ではない人にとって、
電話がプログラミング不要でコマンドライン操作と連携させることができるこの例が、新しい可能性を探る参考になれば幸いです。
Appendix: 設定説明
使ったもの
- Twilioアカウント、電話番号
- AWS CLIが使えるサーバ
- SSHでログインできて、
aws configure
の設定が完了していること - 参考 AWS CLI の設定
- SSHでログインできて、
- FrontOps(セルフサービスを作れる一次対応ツール)
着信~認証
- 名乗った後に認証番号の入力を促すTwiMLを設定します。
-
{{{twilioVoiceUrl}}}
は自動で設定されます。
-
- Twilioから送られたデータは
msg.payload
に入ります。 - ユーザが入力した値は
msg.payload.Digits
に入ります。 - 認証番号は1234としています。
メニュー
認証に成功したらメニューを案内して、選択されるのを待ちます。
「1」が押された場合
-
AWS CLIでインスタンス状態を取得します。
mustacheにより{{{instanceId}}}
はmsg.instanceId
で展開されます。
running
やstopped
といった状態だけわかればいいので、query
で出力を絞り込んでいます。
aws ec2 describe-instances --output text --instance-ids {{{instanceId}}}
--query "Reservations[0].Instances[0].Status.Name"
コマンドの実行結果は、`msg.payload`に
```json:
{
stdout: "stopped",
stderr: "",
code: 0
}
という形で保存されます。
- コマンド実行完了を報告するTwiMLを設定します。
mustacheにより{{{payload.stdout}}}
はmsg.payload.stdout
で展開されます。
手抜きしてコマンドの出力をそのまま読み上げに使っています。
「2」が押された場合
-
AWS CLIでインスタンスを起動します。mustacheにより
{{{instanceId}}}
はmsg.instanceId
で展開されます。
aws ec2 start-instances --instance-ids {{{instanceId}}}
1. コマンド実行完了を報告するTwiMLを設定します。
![qiita-twilio-callflow-4b.png](https://qiita-image-store.s3.amazonaws.com/0/133603/aa713a25-9c40-d366-d19f-de4aef30d6ed.png)
## 「3」が押された場合
1. AWS CLIでインスタンスを停止させます。mustacheにより`{{{instanceId}}}`は`msg.instanceId`で展開されます。
```bash:
aws ec2 stop-instances --instance-ids {{{instanceId}}}
- コマンド実行完了を報告するTwiMLを設定します。