AWS CodeCommit上で管理しているリポジトリに、誰かがcommit/pushしたらSlackで通知を受け取りたいと思って試行錯誤したときのメモになります。Lamda関数はNode.jsで記述しています。
スクリーンショット
※ アイコンとCodeCommitの太字はSlack Incomming Webhookのカスタマイズで変更しています。
前置き
- CodeCommitやLamda、Slackの細かい話は書きません。
- Lamda関数のNode.jsのサンプルコードや注意点だけを書きます。
- 以下はすべてAWS Console上からの操作です。
処理の流れ
CodeCommit → トリガー → Lambda → Slack Incomming WebhookのURLにPOST → Slackからスマホアプリ等に通知が飛ぶ
Lamda関数
適当な名前でLamda関数を作成します。以下のサンプルコードをindex.jsに上書きします。options
のIncomming WebhookのURLと、中程にあるSlack上に表示するメッセージのBlock Kitテンプレートはお好みに合わせて修正します。
const AWS = require('aws-sdk');
const codecommit = new AWS.CodeCommit({
region: 'ap-northeast-1'
});
const https = require('https');
//const util = require("util");
const options = {
hostname: 'hooks.slack.com',
path: '/services/*******/*******/*******',
method: 'POST',
headers: {
"Accept" : "application/json",
"Content-Type" : "application/json; charset=UTF-8"
}
};
exports.handler = function(event, context) {
let repository = event.Records[0].eventSourceARN.split(":")[5];
let references = event.Records[0].codecommit.references;
let funcArr = references.map((x) => {
return new Promise((resolve,reject) => {
let params = {
commitId: x.commit,
repositoryName: repository
};
codecommit.getCommit(params, function(err, data) {
if (err) reject(err);
else resolve({params:params,data:data});
});
});
});
Promise.all(funcArr)
.then((values) => {
//console.log(util.inspect({
// values:values
//},{colors:true, depth: null}));
return new Promise((resolve,reject) => {
let blocks = [];
blocks.push({
type: 'section',
text: {
type: 'mrkdwn',
text: `new commit pushed to \`${references[0].ref}\`\n\n*Repository:* "${repository}"`,
}
});
let v = values.map((x) => {
let tmp = new Date(x.data.commit.committer.date.split(' ')[0]*1000);
tmp = `${tmp.getFullYear()}/${('0'+(tmp.getMonth()+1)).slice(-2)}/${('0'+tmp.getDate()).slice(-2)} ${('0'+tmp.getHours()).slice(-2)}:${('0'+tmp.getMinutes()).slice(-2)}:${('0'+tmp.getSeconds()).slice(-2)}`;
return {
type: 'section',
fields: [
{
type: 'mrkdwn',
text: '*CommitId:*\n'+x.params.commitId
},
{
type: 'mrkdwn',
text: '*Comment:*\n'+x.data.commit.message
},
{
type: 'mrkdwn',
text: '*Committer:*\n'+x.data.commit.committer.name
},
{
type: 'mrkdwn',
text: '*When:*\n'+tmp
}
]
};
});
values = {blocks:blocks.concat(v)};
resolve(values);
});
}).then((value) => {
//console.log(util.inspect({
// value:value
//},{colors:true, depth: null}));
let req = https.request(options, (res) => {
let body = '';
//console.log('statusCode: '+res.statusCode);
res.setEncoding('utf8');
res.on('data', (chunk) => {
body += chunk;
});
res.on('end',() => {
//console.log({body:body});
context.done(null,body);
});
});
req.on('error',(e) => {
//console.log({e:e});
context.fail(e);
});
req.write(JSON.stringify(value));
req.end();
}).catch((err) => {
//console.log({err:err});
context.fail(err);
});
};
Lambdaのアクセス権限
- Lambda アクセス権 → 実行ロール → IAMロールの設定が別ウィンドウで開く
- 「ポリシーをアタッチします」で
AWSCodeCommitReadOnly
をアタッチ
Lambdaのトリガー
- Lambda 設定 → デザイナー → トリガーの追加
- トリガーの設定 →
CodeCommit
を選択 - リポジトリ名選択、トリガー名に
slackWebhookTrigger
など入力、ブランチ名をすべてのブランチを選択 - 追加
通知のテスト
- CodeCommit リポジトリ選択
- 設定 → トリガー →
slackWebhookTrigger
などトリガー名のリンク - ページ下部 → トリガーのテスト
Lambdaの注意点
環境変数を設定しないと通知内容に含まれる時刻がUTCになってしまいます。以下を設定します。
- Lambda 設定 → 環境変数 → キー:
TZ
、値:Asia/Tokyo
を追加
デバッグ
Lambda関数内のconsole.logのコメントアウトを外し、CloudWatch Logsでどこでエラーが発生しているか確認します。
参考URL
例: AWS Lambda 関数の AWS CodeCommit トリガーを作成する
https://docs.aws.amazon.com/ja_jp/codecommit/latest/userguide/how-to-notify-lambda.html
以上です。