はじめに
人力作業が嫌い、無くしたいと言う願望から
GraphQLを使うための備忘録
GASで集計結果をgoogle sheetに書き込む(略)
今までのgithub apiではproject(beta)が取れない
手順
- Github Personal access tokens発行
- queryを作成する(もしくはmutations)
- リファレンス確認しながら必要なjson内容を組み込む
- queryを
https://api.github.com/graphql
APIで投げてquery通りのjsonが返ってくる - json stringを解析して結果出力
Github Personal access tokensについて
これはgithubのsetting画面から操作するだけ。
- Organizationの認証とか権限の設定とかあるかもしれない
- 今回はclassicのtokenを作ってrepoとprojectの権限を付与しました。
作り方
ここで初めて触った人は少し苦労するかもしれませんが構成や要件それぞれなので本当にリファレンスみてそれを理解した方が自由に組める。
今回の要件
- 集計したいissueは全て同じrepositoryにある
- 集計対象issueは特定のlabelが付く
- 集計対象issueは特定のproject(beta)に紐づかれている
- 対象issueの特定属性で合計値をassigneeごとに集計したい
まずはコード
const variables = {
org: "Your Org",
repo: "Your Repo",
assignee: "Your Assignee",
label: "Your Label",
since: "issue最後更新時間をfilterしている"
};
const query = `
query($org: String!, $repo: String!, $label: String!, $assignee: String, $since: DateTime!) {
repository(owner: $org, name: $repo) {
issues(last: 100, filterBy: {labels: [$label], since: $since, assignee: $assignee}) {
totalCount
nodes {
number
title
url
projectItems(first: 1) {
nodes{
filterColumn: fieldValueByName(name: "filterかけたい項目名") {
... on ProjectV2ItemFieldIterationValue{
title
}
}
cost: fieldValueByName(name: "集計したい値") {
... on ProjectV2ItemFieldNumberValue{
number
}
}
}
}
}
}
}
}
`;
const options = {
method: "POST",
headers: {
"Authorization": `Bearer ${Your token}`,
"Accept": "application/json",
"Content-Type": "application/json"
},
payload: JSON.stringify({ query: query, variables: variables })
};
const response = UrlFetchApp.fetch('https://api.github.com/graphql', options);
const issues = JSON.parse(response.getContentText());
今回使ったobject
- repository
- issueconnection(issuesの中身)
- issue
- ProjectV2ItemConnection(projectItemsの中身)
- ProjectV2Item
-
ProjectV2ItemFieldValue(fieldValueByNameで取得した値の汎用型)
- 実際の型はprojectのcustom Fieldから各パラメータの
Field type
見ながらcastする
- 実際の型はprojectのcustom Fieldから各パラメータの
細かいポイント
- queryの変数について
- 変数声明仕方
$+変数名
:型
で使う時は$+変数名
-
!
がつくとnon null
、付かない場合はnullable
- object型入力はJson objectを引数として渡せます(例:
filterBy
のところ) - 声明した変数は
variables
objectに渡すとquery
に適応されます
- 変数声明仕方
- queryの中身について
- リファレンスから欲しいobjectを探し出しましょう
- 全てのobjectは
Node
を継承している -
nodes
がArrayになる - arrayにアクセスするためには基本paging想定されます
- 件数が少ない場合なら決め打ちで最大以上の件数分とってこれるが、多い場合はPageInfoを使ってpagingの仕組みをくむ
-
... on {Type}
が型filter、Arrayの中は汎用型が含まれる場合が多いからたくさん使う
- 認証について
- headderの
Authorization
にtoken
を渡す -
token
の前に固定文字Bearer+スペースを忘れずに - 認証失敗すると
401
のBad credentials
になる
- headderの
- レスポンスの使い方について
- query以下の構造は記載した階層の通りでjson string返却される。
- 例えば
filterかけたい項目名
をアクセスしたい場合はissues.data.repository.issues.nodes[0].projectItems.nodes[0].filterColumn.title
最後に
queryのデバグは割と簡単でresponse.getContentText()
の中にエラーの詳細が返却されるのでそれをLogに出せばなんとかなるはず。
ほぼ自分見返す用ですが誰かに役立つと嬉しいです。