見出し画像

Amazon Connectを使ってインフラ担当に繋がるまで電話をかけてみた

はじめに

こんにちは、かわチキンです。ナビタイムジャパンで提供するサービスが稼働しているインフラ環境の構築・運用を担当しています。

今回はAmazon Connectを利用したインフラ担当への電話通知の仕組みについてご紹介いたします。

実現したいこと

緊急度が高いアラートを電話通知する

当社のインフラ担当は社用携帯を所持しており、インフラ環境で何らかのアラートが発生した際は主にslackやメールで社用携帯に通知が届くようになっています。
しかし様々なサービスから通知が届くなかで緊急度の高いアラートが埋もれてしまう懸念がありました。
このため緊急度が高く確実にキャッチしたいアラートを電話通知にして「電話が着信したら優先的に対応する」という運用にしたいと考えていました。

インフラ担当へ順番に電話発信し、誰に電話が繋がったかを把握する

アラートは深夜・早朝や休日などにも発生し得るため、slackやメールでの一斉通知ではキャッチ漏れが起きる可能性があります。
そのためインフラ担当に順番に電話発信したうえで「誰がアラートをキャッチしたか」を把握しておくことが必要でした。

Amazon Connect

Amazon ConnectはAWSが提供するクラウド型のコンタクトセンターサービスで、本格的なコンタクトセンターの構築など顧客向けサービスとしても利用できます。
今回は、緊急度の高いアラートをAWS LambdaとAWS DynamoDBを利用したシステムで監視していた点から Amazon Connectの通話機能を利用してみることにしました。

構成

利用リソース

  • EventBridge: 電話発信Lambdaを5分ごとに定期実行する

  • 連絡先DynamoDB: インフラ担当の電話番号を登録している

    • Aさんの電話番号, Bさんの電話番号…

  • 通話管理DynamoDB: 電話が「繋がった」or「繋がっていない」を管理する

  • 電話発信Lambda:  通話管理DynamoDBを確認し、電話が「繋がっていない」場合は連絡先DynamoDBの情報をもとにConnectを呼び出す

  • Connect: 電話番号に電話通知をする

  • 通話管理Lambda: Connectで電話が繋がった場合は通話管理DynamoDBの状態を「電話が繋がった」に更新する

条件

  • 電話発信後の待ち時間は30秒

  • インフラ担当の Aさん → Bさん → … と順番に電話通知していく

ポイント

Amazon Connectの電話発信は「呼び出し後60秒応答がなかったら切断される」という仕様ですが、緊急性の高いアラートのキャッチにおいては1人あたりの呼び出し時間をもう少し短くしたいと考えていました。
そこでAWS Lambdaにおいて「Amazon Connectを呼び出した後に30秒待ち、繋がっていない場合は呼び出しを切断して次の人に電話発信する」という処理を実装しています。

処理の流れ

フローチャート
  • (1) 電話発信Lambda

    • 連絡先DynamoDBをもとにConnectを呼び出してAさんに電話発信する

    • 電話発信後、30秒スリープする

電話発信に使っている start_outbound_voice_contact で取得できるコンタクトIDを保持しておきます。
コンタクトIDは「電話が繋がらなかった場合の呼び出しの切断」に利用します。

response = client.start_outbound_voice_contact(
DestinationPhoneNumber='string',
ContactFlowId='string',
InstanceId='string',
ClientToken='string',
SourcePhoneNumber='string',
QueueId='string',
Attributes={
'string': 'string'
},
AnswerMachineDetectionConfig={
'EnableAnswerMachineDetection': True|False,
'AwaitAnswerMachinePrompt': True|False
},
CampaignId='string',
TrafficType='GENERAL'|'CAMPAIGN'
)

Connect — Boto3 Docs (Connect.Client.start_outbound_voice_contact)

以下はコンタクトIDを contact_id に保持する例です。

status_code = json.dumps(response, indent=4)
contact_id = json.loads(status_code)['ContactId']
return contact_id


  • (2) Amazon Connect

    • 電話が繋がった?

      • はい

        • 通話管理Lambda経由で通話管理DynamoDBを「繋がった」に更新する

        • 電話を切断する

      • いいえ

        • 何もしない

  • (3) 電話発信Lambda:30秒スリープ後

    • 通話管理DynamoDBの状態を確認する

      • 繋がった

        • Aさんに繋がった旨をSlack通知する

        • 処理を終了する

      • 繋がっていない

        • 電話を切断する

          • コンタクトIDをもとに切断する(*)

        • Aさんに繋がらなかった旨をSlack通知する

        • (1)に戻りBさんに電話発信する

※コンタクトIDをもとに切断する処理
「ContactId」に前項で保持していたコンタクトIDを指定します。

response = client.stop_contact(
ContactId='string',
InstanceId='string'
)

Connect — Boto3 Docs (Connect.Client.stop_contact)

実現できたこと

緊急度が高いアラートを電話通知に移行することで、
「多数のslackやメールの内容確認・緊急度の判断」を経由せず、
「アラート復旧に向けたアクション」へ動けるようになりました。

またslackやメールでは「インフラ担当全員への一斉通知」だったため、誰がアラートに気づいているかが把握しづらく「誰か確認していますか?」「私が確認します」といった状況確認のためのアクションが必要でした。
この点も順番に電話発信していくことで「○○さんがアラートをキャッチした」という状況判断がしやすくなりました。

なお前述の構成では最初に「Aさんに電話発信」となっていることからAさんへの着信が他のインフラ担当よりも増えることになりますが、連絡先DynamoDBに登録している電話番号を編集することで順番変更が可能です。
当社では1週間おきに順番変更することで、特定のインフラ担当に着信が集中しないようにしています。

終わりに

これらの要件を実現するにあたり、Amazon ConnectはAWS Lambdaとの連携により呼び出し時間の短縮化・電話が繋がらなかった場合の分岐条件といった細かい実装ができ、またAWS DynamoDBとの連携により電話が繋がったかの状態を保持できるなど、AWSの他サービスとの連携により要件にあわせたカスタマイズができる点が便利でした。

現在、当社での電話通知は「緊急度の高いアラートをインフラ担当がキャッチする」を目的としていることから電話を取った際に流れるメッセージはひとつの定型文のみで、アラートの詳細はslackで別途通知しています。
ですがAmazon Connectはこの応答メッセージもカスタマイズ可能なため、例えば「アラートの種類に応じてメッセージを変更する」あるいは「アラートのサマリーをメッセージとして流す」とすることでインフラ担当がアラート内容をさらに把握しやすくなるなど、電話通知の機能ひとつとっても活用の幅が広がっていくと考えております。

最後までお読みいただきありがとうございました。