Voiceflow Captureブロック(聴話)→APIブロックでTranscriptをLambdaに送り→SESメール送信
LambdaをVPCの外に配置してAPI gateway経由でVoiceflowからのトランスクリプトをhttpsリクエストで受けてSESメールするシンプルなpocです。
商用利用の際は、Lambdaをプライベートサブネットに配置するなど、その他諸々、セキュリティ面を設計から再考する必要があります。
1.SESでメール(ID)登録
SESで「IDの作成」にて「Eメールアドレス」でIDを1個作成します。
2.Lambda関数作成
以下のようなVPCの外のLambdaでVoiceflowからのトランスクリプトを受け取ってSESでメールします。
ランタイム:Node.js 22.x
import { SESClient, SendEmailCommand } from "@aws-sdk/client-ses";
// SESクライアント初期化
const ses = new SESClient({ region: "ap-northeast-1" });
// メール設定
const SENDER = "SESで登録したメアド"; // ID登録検証済み送信者
const RECIPIENT = "SESで登録したメアド"; // 受信者
export const handler = async (event) => {
try {
// API Gateway プロキシ統合の場合、bodyは文字列
const body = JSON.parse(event.body || '{}');
const transcript01 = body.transcript01 || "トランスクリプト未取得";
// Voiceflow Dev/APIブロックに持たせた APIキーの確認
const apiKey = event.headers['x-api-key'] || event.headers['X-API-Key'];
console.log('API Key received:', apiKey ? 'Yes' : 'No');
// メールパラメータ
const emailParams = {
Destination: {
ToAddresses: [RECIPIENT]
},
Message: {
Subject: {
Data: "Voiceflowから新しいトランスクリプトを受信"
},
Body: {
Text: {
Data: `以下のトランスクリプトをVoiceflowから受信しました:\n\n${transcript01}\n\n受信時刻: ${new Date().toLocaleString('ja-JP', { timeZone: 'Asia/Tokyo' })}`
},
Html: {
Data: `
<h3>Voiceflowトランスクリプト</h3>
<p><strong>内容:</strong></p>
<p>${transcript01}</p>
<hr>
<p><small>受信時刻: ${new Date().toLocaleString('ja-JP', { timeZone: 'Asia/Tokyo' })}</small></p>
`
}
}
},
Source: SENDER
};
// SESでメール送信
const command = new SendEmailCommand(emailParams);
await ses.send(command);
// 成功レスポンス
return {
statusCode: 200,
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*'
},
body: JSON.stringify({
message: "トランスクリプトを正常に受信し、メールを送信しました",
transcript01: transcript01
})
};
} catch (error) {
console.error("Error:", error);
// エラーレスポンス
return {
statusCode: 500,
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
error: "処理中にエラーが発生しました",
message: error.message
})
};
}
};
LambdaのIAMロールに追加したSES向けIAMポリシー
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "voiceflowcapturatest",
"Effect": "Allow",
"Action": [
"ses:SendRawEmail",
"ses:SendEmail"
],
"Resource": "arn:aws:ses:ap-northeast-1:<AWSアカウントID>:identity/<ID登録したメールアドレス>"
}
]
}
3.API Gateway 作成
- APIキー作成
- 使用料プラン作成(念のため、絞っておきます)
- スロットリング (オン)
- レート : 5
- バースト:10
- クォータ
- リクエスト:100
- 1日あたり
- リクエスト:100
- スロットリング (オン)
- 関連付けられたAPIキーで 1. のAPIキーを追加する
- REST API→新しいAPI→API名(voiceflow-capture-test-apigt)→APIを作成
- POSTリクエスト送信先となるリソースを作成する
- リソースを作成→リソース名(test-resource)
- 作られた「/test-resouce」が選択されている状態で、「メソッドを作成」→メソッドタイプ「POST」→統合タイプ「Lambda関数」→2.で作ったLambdaを選択→「API キーは必須です」にチェックを入れる→「メソッドを作成」
- 「POST」→統合リクエスト→Lambda プロキシ統合→「True」に変える
- CORS対応。「/test-resouce」が選択されている状態で、「メソッドを作成」→メソッドタイプ「OPTIONS」→統合タイプ「Mock」→2.で作ったLambdaを選択→「メソッドを作成」
- 「OPTIONS」が選択されている状態で、「メソッドレスポンス」の「編集」→レスポンスヘッダーに以下3種のヘッダーを追加→保存
- Access-Control-Allow-Origin
- Access-Control-Allow-Methods
- Access-Control-Allow-Headers
- 「統合レスポンス」の「編集」→「ヘッダーのマッピング」の「レスポンスヘッダー
」で以下のように、マッピング値を設定- Access-Control-Allow-Headers→'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'
- Access-Control-Allow-Methods→'OPTIONS,POST'
- Access-Control-Allow-Origin→'*'
- 「OPTIONS」が選択されている状態で、「メソッドレスポンス」の「編集」→レスポンスヘッダーに以下3種のヘッダーを追加→保存
- APIをデプロイ→新しいステージ(ステージ名:dev)→「デプロイ」
- 使用料プラン→3-2.で作成した使用料プランを選択→APIステージを追加→API(voiceflow-capture-test-apigt を選択)→ステージ(dev を選択)→「使用料プランに追加」
(API gatewayとAPIキーがここで紐付きます)
4.VoiceflowでProjectを作成
- Messageブロックで何か質問しておく
- Listen/Captureブロックを設置→「Save entire reply to...」で「Create variable」にて発話を格納する変数名を任意で入力 EX)reply_capture
- MessageブロックからListen/Captureブロックまで矢印でつなぐ
- reply_capture 変数をAPI GatewayにPOSTリクエストするため、Dev/APIブロックを設置
- 「POST」を選び、API Gatewayで「ステージ」のPOSTにて「URLを呼び出す」に記載されているURLを選んだPOSTの下に貼り付け
- Listen/CaptureブロックからDev/APIブロックまで矢印で結ぶ
- Headersへ次の二点を入力
- Header:Content-Type、Value:application/json
- Header:x-api-key、Value:「3-1で作ったAPIキー」
- Bodyへの入力
- Raw
- JSON
- {"transcript01": "{reply_capture}"}
5.Voiceflowで会話開始
4-1のMessageブロックの質問に返事をした発声が、SESメールで届きます。
音声会話は、Voiceflowのproject作成フローキャンバス画面で音声確認する にてやり方を確認できます
参考 API GatewayへのCURLのPOST
うまくいかない場合、下記のcurlによる検証が可能です。
curl -X POST <「URLを呼び出す」に記載されているURL> -H "Content-Type: application/json" -H "x-api-key: <3-1で作ったAPIキー>" -d '{"transcript01": "test message2"}'
