今週の開発がんばりを自動レポートする
みなさん、課題をいっぱい見つけていっぱい解決してますか?
そういうのってちょっと褒められたくないですか?
私は褒められたいです。
他のチームもそういうので褒められるきっかけになるといいなと思ってます。
という動機づけで
・毎週金曜に issue を集計して
・グラフ化して
・Slack で定時投稿してくれる
という Zapier を作りました。
Zapier にグラフ作成してくれるサービスあるかなーと雑に探してみたんですが見つからず。
そこで、無料でグラフ作成できる API を提供している QuickChart を利用することにしました。
以下のドキュメントによると無償版では 1 chart/sec という rate limit があるようで、有償版を利用すると解除されるようです。
様々なグラフが使えるようなので合わせてチェックしてみるといいかもしれません。
ということで、作るものを整理すると
・毎週金曜に(GitHub API で) issue を集計して
・(QuickChart API で)グラフ化して
・Slack で定時投稿してくれる
となります。
それがこちら。
1. は名前の通り毎週金曜17時に起動するという schedule だけなので、2. 以下から補足。
2. 今週のチケット状況
ここでは
・月曜 0:00以降に変更があった issue を GitHub API v4 で取得する
・月曜以降に新規作成されているものは曜日別に集計
・月曜以降にクローズされているものは曜日別に集計
・集計結果をまとめた JSON を返す
ということをしてます。
今回は issue 100 件までしか取ってきてないのですが、正確に集計する場合は pageInfo を使って pagination する必要があります。
// input data に GitHub API call 用 token をセットしています
// 金曜日の0時0分にセット
var date = new Date()
date.setHours(0,0,0,0)
var monday = date
monday.setDate(monday.getDate() - 4)
const header = {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization': `Bearer ${inputData.githubToken}`
}
// check https://developer.github.com/v4/explorer/
const query = `{
repository(owner: "orgName", name: "yourRepoName") {
issues(first: 100, filterBy: {since: "${monday.toISOString()}"}) {
totalCount
nodes {
createdAt
closedAt
}
pageInfo {
endCursor
hasNextPage
}
}
}
}`
const body = { 'query': query }
const res = await fetch('https://api.github.com/graphql', {
method: 'POST',
body: JSON.stringify(body),
headers: header
})
const json = await res.json()
// QuickChart API 用の JSON を用意して次のステップに流用します
// Zapier の input data は常に String 変換されてしまうので
// 各 issue status 用配列を input data に渡して連想配列を組み立てるよりは楽かも
var seeds = {
chart: {
type: 'bar',
data: {
labels: ['月', '火', '水', '木', '金'],
datasets: [
{
label: '新規作成',
data: [0, 0, 0, 0, 0]
},
{
label: 'クローズ',
data: [0, 0, 0, 0, 0]
}
]
}
}
}
const graphJson = await json.data
.repository
.issues
.nodes
.reduce((acc, cur) => {
const createdAt = new Date(cur.createdAt)
if (monday <= createdAt) {
acc.chart.data.datasets[0].data[createdAt.getDay() - 1] += 1
}
if (cur.closedAt !== null) {
const closedAt = new Date(cur.closedAt)
if (monday <= closedAt) {
acc.chart.data.datasets[1].data[closedAt.getDay() - 1] += 1
}
}
return acc
}, seeds)
return {
"json": JSON.stringify(graphJson)
}
上記のコード中でも触れてますが、QuickChart API の Request Parameter をここで用意しています。
{
chart: {
type: 'bar',
data: {
labels: ['月', '火', '水', '木', '金'],
datasets: [
{
label: '新規作成',
data: [0, 0, 0, 0, 0]
},
{
label: 'クローズ',
data: [0, 0, 0, 0, 0]
}
]
}
}
}
今回は棒グラフ(type: 'bar')を使ってます。
他のグラフを指定したいときは以下を参照。
これをもとに曜日別に increment して、次以降の Zap で使えるように返します。
3. QuickChart API でグラフ取得
先程の Zap で返された JSON (String) を引数にしてグラフ作成 API を叩きます。
成功すれば url にグラフ画像の URL が入ります。
// input date に先程の JSON を入れておく
const header = {
'Accept': 'application/json',
'Content-Type': 'application/json'
}
// https://quickchart.io/documentation/#parameters
const res = await fetch('https://quickchart.io/chart/create', {
method: 'POST',
body: inputData.graphJson,
headers: header
})
const json = await res.json()
const url = await json.url
return { "url": url }
4. Slack に投稿
生成された画像 URL を Attach Image By URL にして投稿すれば完成です。
がんばりを可視化しよう
自分で自分を褒めるきっかけをつくるもよし、他人を褒めるきっかけにするもよし。
他人に褒められるきっかけにするもよし。
ちなみに社内ではこれを CS チケット消化サマリーとして使ってます。
問い合わせ対応は基本大変な作業なので激励していきたい。
他にもいいアイデアあればまたなにか書きます。
読んでいただきありがとうございますー よろしければシェアもおねがいします🙏