こんにちは。西山です。
ギークフィードではオフィスの電話システムとして、社内にAsteriskサーバーを立てて利用しています。
リモートワーク開始後に電話を取る人も機会も減ったこともあり、効率よく着信電話を処理するためにコールフロー内で処理を行う必要が出てきました。
今回はAsteriskのダイアルプランからAWSサービスへアクセスする方法を、DynamoDBを例に紹介します。
数少ないAsteriskエンジニアの一助になれば幸いです。
※Asteriskとは?
AsteriskはオープンソースのPBXでDigiumのMark Spencerによって始められました。(主に)Linuxプラットフォーム上で動作します。
PBXというと会社内の電話やビジネスホン等を思い浮かべるのですが、Asteriskが使用されるのは、いわゆる電話の分野だけではありません。通話を繋いだり切ったり(呼制御)、通話を必要とするサービスは旧来の電話だけで使われるわけではありません。様々な音声サービスに使用できるのがAsteriskです。このため電話交換機からインターネット上の音声サービスまで様々に使用されているのがAsteriskです。— Voip-Info.jpより引用
※AGIとは?
Asterisk Gateway Interfaceの略。Asteriskのダイアルプラン(コールフロー)と、チャネル・呼制御を行う外部プログラムとの間のインターフェースです。AGIプログラムは同期的に実行されます。
AGIをインストール
AGIは様々な言語で提供されていますが、私はPHP版のAGIしか使ったことがないので今回もPHPAGIを利用します。
AGIのインストールは簡単です。
- PHPAGIのサイトからzipファイルをダウンロード
- phpagi.php, phpagi-fastagi.php, phpagi-asmanager.phpを、Asteriskがインストールされているサーバーの/var/lib/asterisk/agi-binに配置する
- 上記ファイルにAsterisk実行ユーザーへ実行権限を付与する
上記が完了すると、ダイアルプラン内からAGIファンクションでPHPのAGIスクリプトを実行することができます。
スクリプトを書く
実行するスクリプトをPHPで書きます。基本的には普通のPHPコードを書く際と同じですが、一部AGIの要素が入っています。
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 |
#!/usr/bin/env php <?php require_once('/var/lib/asterisk/agi-bin/phpagi.php'); require 'vendor/autoload.php'; use Aws\Sdk; use Aws\DynamoDb\Marshaler; use Aws\DynamoDb\Exception\DynamoDbException; $targetPhonenumber = trim($argv[1]); // AsteriskとやりとりをするAGIインスタンスを作成 $agi = new AGI(); // NoOpは何もせずログを書く $agi->exec('NoOp', 'start agi script: checkDynamoDB.php'); $agi->exec('NoOp', 'targetPhonenumber: ' . $targetPhonenumber); // DynamoDB $sdk = new Sdk([ 'region' => 'ap-northeast-1', 'version' => 'latest', 'credentials' => [ 'key' => 'アクセスキー', 'secret' => 'シークレットアクセスキー' ] ]); $dynamodb = $sdk->createDynamoDb(); $marshaler = new Marshaler(); $key = $marshaler->marshalJson('{ "phoneNumber": "' . $targetPhonenumber . '" }'); $params = [ 'TableName' => 'DynamoDBのテーブル名', 'Key' => $key ]; $result = $dynamodb->getItem($params); if (!is_null($result->get('Item'))) { // hit in database $agi->exec('NoOp', 'hit in database'); // Gotoはダイアルプランの特定コンテキストやラベルに移動する $agi->exec('Goto', 'specified-customer'); } else { // not hit $agi->exec('NoOp', 'not hit in database'); } return; ?> |
1行目のシェバンはAsteriskがスクリプトを解釈するために必須です。
AGIインスタンスを作成し、exec関数を使うことでAsteriskの呼制御をプログラムから実行することができます。
例として上記スクリプトでは、引数で渡された顧客電話番号をDynamoDBで検索し、DB内でヒットしたら特定のラベルへダイアルプランフローを移動し、ヒットしない場合はもとのフローに戻るという処理になっています。
AWSの認証に関しては社内の物理サーバーからのアクセスのため、アクセスキーを使用しています。もちろんAWS CLIをインストールする方法でも問題ありません。
AsteriskサーバーがEC2の場合、インスタンスプロファイルに必要なIAMロールをアタッチしてセキュアに認証を行いましょう。
また、スクリプトファイルもAsterisk実行ユーザーへ実行権限を与えてください。
ダイアルプランからAGIを呼び出す
最後にダイアルプランからAGIを呼び出します。
AGI関数の第一引数には実行するスクリプトを指定し、第二引数にはスクリプトに渡す引数を指定します。この場合は、電話をかけてきた相手の電話番号を渡しています。
ダイアルプランは/etc/asterisk/extensions.confです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
[incoming] ;------------------------------------ ;GeekFeed代表 0338636754=GEEKFEED ;------------------------------------ exten => ${GEEKFEED},1,NoOp(GF NUMBER) exten => ${GEEKFEED},n,Macro(cidnamecheck) exten => ${GEEKFEED},n,Set(CALLERID(num)=${CALLERID(num)}) exten => ${GEEKFEED},n,NoOp("CallerID num is "${CALLERID(num)}) exten => ${GEEKFEED},n,Set(CALLERID(name)=GEEKFEED:${CALLERID(num)}) exten => ${GEEKFEED},n,NoOp("CallerID name is "${CALLERID(name)}) ; for dynamodb exten => ${GEEKFEED},n,AGI(checkDynamoDB.php, ${CALLERID(num)}) ; exten => ${GEEKFEED},n(open),Dial(${GROUP_ALL},30,tTwW) exten => ${GEEKFEED},n(specified-customer),Playback(ja/silence/ja/greeting) exten => ${GEEKFEED},n,Hangup |
ダイアルプラン変更後は、
1 |
$ dialplan reload |
をAsteriskコンソールで実行します。
Tips
AGIをデバッグするには、上記でも記載しているNoOp関数を指定してAsteriskコンソールでログを確認することができます。
また、Asteriskコンソールで
1 |
$ agi set debug on |
を実行することで、AGIのデバッグを有効化することができます。
AGIスクリプトはAGIインスタンスの処理以外は普通にPHPスクリプトとして実行することもできるので、Linuxターミナル上でphpコマンドで実行することでもデバッグを行えます。
さいごに
いつものエンジニア募集の告知
ギークフィードではハイレベルなクラウドエンジニア(を目指している人含む)を随時募集しています。
量より質を重視する企業理念の関係上、採用合格率は決して高くありませんが、我こそはと思う方はhttps://www.geekfeed.co.jp/recruitment
よりご気軽にご応募ください!
- 組織内のIPv4アドレス(EIP)を自動通知してコスト削減する - 2024-12-03
- 組織内のAWSコスト最適化のためにやっている7つのこと - 2024-12-01
- Amazon Connect Contact Lens + iPaaSで生成AI活用&他サービス連携を簡単に実現!– Amazon Connect アドベントカレンダー 2024 - 2024-12-01
- AWS Step Functionsの基本を再学習しました - 2024-09-23
- Amazon SESでバウンスメールを管理する - 2024-07-07