TwilioとWindows PowerShellを使って連続で電話を掛けたい

この記事は富士通クラウドテクノロジーズ Advent Calendar 2021の1日目の記事です。

はじまして。

TwilioとWindows PowerShellのみで連続で電話を掛けるための情報をまとめました。

##この記事の対象者
+ PowerShellはそれなりに読めるし書けるよという方
+ サーバなどの監視メッセージをトリガーにしてTwilioを使って通報したい方
+ PowerShellもTwilioも分からないけど何かしらのとっかかりにしたい方

##はじめに
「連続電話」以外の言葉を思いつかなかったので、そのように書きましたが下記を実現します。
####私的な連続電話の意味
Aさんに電話を掛けて、電話に出なかったらBさんへ電話を掛けて、
Bさんが出なかったらCさんへ
Cさんが出なかったら、Aさんへ戻って電話を掛け、Bさんへ…。

というのをイメージしています。

###Twilioで連続電話

```powershell:function.ps1
#通報ルール・各種パラメータ
$call_to_members=@("+81XXXXXXXX","+81XXXXXXXX","+81XXXXXXXX") #連絡先
$call_roop=3 #AさんからCさんへ電話を掛け続けて出なかった場合に、Aさんへ戻る回数
$call_timeout=35 #電話を鳴らす時間
$call_script="サーバが壊れたよ。直してください。" #電話で喋る内容
$call_cooltime=15 #電話間の間隔。Aさんへつながら場合にBさんへ掛けるまでの待ち時間

Call-Twilio -call_to_members $call_to_members -call_roop $call_roop -call_timeout $call_timeout -call_script $call_script -call_cooltime $call_cooltime

function Call-Twilio($call_to_members=$false,$call_roop=2,$call_timeout=30,$call_script="電話です",$call_cooltime=15){
    if(!$call_to_members){
        return $false;
    }
    #パラメータ
    $call_from="+81XXXXXXXX" #Twilioで購入
    $key = "Twilioのサイトから取得" #電話用APIキー
    $secret = "Twilioのサイトから取得" #電話用APIキー

    #Calls API
    $uri = "https://api.twilio.com/2010-04-01/Accounts/$key/Calls"
    $twiml="<Response><Gather timeout='5' finishOnKey='5'><Say language='ja-JP'>$call_script</Say></Gather></Response>"

    #BASIC認証
    $auth = "${key}:${secret}"
    $base64 = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($auth))
    $header = @{Authorization = "Basic $base64"}
    
    #現在時刻と10分前の時間
    $now=Get-Date
    $now_encode=$now.AddMinutes(-10).ToString("yyyy-MM-ddTHH:mm:ss+09:00")

    for($k=0;$k -lt $call_roop;$k++){
        #時間調整
        if($k -ge 2){
            Write-Debug "--連続通報　時間調整--"
            Write-Debug "sleep $call_cooltime"
            sleep $call_cooltime
        }

        for($i=0;$i -lt $call_to_members.Count;$i++){
            if($call_to_members[$i]){
                Write-Debug "--通報--"
                Write-Debug $call_to_members[$i]                 
                $parameters = @{Twiml=$twiml; To="$($call_to_members[$i])"; From=$call_from; timeout=$call_timeout; }
                $result=Invoke-WebRequest -Uri "$uri.json" -Method POST -Body $parameters -Headers $header -UseBasicParsing
            }

            Write-Debug "--タイムアウト時間待つ--"
            Write-Debug "sleep $call_timeout"
            sleep $call_timeout

            #電話リスト取得
            $parameters = @{"StartTime>"=$now_encode;}
            $result_view_call=Invoke-WebRequest -Uri "$uri.json" -Method Get -Body $parameters -Headers $header -UseBasicParsing
            $result_view_call_json=ConvertFrom-Json $result_view_call.Content

            #$result_view_call_json.calls

            #$call_timeoutを経過しても通話中・もしくは完了にならなければステータスをキャンセルする。
            if($result_view_call_json.calls){
                for($j=0;$j -lt $result_view_call_json.calls.Count;$j++){
                    if($result_view_call_json.calls[$j].status -match "completed" -or $result_view_call_json.calls[$j].status -match "in-progress" -or $result_view_call_json.calls[$j].status -match "busy"){
                        #連絡がついている人の番号
                        $called_index=$call_to_members.IndexOf($result_view_call_json.calls[$j].to)
                    
                        if($called_index -ge 0){
                            #$call_to_members[$delete_index]=""
                            Write-Debug "通報完了"
                            return $($call_to_members[$called_index])
                            exit
                        }
                    }elseif($result_view_call_json.calls[$j].status -match "canceled"){
                        #なにもしない
                    }else{
                        #通話をキャンセル            
                        $parameters = @{Status="canceled";}
                        $result=Invoke-WebRequest -Uri "$uri/$($result_view_call_json.calls[$j].sid).json" -Method POST -Body $parameters -Headers $header -UseBasicParsing
                    }
                }
            }
        }
    }
    return $null
}
```

###Proxy認証
社内などでproxy認証が必要な場合は下記を参考にしてください。

https://qiita.com/kkdd/items/ac6e65f6e2e8fc32e7ca

##気にしなければいけない箇所
* 留守電を設定している人がいたら、そこで電話が止まってしまう
* 連絡元・先は、E.164番号で記載が必要（日本だと+81と先頭の0を除いた番号）

##最後に
恐らく上記のコマンドで連続電話？できると思いますのでお試しください。では。


お願い：初めて記事を書いています。至らぬところ多々あると思いますが、温かく見守っていただけますとありがたいです。