Last active
November 26, 2021 08:22
-
-
Save ppaquette/67149e69e3313eb3b7c5924a1198b3b1 to your computer and use it in GitHub Desktop.
Lambda to export twilio recordings to S3
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
const axios = require('axios'); | |
const AWS = require('aws-sdk'); | |
const S3UploadStream = require('s3-upload-stream'); | |
const Twilio = require('twilio'); | |
const ACCOUNT_SID = "AC2xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; | |
const AUTH_TOKEN = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; | |
const S3_BUCKET = "BUCKET-NAME"; | |
const S3_PREFIX = "Recordings"; | |
function add_leading_zero(number) { | |
let n = number.toString(); | |
if (n.length < 2) { n = '0' + n; } | |
return n; | |
} | |
function get_download_url(recording) { | |
const apiVersion = recording.apiVersion; | |
const recordingSID = recording.sid; | |
return `https://api.twilio.com/${apiVersion}/Accounts/${ACCOUNT_SID}/Recordings/${recordingSID}.mp3` | |
} | |
function get_upload_path(recording, from_number, to_number) { | |
const recordingDate = new Date(recording.dateCreated); | |
const year = recordingDate.getFullYear(); | |
const month = add_leading_zero(recordingDate.getMonth() + 1); | |
const day = add_leading_zero(recordingDate.getDate()); | |
const hour = add_leading_zero(recordingDate.getHours()); | |
const minute = add_leading_zero(recordingDate.getMinutes()); | |
const second = add_leading_zero(recordingDate.getSeconds()); | |
const duration = add_leading_zero(recording.duration); | |
return `${S3_PREFIX}/${year}/${month}/${year}.${month}.${day}-${hour}.${minute}.${second}_${from_number}_${to_number}_${duration}s.mp3` | |
} | |
async function transfer_recording(download_url, upload_stream) { | |
const response = await axios({method: 'GET', url: download_url, responseType: 'stream'}); | |
response.data.pipe(upload_stream); | |
return new Promise((resolve, reject) => { | |
upload_stream.on('uploaded', resolve) | |
upload_stream.on('error', reject) | |
}); | |
} | |
module.exports.handler = async function(event, context, callback) { | |
const client = Twilio(ACCOUNT_SID, AUTH_TOKEN); | |
// Retrieving and deleting all recordings | |
const recordings = await client.recordings.list(); | |
for (const recording of recordings) { | |
if (recording.status !== "completed") { continue; } | |
// Getting the upload and download paths | |
const call = await client.calls(recording.callSid).fetch(); | |
const download_url = get_download_url(recording); | |
const upload_path = get_upload_path(recording, call.from, call.to); | |
let s3Stream = S3UploadStream(new AWS.S3()); | |
// Alternatively, one could download a ".wav" by using ".wav" in the in the download_url and a ContentType of "audio/x-wav" | |
let upload_stream = s3Stream.upload({Bucket: S3_BUCKET, Key: upload_path, ContentType: 'audio/mpeg'}); | |
// Transferring to S3 | |
console.log(`Transferring ${recording.callSid} to ${upload_path}`); | |
await transfer_recording(download_url, upload_stream); | |
// Deleting recording | |
await client.recordings(recording.sid).remove(); | |
} | |
callback(); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Now the recording can be upload to S3, but it's throw this warning, do you know why? and sometimes it's will run a long time(more than 1h) in here:"let upload_stream = s3Stream.upload({Bucket: S3_BUCKET, Key: upload_path, ContentType: 'audio/mpeg'});"
FYI, I pass credentialData like this:
let credentialsData={ accessKeyId: 'AKIASXXXXXXUXHFPU', secretAccessKey: 'TAuXXXXXXXXXXXXXLe4mN8jOfrUemvIJfb7fe6swK' };
let s3Stream = S3UploadStream(new AWS.S3(credentialsData));