Twilioで録音された録音データを、S3に自動でアップロードして削除する


はじめに

みなさん、こんにちは。
KDDIウェブコミュニケーションズの Twilio事業部エバンジェリストの高橋です。

今回は、Twilio 上で録音された録音データを自動的に S3 にアップロードし、アップロードが完了すると該当する録音データを自動的に Twilio 上から削除する方法をご紹介します。

準備

事前に以下の準備をしておいてください。

  • Twilio CLI のインストール(こちらの記事を参考にしてください)
  • Twilio CLI サーバーレスプラグインのインストール(こちらの記事を参考にしてください)
  • S3 にバケットを作成(バケット名を控えておいてください)
  • S3 にアップロードする権限をもった、AWS のアクセスキーとシークレットアクセスキー

ソースコードの準備

今回のプログラムは、すでに GitHub 上に公開されていますので、そちらを使って作業をしていきましょう。

  • 適当な作業ディレクトリに移動します。
  • 以下のコマンドでプログラムを取得します。
git clone https://github.com/twilioforkwc/twilio-voice-recording-to-s3.git
  • 設定情報を設定しますので、以下のコマンドをつかって設定情報のサンプルをコピーします。
cd twilio-voice-recording-to-s3
cp .env.sample .env
  • コピーした.envをエディタで開き、以下の内容で更新します。
項目名 内容
ACCOUNT_SID Twilio のアカウント SID(AC から始まる文字列)
AUTH_TOKEN 同じく Auth Token
AWS_ACCESS_KEY AWS のアクセスキー
AWS_SECRET_ACCESS_KEY 同じくシークレットアクセスキー
AWS_REGION AWS のリージョン(デフォルトは東京リージョン)
AWS_S3_BUCKET 録音データを保管するバケット名
AWS_S3_PREFIX 録音データのプレフィックス(デフォルトはRecordings

解説

今回作成したコード(export-s3.js)をご紹介します。

const axios = require("axios");
const AWS = require("aws-sdk");
const S3UploadStream = require("s3-upload-stream");

const transfer_recording = async (context, download_url, upload_stream) => {
  const res = await axios({
    method: "GET",
    url: download_url,
    responseType: "stream",
    auth: {
      username: context.ACCOUNT_SID,
      password: context.AUTH_TOKEN,
    },
  });
  res.data.pipe(upload_stream);
  return new Promise((resolve, reject) => {
    upload_stream.on("uploaded", resolve);
    upload_stream.on("error", (error) => reject(error));
  });
};

exports.handler = async function (context, event, callback) {
  try {
    if (event.RecordingStatus !== "completed") {
      throw new Error("Not completed.");
    }

    const download_url = `${event.RecordingUrl}.mp3`;
    const upload_path = `${context.AWS_S3_PREFIX}/${event.CallSid}_${event.RecordingSid}.mp3`;

    // Initialize AWS configure
    AWS.config.update({
      region: context.AWS_REGION,
      credentials: new AWS.Credentials(
        context.AWS_ACCESS_KEY,
        context.AWS_SECRET_ACCESS_KEY
      ),
    });

    let s3Stream = S3UploadStream(new AWS.S3());

    let upload_stream = s3Stream.upload({
      Bucket: context.AWS_S3_BUCKET,
      Key: upload_path,
      ContentType: "audio/mpeg",
    });

    console.log(`Transferring ${event.CallSid} to ${upload_path}`);
    await transfer_recording(context, download_url, upload_stream);

    const client = context.getTwilioClient();
    await client.recordings(event.RecordingSid).remove();

    callback(null, "Transfer completed.");
  } catch (err) {
    callback(err);
  }
};

axios を使って録音データをストリームとして取得し、それを S3UploadStream に Pipe することでアップロードします。Pipe でつなぐことで、ローカルに一時ファイルを作成することなく転送が可能です(素敵!)。

axios でデータを取得するときに、Basic 認証をかけていますが、これは Twilio の Programmable Voice の設定にあるEnforce HTTP Auth on Media URLs を有効にしていることを想定しています(無効にしていても動作しますが、ぜひ有効にしましょう)。

デプロイ

デプロイするときは、Twilio CLI プロファイルが対象の Twilio プロジェクトのものであることを確認してください。
違うプロファイルでデプロイをすると、間違ったプロジェクト内に Functions ができてしまいます。プロファイルを切り替えるときは、twilio profiles:use プロファイル名で行います。

  • 以下のコマンドを使って、プログラムをデプロイします。
twilio serverless:deploy --force
  • 以下のような感じでデプロイがされれば成功です。
Deploying functions & assets to the Twilio Runtime

Account         ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Token           5c19****************************
Service Name    twilioVoiceRecordingToS3
Environment     dev
Root Directory  /Users/katsumi/Documents/workspace/Node.js/twilioVoiceRecordingToS3
Dependencies    aws-sdk, axios, s3-upload-stream, twilio
Env Variables   AWS_ACCESS_KEY, AWS_SECRET_ACCESS_KEY, AWS_REGION, AWS_S3_BUCKET, AWS_S3_PREFIX
Runtime         undefined

✔ Serverless project successfully deployed

Deployment Details
Domain: twiliovoicerecordingtos3-XXXX-dev.twil.io
Service:
   twilioVoiceRecordingToS3 (ZSe8d5680a4c68e08a6bc5a41e964588c9)
Environment:
   dev (ZEdb28386fa0b2467c75db08f29b263b5b)
Build SID:
   ZB44ca257c919636d6c8f23f33d5f8d1d1
Runtime:
   node12
View Live Logs:
   https://www.twilio.com/console/assets/api/ZSe8d5680a4c68e08a6bc5a41e964588c9/environment/ZEdb28386fa0b2467c75db08f29b263b5b
Functions:
   https://twiliovoicerecordingtos3-XXXX-dev.twil.io/export-s3
Assets:

最後の方に表示されるFunctions:の URL( https://twiliovoicerecordingtos3-XXXX-dev.twil.io/export-s3 )を控えておいてください(XXXX のところに数字が入ります)。

Twilio 側の設定

Twilio 録音では、通話が終了してから録音データが作成されるまでに少しだけタイムラグが発生します。そのため、録音データが完成したときに通知される RecordingStatusCallback を利用するのがよいです。

具体的には、<Record>動詞の RecordingStatusCallback に、今控えておいた Functions の URL を指定します。もし Studio で録音をしているのであれば、Record Voicemail ウィジェットに以下のような設定項目がありますので、そこに先程の URL を設定します。

テスト

以上でセットアップは終了です。

あとは実際にテストをして、Twilio 上に録音データが残っていないことと、S3 に録音データがアップロードされたことを確認してください。

まとめ

録音データの保存場所を日本に限定させておきたい場合などは、今回の方法を使って対処することが可能です。また、録音データが溜まっていくと Twilio 上にストレージの料金がかかりますので、そのような心配からも S3 への転送は有効ですね。
あとは、必要に応じて S3 の暗号化を設定しておくと良いでしょう。


Twilio(トゥイリオ)とは

https://cloudapi.kddi-web.com
Twilio は音声通話、メッセージング(SMS /チャット)、ビデオなどの 様々なコミュニケーション手段をアプリケーションやビジネスへ容易に組み込むことのできるクラウド API サービスです。初期費用不要な従量課金制で、各種開発言語に対応しているため、多くのハッカソンイベントやスタートアップなどにも、ご利用いただいております。

自己紹介  
高橋克己(Katsumi Takahashi) 自称「赤い芸人
グローバル・インターネット・ジャパン株式会社 代表取締役
株式会社KDDIウェブコミュニケーションズ Twilio事業部エバンジェリスト

2001年より大手通信事業者の法人サービスの教育に携わり、企業における電話のしくみや重要性を研究。2016年よりTwilio事業部にジョインし、Twilioを使ったスマートコミュニケーションの普及活動を精力的に行っている。
2015 Hall of Doers
2019 Twilio Champions