この記事はkintone Advent calender 2021の12/3を担当します!🎄
kintoneで全てを管理したい…
弊社しいては僕らのチームでは、kintone上でタスク管理・コミュニケーションをしています。
しかしコードの管理はGithub、ビデオ会議ではzoomというように、kintoneだけでなくさまざまなwebサービスを使って業務が成り立っています。
今まではGithubで自分たちが管理しているプロジェクトのコードにissueが登録されたり、dependabotによるPull Requestが行われた際は、手動でTaskとしてkintoneに登録していました。これが非常にめんどくさい…ヒューマンエラーも出てしまう…
今回これを、Github Webhook をトリガーにしてAWS経由でkintoneにrecord登録することで、従来手動で行っていた作業を自動化したのでシェアします!
で、どんなの作った?
基本的には以下の流れです。
- Github webhook
- AWS lambdaで実行
- kintoneにGithubの情報をレコード登録。
1.dependabotのPR→レコード登録
僕らが管理しているプロジェクトのライブラリがバージョンアップした際に、dependabotからPull Requestが来ます。
こいつの情報を取得して、PR来ると同時にレコードを追加させたい!
cybozuのESLintのルールセットがアップデートきた時の挙動です↓
Github側画面
kintone側画面
こんな感じでライブラリの情報などをkintoneへ渡してレコード登録できました!
2.issueの登録→レコード登録
OSSも管理しているので、issueが来たら確認する必要があります。
kintoneでコミュニケーションしているので、kintoneで確認できると尚良い!!
Github側画面
kintone側画面
issueのtitleとbodyをkintoneに渡し、レコードが登録されました!
実装内容
使った技術たち
- typescript
- webpack
- API Gateway
- lambda
- serverless framework
- kintone-rest-api-client
こんな感じで実装したよ!
セットアップ
まずserverless frameworkのプロジェクトを作成する必要があります。
今回はtypescript + AWSでセットアップ。
$ sls create -t aws-nodejs-typescript -p github-to-kintone
また、バンドルとコンパイルにwebpackを使用しました。
serverless frameworkでwebpackを使用する際は少し設定が必要です。
plugins: ['serverless-webpack'],
プラグインを設定し、serverless.tsに記述。
これで大体のセットアップが完了しました。
今後はsrc/functions
配下に処理を記述していきます。
functionの設定などをする
httpのメソッドとfunctionの名前を命名してあげましょう。
import { handlerPath } from "../../libs/handlerResolver";
export default {
handler: `${handlerPath(__dirname)}/handler.main`,
events: [
{
http: {
method: "post",
path: "function_name",
},
},
],
};
hander.tsの作成された関数の内部に書いていく
sls create
を打った際に作成された関数があると思うのでその中に処理を記述します。
最初に送信元の検証します。
下準備として、ruby -rsecurerandom -e 'puts SecureRandom.hex(20)'
で取得したランダムな文字列を秘密鍵としてGitubに登録してください。
Githubが送ってくるhash値がプログラム側で計算したのと同じになるか計算させます。これにより安全なリクエストかどうかわかります。詳しくはGithubのドキュメントをご覧ください。
const hashFromGithub: string = event.headers["X-Hub-Signature-256"];
// isAllowed()は自前で用意した検証するための関数
if (!isAllowed(SECRETS, event, hashFromGithub)) {
return;
}
eventにpayloadが入ってくるのでその情報を利用し、Github webhookの情報に応じた処理の分岐を実現。
const githubEventName: string = event.headers["X-GitHub-Event"];
const eventBodyAction: string = event.body.action;
const user: string = event.body.sender.login;
if (
githubEventName === "pull_request" &&
eventBodyAction === "opened" &&
user === "dependabot[bot]"
){
// dependabot[bot]によるPull Requestの場合の処理
}
if (githubEventName === "issues" && eventBodyAction === "opened") {
// issueがオープンした際の処理
}
ifのブロックの中で実際にkintoneにレコード登録していきましょう。
kintoneのREST APIを打つために今回、@kintone/rest-api-clientを使用しています。packageの詳しい使い方はここでは割愛。
// rest API clientに渡すパラメータを返す部分を関数に切り出し。
export const returnParams = (
appId: number,
summaryValue: string,
descriptionValue: string
): Params => {
const params: Params = {
app: appId,
record: {
Summary: {
value: summaryValue,
},
Description: {
value: descriptionValue,
},
},
};
return params;
};
// レコード登録に含めたい情報を関数に渡して、整形する。
const sendToKintoneParams: Params = returnParams(appId, alertSummary, alertDescrption);
// レコード登録
await client.record.addRecord(sendToKintoneParams);
そして、AWSにデプロイして挙動を確認。
serverless.tsに適切な認証情報を記述したのちに、sls deploy
コマンド打ちましょう。
Githubの適用させたいrepositoryに行き、setting>webhookからエンドポイントのurlやevent、secretsの設定をすれば終了です。
個人的に大変だった部分!
ログインするためのセキュリティパラメーター
弊社が使っているkintone環境でrest api clientを用いてログインしrecord操作するためには、セキュアアクセスのパラメーターを設定する必要があります。
↓下記のような感じでclientのインスタンスを生成することで設定できました。
const client: KintoneRestAPIClient = new KintoneRestAPIClient({
baseUrl: KINTONE_DOMEIN,
auth: {
username: KINTONE_USERNAME,
password: KINTONE_PASSWORD,
},
clientCertAuth: {
pfxFilePath: path.resolve(
__dirname,
"../../../certs/file_name.pfx"
),
password: KINTONE_CERT_AUTH_PASSWORD,
},
});
hashの照合
上記でも紹介しましたが、Github webhookのセキュリティの保護を設定しました。
const hash: string = createHmac("sha256", secrets)
.update(JSON.stringify(event.body))
.digest("hex");
まとめ
serverless frameworkを使うとlambdaが扱いやすくなるし、kintoneとlambdaの相性は抜群です!
ぜひ他のサービスとkintoneを連携してみてください!