お知らせ・ブログ

オノコムからの最新情報や、生成AI、AWSクラウド、ノーコードアプリケーションに関する有益な情報をお届けします。

Amazon Connectで自動架電を行うシンプルな構成(Lambda連携)

2025年07月03日
あきひが
ブログ

【はじめに】

弊社では、顧客からのお問い合わせ用にAmazon Connectを使用して、カスタマサポートデスクを立ち上げたのですが、その際に受電だけでなく架電にも使用できるということを知り、試してみました。

今回は、AWS LambdaからAmazon ConnectのAPIを呼び出して、自動で特定の番号に架電する仕組みを構築してみましたので内容をご紹介します。

【システム構成】

主に使用したサービスは以下の通りです。

  • Amazon Connect(コンタクトフローと電話番号)
  • AWS Lambda(発信API呼び出し)
  • CloudWatch Logs(ログ確認)

※ 本構成では、すべてのAWSサービスを東京リージョン(ap-northeast-1)で使用しています。

【Amazon Connectの前準備】

既にAmazon Connectのインスタンス作成、架電に使用する電話番号の取得については、済んでいるものとして続けますが、ざっくり書き出すと以下のような感じです。

  1. Amazon Connectインスタンスを作成。

  2. Amazon ConnectインスタンスのアクセスURLより、Amazon Connectのダッシュボードにログイン。

  3. ダッシュボードの電話番号の表示にて、電話番号(050)の取得を行う。

    (最終的には、AWSサポートケースへの申請が必要となります。)

  4. 二週間ほど待った後に番号の取得が完了。

【コンタクトフローの全体像】

次にコンタクトフローの作成について。

今回は、単純に架電を行うのみなので、最低限の構成にしています。

架電フロー

【使用したブロック】

上記コンタクトフローにて使用したのは、下記の4ブロック。

ここで記載していないブロックの設定項目については、デフォルトの設定を使用しています。

  • 音声の設定(AIエージェントの声)

    言語:日本語

    音声:Tomoko

    言語属性を設定:チェック

  • プロンプトの再生(AIエージェントに読ませる内容)

    テキスト読み上げまたはチャットテキスト:動的に設定

    名前空間:ユーザー定義済み

    キー:message

    次として解釈:テキスト

  • プロンプトの再生(エラー時に流す内容)

    テキスト読み上げまたはチャットテキスト:手動で設定

    読み上げるテキストを入力:エラーが発生しました。

  • 切断(架電の終了)

【Lambda関数の作成】

次にトリガーとなるLambda関数について。

API Gatewayは使用せずに、AWSコンソール上からテストタブのテストボタンを手動で実行する形にしています。

  • index.ts
import { ConnectClient, StartOutboundVoiceContactCommand } from '@aws-sdk/client-connect';
import { Context } from 'aws-lambda';

// Lambdaレスポンス型の定義
type LambdaResult = {
  result: boolean;
  message?: string | null;
  error: string | null;
};

interface OutboundCallRequest {
  destinationPhoneNumber: string;
  message: string;
  instanceId: string;
  contactFlowId: string;
  sourcePhoneNumber: string;
  name?: string;
}

const connectClient = new ConnectClient({ region: 'ap-northeast-1' });

export const handler = async (
  event: any,
  context: Context
): Promise<LambdaResult> => {
  try {
    // API Gateway経由の場合はevent.body、直接呼び出しの場合はeventそのものを使用
    const request: OutboundCallRequest = event.body ? JSON.parse(event.body) : event;
    
    const { destinationPhoneNumber, message, instanceId, contactFlowId, sourcePhoneNumber, name } = request;

    if (!destinationPhoneNumber || !message || !instanceId || !contactFlowId || !sourcePhoneNumber) {
      return {
        result: false,
        message: null,
        error: 'Missing required parameters: destinationPhoneNumber, message, instanceId, contactFlowId, sourcePhoneNumber'
      };
    }

    const params = {
      DestinationPhoneNumber: destinationPhoneNumber,
      InstanceId: instanceId,
      ContactFlowId: contactFlowId,
      SourcePhoneNumber: sourcePhoneNumber,
      Name: name || 'Automated Alert Call',
      Attributes: {
        message: message
      }
    };

    const command = new StartOutboundVoiceContactCommand(params);
    await connectClient.send(command);

    return {
      result: true,
      message: '成功しました',
      error: null,
    };

  } catch (error) {
    console.error('Error initiating outbound call:', error);
    
    return {
      result: false,
      message: null,
      error: error instanceof Error ? error.message : 'Unknown error'
    };
  }
};

上記コードは、TypeScriptを使用しています。使用している「tsconfig.json」、「package.json」は、以下の通りです。

ご自身の環境に合わせて読み替えるなどの対応をお願いします。

  • tsconfig.json
{
  "compilerOptions": {
    "target": "es2023",
    "strict": true,
    "preserveConstEnums": true,
    "noEmit": true,
    "sourceMap": false,
    "module":"ESNext",
    "moduleResolution":"node",
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "isolatedModules": true
  },
	"include": ["index.ts"],
  "exclude": ["node_modules", "dist"]
}
  • package.json
{
	"name": "sample-project",
	"version": "0.1.0",
	"private": true,
	"devDependencies": {
		"@types/aws-lambda": "^8.10.147",
		"@types/aws-sdk": "^0.0.42",
		"@types/node": "^22.13.4",
		"esbuild": "^0.24.2",
		"ts-node": "^10.9.2",
		"typescript": "^5.8.3"
	},
	"scripts": {
		"prebuild": "rm -rf dist",
		"build": "esbuild index.ts --bundle --minify --sourcemap --platform=node --target=es2023 --outfile=dist/index.js --external:@aws-sdk/*",
		"postbuild": "cd dist && zip -r package.zip index.js*"
	},
	"dependencies": {
		"@aws-sdk/client-connect": "^3.0.0"
	}
}

【Lambdaの実行に必要な権限】

次に上記Lambda関数を実行する際に必要となるポリシーの設定について。

Amazon Connectを使って架電を行うために「connect:StartOutboundVoiceContact」の権限をインラインポリシーに設定します。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "connect:StartOutboundVoiceContact"
            ],
            "Resource": [
                "arn:aws:connect:ap-northeast-1:(AWSアカウントID):instance/(AmazonConnectインスタンスID)",
                "arn:aws:connect:ap-northeast-1:(AWSアカウントID):instance/(AmazonConnectインスタンスID)/contact-flow/(対象のコンタクトフローID)",
                "arn:aws:connect:ap-northeast-1:(AWSアカウントID):instance/(AmazonConnectインスタンスID)/contact/*"
            ]
        }
    ]
}

AWSアカウントID、AmazonConnectインスタンスID、対象のコンタクトフローIDは、ご自身の環境に合わせて読み替えるなどの対応をお願いします。

【Lambda関数の動作確認】

Lambda関数のテストは、AWSコンソール上のテストタブから行います。

イベントには、事前に取得した発信元電話番号や、必要なmessage属性などを含めたJSONを設定します。

{
  "destinationPhoneNumber": "+81123456789",  // 架電先電話番号(例:+81 日本)
  "message": "システムエラーが発生しました。至急確認をお願いします。",  // 音声メッセージ
  "instanceId": "your-connect-instance-id",  // AmazonConnectインスタンスID
  "contactFlowId": "your-contact-flow-id",  // AmazonConnectコンタクトフローID
  "sourcePhoneNumber": "+81509876543",  // 発信元電話番号(AmazonConnectで取得済み)
  "name": "緊急アラート"  // 表示名(任意)
}

実行後、架電先電話番号として設定した「+81123456789」に対して「+81509876543」から架電が行われます。

CloudWatch Logsに出力されたログから、正常にAPI呼び出しが行われたかを確認できます。

また、Amazon Connectの「通話履歴」からも発信記録が確認可能です。

【まとめ】

今回は、AWS LambdaからAmazon Connectを使って自動で特定の番号へ架電する仕組みを構築しました。

Amazon Connect側のフローは最小限に抑え、Lambda関数からの呼び出しとCloudWatch Logsによる確認だけで、比較的簡単に架電が可能です。

電話番号の取得にやや時間がかかる点はあるものの、それ以外はスムーズに作業を進めることができると思います。

ここまでできれば、後の応用は、かなり広がるのではないでしょうか?

例えば、

  • サーバーがアラートを上げたときにメールだけではなく、電話で技術者に連絡を行う。
  • DynamoDBとの連携で複数人に順次架電を行う。
  • EventBridgeとの組み合わせでリマインダーとして使用する。

このように、従来は人が対応していた作業を自動化することで、業務の効率化や対応漏れの防止につながります。

まずはシンプルな構成から試してみませんか?