LoginSignup
19
12

More than 5 years have passed since last update.

Amazon S3にドキュメントを置いたらLambda経由でSlackに通知させてみた

Last updated at Posted at 2016-08-29

やりたかったこと

S3にファイルをアップロードしたタイミングでSlackに通知する仕組みを作りました。
だいたい1時間くらいで実装できます。
実装後のイメージとして、まずはこんな感じにS3にファイルをアップロードします。
UploadToS3.jpg
するとSlackに通知されます。
UploadNotification.jpg

仕組み

通知の仕組みを図で表すこんな感じです。
S3toSlackOverview.jpg
AWSのサービス間は連携が優れています。この辺のサービスを作った結果の感想をマイクロサービス否定派が変節した経験に書いています。

Slack側設定

Slackの受信設定をincoming webhook integrationから設定します。
投稿するチャネルを選択して"Add Incoming WebHooks integration"を押します。
SlackWebhookSetting.jpg
そうすると、Webhook URLが発行されます。
SlackWebhookResult.jpg

AWS Lambda設定

AWS Lambda設定を簡単にスクリーンショットを貼っていきます。

1. Select blueprint

blueprintからs3-get-objectを選択します。ここはpythonでもよかったのですが、特にこだわりなく選んでいます。
S3toSlack.jpg

2. Configure triggers

S3のBucket名とEven type(Put)を選択。
S3toSlack_02.ConfigureTriggers.jpg

3. Configure function

あとはその他の属性を入力します。
S3toSlack_03.ConfigureFunction.jpg
S3toSlack_03.ConfigureFunction2.jpg

AWS Lambdaのコーディング

最後にコーディング。動けばいい程度の認識でコーディングしたので、正直、自信がありません(Node.jsはお遊び程度の知識しかないですし)。

S3toPostSlack.js
'use strict';
console.log('Loading function');

let aws = require('aws-sdk');
let s3 = new aws.S3({ apiVersion: '2006-03-01' });

var url        = require("url");
var http       = require('http');
var https      = require('https');
var webhookUrl = url.parse("https://hooks.slack.com/services/<path>");

var webhookOptions = {
  hostname: webhookUrl.hostname,
  path:     webhookUrl.path,
  port:     443,
  method:   "POST",
  headers: { "Content-Type": "application/json"  }
};

exports.handler = (event, context, callback) => {
    //console.log('Received event:', JSON.stringify(event, null, 2));

    // Get the object from the event and show its content type
    const bucket = event.Records[0].s3.bucket.name;
    const key    = decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, ' '));
    const size   = Math.floor(event.Records[0].s3.object.size / 1024);
    const params = {
        Bucket: bucket,
        Key: key
    };

    var filename = event.Records[0].s3.object.key;
    var payload = JSON.stringify({
        channel:    "#<channel name>",
        icon_emoji: ":paperclip:",
        username:   "S3 Backet:" + bucket,
        text:       key + "がアップロードされました:" + size + "MB"
      }); 

    console.log(payload);

    var req = https.request(webhookOptions, function(res) {
        res.setEncoding("utf8");
        res.on("data", function(chunk) {
          console.log(chunk);
          context.succeed();
        });
      }).on("error", function(e) {
        console.log("error: " + e.message);
      });
    req.write(payload);
    req.end();


    s3.getObject(params, (err, data) => {
        if (err) {
            console.log(err);
            const message = `Error getting object ${key} from bucket ${bucket}. Make sure they exist and your bucket is in the same region as this function.`;
            console.log(message);
            callback(message);
        } else {
            console.log('CONTENT TYPE:', data.ContentType);
            callback(null, data.ContentType);
        }
    });
};

参考

以下の記事も併せて参考になるかと思います。

19
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
12