Last active
July 2, 2019 23:17
-
-
Save danshev/5393bb1741e845ec17d30b6655dac547 to your computer and use it in GitHub Desktop.
TeslaCam-Create-Playlist (for AWS Lambda)
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
/* | |
Function: TeslaCam-Create-Playlist | |
Runtime: Node.js 10.x | |
Environment: AWS Lambda | |
Description: | |
This function is meant to be triggered by a periodic CloudWatch Event. | |
Upon execution, it will scan an S3 bucket (containing TeslaCam files), | |
build an M3U playlist of processed / merged TeslaCam videos, determine | |
how many *new* videos were added, and push a message to AWS SNS (for alerting). | |
Environment Variables: | |
- S3_BUCKET = the.name.of.your.bucket | |
- SNS_ARN = your:arn:for:aws:sns:etc-etc | |
Assumptions: | |
1. Your S3 bucket is only used for TeslaCam work | |
2. You're using the other two Lambdas: | |
- TeslaCam-Identify-Sets-and-Kickoff | |
- TeslaCam-Merge-Videos | |
3. This Lambda function has a permissions Role enabling it to: | |
a. Read from and Write to S3 | |
b. Publish to SNS | |
c. (Recommended) Write to CloudWatch Logs | |
*/ | |
let AWS = require('aws-sdk'); | |
let s3 = new AWS.S3(); | |
let readline = require('readline'); | |
exports.handler = async (event) => { | |
var myProxyResponseObj = { | |
statusCode: 500, | |
body: JSON.stringify('It worked!'), | |
}; | |
let playlistParams = { Bucket: process.env.S3_BUCKET, Key: 'playlist.m3u' }; | |
// Check if a playlist exists and populate previousVideos array | |
var previousVideos = []; | |
try { | |
await s3.headObject(playlistParams).promise(); | |
// Download the current playlist | |
let s3ReadStream = s3.getObject(playlistParams).createReadStream(); | |
let rl = readline.createInterface({ input: s3ReadStream, terminal: false }); | |
let myPromise = new Promise((resolve, reject) => { | |
rl.on('line', (line) => { | |
if (line.indexOf("https") >= 0) { | |
previousVideos.push(line.match(/[^\/]+\/[^\/]+$/g)[0]); | |
} | |
}); | |
rl.on('error', () => { console.log('error'); }); | |
rl.on('close', () => { resolve(); }); | |
}) | |
try { await myPromise; } | |
catch(err) { | |
myProxyResponseObj.body = JSON.stringify({ "message": err.message }); | |
return myProxyResponseObj; | |
} | |
} | |
catch (err) { | |
console.log('There was no previous playlist file (no big deal)'); | |
} | |
// Retrieve the keys of previously-processed videos | |
var data; | |
try { data = await s3.listObjectsV2({ Bucket: process.env.S3_BUCKET, Prefix: 'fullscreen' }).promise(); } | |
catch (err) { | |
myProxyResponseObj.statusCode = err.statusCode; | |
myProxyResponseObj.body = JSON.stringify({ "message": err.message }); | |
return myProxyResponseObj; | |
} | |
// Build playlist file | |
var currentVideos = []; | |
var playlist = "#EXTM3U\n"; | |
for (const obj of data.Contents) { | |
currentVideos.push(obj.Key); | |
playlist = playlist.concat("#EXTINF:60, "+ obj.Key.split("/")[1] +"\n"); | |
playlist = playlist.concat("https://s3.amazonaws.com/"+ process.env.S3_BUCKET +"/"+ obj.Key +"\n"); | |
} | |
var params = { | |
ACL: "public-read", | |
Bucket: process.env.S3_BUCKET, | |
Key: 'playlist.m3u', | |
ContentType: 'text/plain', | |
Body: playlist.trim() | |
}; | |
// Upload the file to S3 | |
try { await s3.putObject(params).promise(); } | |
catch(err) { | |
myProxyResponseObj.body = JSON.stringify({ "message": err.message }); | |
return myProxyResponseObj; | |
} | |
// ==> Determine if there were any new videos in the updated playlist | |
let newVideos = currentVideos.filter( | |
function(e) { return this.indexOf(e) < 0; }, previousVideos | |
); | |
// If there were new videos, publish to SNS | |
if (newVideos.length > 0) { | |
let correctWording = newVideos.length == 1 ? " video is " : " videos are "; | |
let sns = new AWS.SNS(); | |
params = { | |
Message: newVideos.length +" new"+ correctWording +"available! \n\nhttps://s3.amazonaws.com/shevenell.teslacam/playlist.m3u", | |
Subject: "New Videos", | |
TopicArn: process.env.SNS_ARN | |
}; | |
try { await sns.publish(params).promise(); } | |
catch(err) { | |
console.log(err); | |
} | |
} | |
myProxyResponseObj.statusCode = 200; | |
return myProxyResponseObj; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment