lambdaが楽しいらしい。
とりあえず動かしてみた。(2015/05/04 00:00ごろ)
目標
S3の特定のバケットにファイルがアップロードされたらメールでダウンロードリンクを通知する。
準備
- Lambdaが使えるリージョンでバケットを作成
- Amazon SNSでTopicを作成
- 作ったTopicに対してSubscriptionをemailで作成
やったこと
Lambdaで新しいfunctionを作成。
Code entry typeを inline
CodeTemplate を"S3 Get Object"
ロールはBasicExecutionRoleで動作した。(他のサービスへの許可いらないのかなーなどと思ったけど放置)
他はデフォルト値。
zipにしてライブラリなどごとごそっとあげてもいいようだけど、今回はやらない。
できたもの
上記の"S3 Get Object"のテンプレートから sns系の処理を書き足して、if文の書きっぷりをちょっと修正したのが以下。
var aws = require('aws-sdk');
var s3 = new aws.S3({apiVersion: '2006-03-01'});
var sns = new aws.SNS({apiVersion: '2010-03-31'});
var snsParams = {
Message: 'modify by code...',
Subject: 'upload notice',
TopicArn: 'arn:aws:sns:us-east-1:123456789012:uploaded'
};
exports.handler = function(event, context) {
console.log('Received event:', JSON.stringify(event, null, 2));
// Get the object from the event and show its content type
var bucket = event.Records[0].s3.bucket.name;
var key = event.Records[0].s3.object.key;
s3.getObject({Bucket: bucket, Key: key}, function(err, data) {
if (err) {
console.log("Error getting object " + key + " from bucket " + bucket +
". Make sure they exist and your bucket is in the same region as this function.");
context.fail('Error', "Error getting file: " + err);
}
var downloadLink = 'https://s3.amazonaws.com/' + bucket + '/' + key;
var message = 'download link is ' + downloadLink;
// snsで通知するメッセージにダウンロードリンクを設定。
snsParams.Message = message;
sns.publish(snsParams, function() {
context.succeed("success");
});
});
};
AWSのドキュメント によるとsns.publishのcallbackは2つ引数をとる気がするんだけど、なぜか動かないので今の形にしている。
バケットとLambdaの紐付け
S3の管理画面、イベントから設定。
ObjectCreatedに対してLambdaを設定する。
※Lambda非対応のリージョンのバケットでは選択肢にLambdaが現れない。
届いたメッセージ
upload noticeっていうタイトルの、
download link is https://example.com/hogehoge という本文と
AWSで勝手に付けてるフッタのようなものがついたメッセージが届き無事に動作。
感想
今回はS3に新しいファイルが生まれたところを基点でやってみましたが、最近のアップデートで同期呼び出しなども可能になったようで使いどころを考えるのが面白い感じになってますね。