6
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

AWS Lambdaを使ってBacklogとS3を連携

Posted at

#はじめに
 これまで静的ページ配信のために、AWSコンソールからS3の設定を行い、ファイルをアップしていました。数が増えてきて毎回ぽちぽちやるのは大変になり、自動化できたら楽だなあというのと、静的コンテンツとはいえバージョン管理したいよね、という要望が出てきたので、AWS Lambdaを使ってBacklogとS3を連携して、コンテンツのアップロードを自動化するシステムを作ってみました。

#使うサービス

  • Lambda
  • API Gateway
  • S3
  • Backlog (SVN)

lambda.png

  • 今回は図の②③④を紹介します。
  • バージョン管理にgitでなく、svnを使うのはデザイナーさんやディレクターさんでも使えるようにです。
  • Lambda, Gatewayの設定とBacklogのwebhookについては↓を参照。

http://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/getting-started.html
http://www.backlog.jp/help/adminsguide/webhook-setting/userguide2493.html

#描いた

filename
var async = require('async');
var request = require('request');
var aws = require('aws-sdk');
aws.config.update({
  accessKeyId: 'your_key',
  secretAccessKey: 'your_secret_key',
  region: 'your_region'
});
var s3 = new aws.S3({ apiVersion: '2006-03-01' });

exports.handler = function(event, context) {

    var project = event.project.projectKey;
    var root = '';

    getDir(project, root, function(dir1){
        getDir(project, dir1, function(dir2){
            putContent(project, dir1 + dir2);
        });
    });
};

/**
 *  ディレクトリ名を返す関数
 **/
function getDir(project, dir, callback){

    var exec = require('child_process').exec;
    var cmd = "curl --user your_username:your_password https://your_domain.backlog.jp/svn/" + project + "/" + dir + " | grep href | grep -oE '\"([^\.]*)\"' | sed -e 's/\"//g'";

    exec(cmd, function(error, stdout, stderr) {

        dirs = stdout.split('\n');

        var i = 0;
        async.whilst(function start(){

            return i < dirs.length;

        }, function main(done){

            callback(dirs[i]);

            i++;
            done();

        }, function result(err){
            if (err) console.error(err);
        });
    })
}

/**
 *  S3にアップする関数
 **/
function putContent(project, dir){

    var exec = require('child_process').exec;
    var cmd = "curl --user your_username:your_password https://your_domain.backlog.jp/svn/" + project + "/" + dir + "| grep href | grep -oE '\".*\..*\"' | sed -e 's/\"//g' | grep -v ../";
    var files = [];

    exec(cmd, function(error, stdout, stderr) {

        files = stdout.split('\n');

        var i = 0;
        async.whilst(function start(){

            return i < files.length;

        }, function main(done){

            if(files[i] != ""){

                var key = files[i];

                var options = {
                    url: 'https://your_domain.backlog.jp/svn/' + project + '/' + dir + key,
                    auth: {
                        user: "your_username",
                        password: "your_password"
                    }
                };

                if(/.*image.*/.test(dir + key)){

                    options['encoding'] = null;

                }

                request.get(options, function (error, response, body) {

                    if (!error && response.statusCode == 200) {

                        var params = {
                            ACL: 'public-read',
                            Bucket: 'your_bucket',
                            Key: dir + key,
                            Body: body,
                        };


                        if (/.*html.*/.test(dir + key)) {

                            params['ContentType'] = 'text/html';

                        } else if (/.*css.*/.test(dir + key)) {

                            params['ContentType'] = 'text/css';

                        } else if (/.*js.*/.test(dir + key)) {

                            params['ContentType'] = 'text/javascript';

                        } else {

                            params['ContentType'] = response.headers['content-type'];

                        }

                        s3.putObject(params, function(err, data) {
                            if(err) console.log(err);
                        });

                    } else {
                        console.log('error: '+ response.statusCode);
                    }
                })
            }

            i++;
            done();

        }, function result(err){
            if (err) console.error(err);
        });
    })
}

#できたこと

Backlogのsvnリポジトリにコミットするだけで、リポジトリ内のファイルがS3にコピーされるようになりました。これでファイルの公開をデザイナーさんだけでできるようになります。

#苦労した点

  • backlogからのwebhookで返ってくる情報が少ない

  • 公式サイトにはgitのwebhookのサンプルしか書いてなかったが、実際に返ってきたjsonはサンプルと違う、情報が少ない :tada:

  • svnはより少ない :confetti_ball:

  • 画像のアップロード

  • S3にアップした画像が壊れていると表示されて困っていたが、requestモジュールで画像を取得するときは以下の設定が必要だった

     `options['encoding'] = null;`
    

#まとめ

  • Lambda, node.jsなどなどきちんと使うの初めてで色々苦労しましたが、新しいサービスを積極的に使えるのは面白かったです。Lambdaの使い途はまだまだあるので、どんどん使っていければと思います!
6
7
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
6
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?