実現したいこと
Backlogの更新をChatworkに伝たい。
それも、安く。今風に。
(実際、参考に書いた記事の焼き直しです。。先人の知恵に感謝です。)
出来たもの
手順
Fluctを利用して、アプリケーションを生成する。
fluct new backlog-to-chatwork
cd backlog-to-chatwork
fluct generate webhook
package.jsonにライブラリを設定する。
request
モジュールを利用するため、package.json
に追加しておきます。
(Fluctにバグがある気がします。後述します。)
Actionの設定を変更する。
{
"name": "webhook",
"private": true,
"fluct": {
"contentType": "application/json",
"httpMethod": "POST",
"path": "/webhook",
"statusCode": 200
}
}
httpMethod
をPOSTに変更し、path
を任意の値に設定します。
メインのJSを実装する。
var request = require('request');
// constants
var CHATWORK_API_KEY = 'XXX';
var ROOM_ID = 'XXX';
var BACKLOG_URL = 'https://XXX.backlog.jp/';
function create_link(event, content) {
var url = BACKLOG_URL + "view/" + event.project.projectKey + "-" + content.key_id;
if (content.comment && content.comment.id) {
url += "#comment-" + content.comment.id;
}
return url;
}
function create_links(event, link) {
var urls = [];
link.forEach(function(content) {
urls.push(create_link(event, content));
});
return urls;
}
function create_message(event) {
switch(event.type) {
case 1:
return "[info][title]" + event.createdUser.name + "が「" + event.content.summary + "」を追加しました。[/title]" + create_link(event, event.content) + "[/info]";
case 2:
case 3:
return "[info][title]" + event.createdUser.name + "が「" + event.content.summary + "」を更新しました。[/title]" + create_link(event, event.content) + "\n\n" + event.content.comment.content + "[/info]";
case 14:
return "[info][title]" + event.createdUser.name + "が課題をまとめて更新しました。[/title]" + create_links(event, event.content.link).join("\n") + "[/info]";
}
return "unknown event type: " + event.type;
}
function post_to_chatwork(message, callback) {
var url = 'https://api.chatwork.com/v1';
var options = {
url: url + "/rooms/" + ROOM_ID + "/messages",
headers : {
'X-ChatWorkToken': CHATWORK_API_KEY
},
form: {
'body': message
}
};
request.post(options, function (error, response, body) {
if (!error && response.statusCode == 200) {
console.log(body);
}
callback(error, response, body);
});
}
exports.handler = function(event, context) {
console.log('start event');
var message = create_message(event.requestParameters);
console.log('send message: ' + message);
post_to_chatwork(message, function(error, response, body) {
console.log('response body: ' + body);
console.log('end event');
context.done(null, 'ok');
});
};
認証情報などを下記のように設定する必要があります。
CHATWORK_API_KEY
:Chatworkから取得したAPIトークン
ROOM_ID
:送信先のroom_id
BACKLOG_URL
: Backlog登録時のサブドメインを設定したURL
とりあえずということで、課題の追加・更新のみを対象としています。
デプロイする
fluct deploy
デプロイが成功すると、URLが返却されます。
Uploaded function: webhook
Updated endpoint: POST /webhook
Deployed: https://XXX.execute-api.us-east-1.amazonaws.com/production
Backlogのwebhook設定する。
デプロイ時に返却されたURL+パスをBacklogに設定します。
確認する。
Backlog上で、課題を追加してみる。
Chatworkの指定のチャットルームに、下記のようなメッセージが表示される。
困ったこと
event
変数の形式
最初は、Fluct無しで実装していました。
その時は、メインのhandler
内でevent.type
のようにwebhookの内容が取得できていました。
それが、Fluctを使うと取得できなくなって、event
をそのまま取得してみると、event.requestParameters.type
のように取得する必要があることがわかりました。
何が違うのか調べたところ、API GatewayのIntegration Request
にMappingが設定されていました。
ここで、JSONの形式を変換していたようです。
request
モジュールが読み込めない
Fluctのサンプルアプリケーションをみると、rootのpackage.json
に記載されているdependencies
は生成されたzipに取り込まれるようでした。
そのため、下記のように必要なモジュールだけを記載しました。
"dependencies": {
"request": "^2.62.0"
}
すると、zipファイルに取り込まれませんでした。
https://github.com/r7kamura/fluct/blob/3b58f6b876534abc445b15a535d77616b51fcf2d/src/composer.js#L120
ここで、this.application.getProductionPackageNames()
がArrayじゃないからな気はしてるけど、深追いしてないです。
とりあえず、2つにしたらちゃんと動きました。