Next.js × GraphQL で GitHubからcontributions数を取得
はじめに
GitHubログインをしてcontribution数を取得するため、にGraphQLを使ってみました。
今回はその時のメモを残していきます。
使用したもの
今回は GraphQLを用いたAPI ルート を使用してみました。
また、GitHubの情報を取得するために @octokit/core
を使用しました。
設定
GitHubのtokenの設定
https://github.com/settings/tokens
からPersonal access tokensを選択、
「Generate new token」を押して、
とりあえず repo
だけ選択しておけばOK
作ったtokenをenvに追加
ex)
NEXT_PUBLIC_GITHUB_API_KEY=***********
@octokit/core
のインストール
$ yarn add @octokit/core
GitHubのGraphQL APIを試してみる
https://docs.github.com/en/graphql/overview/explorer
ここからクエリを入力してどのような値を取得できるか試すことができる。
試しに
query contributions { // $userName を自身のgithubIdの文字列にする user(login: $userName) { // $to と $from を "YYYY-MM-DDThh:mm:ss"の形で入力 contributionsCollection(to: $to, from: $from) { contributionCalendar { weeks { contributionDays { date contributionCount } } } } } }
と入力して実行ボタンを押してみると、
{ "data": { "user": { "contributionsCollection": { "contributionCalendar": { "weeks": [ { "contributionDays": [ { "date": "2021-12-31T00:00:00.000+00:00", "contributionCount": 10 }, { "date": "2022-01-01T00:00:00.000+00:00", "contributionCount": 3 } ] }, { "contributionDays": [ { "date": "2022-01-02T00:00:00.000+00:00", "contributionCount": 7 }, . . .
といった形で出力されたと思います。
https://docs.github.com/en/graphql/reference/queries
ここから様々なクエリを知ることができるので、試してみてください。
コードを書いていく
今回、直近3日分のcontributions数を取得したかったので以下のようなコードを書いた。
また、現在時刻等を取得したかったので、dayjs
を使用しているため使う場合には、インストールを忘れずに。
~/pages/api/contributions/[userName].tsimport { Octokit } from "@octokit/core"; import dayjs from "dayjs"; import type { NextApiRequest, NextApiResponse } from "next"; type Contributions = { user: { contributionsCollection: { contributionCalendar: { weeks: [ { contributionDays: [ { date: string; contributionCount: number; } ]; } ]; }; }; }; }; export default async function handler( request: NextApiRequest, response: NextApiResponse ) { const { userName } = request.query; const octokit = new Octokit({ auth: process.env.NEXT_PUBLIC_GITHUB_API_KEY }); const now = dayjs().format("YYYY-MM-DDThh:mm:ss"); const twoDaysBefore = dayjs() .subtract(2, "day") .format("YYYY-MM-DDThh:mm:ss"); const query = ` query contributions ($userName:String!, $now:DateTime!, $twoDaysBefore:DateTime!) { user(login: $userName) { contributionsCollection(to: $now, from: $twoDaysBefore) { contributionCalendar { weeks { contributionDays { date contributionCount } } } } } } `; const contributions = await octokit.graphql<Contributions>(query, { userName, now, twoDaysBefore }); const dailyContributions: number[] = []; contributions.user.contributionsCollection.contributionCalendar.weeks.forEach( (week) => { week.contributionDays.forEach((contributionDay) => { dailyContributions.push(contributionDay.contributionCount); }); } ); return response.status(200).json({ values: dailyContributions }); }
これを書いて、localhost:3000/api/contributions/$userName
($userName は任意のgithubId)にアクセスしてみると、
{ values: [ 8, 4, 10 ] }
と表示されると思います。
実際に値を使う時
~/hook/useContributions.tsexport interface Contributions { values: number[]; } export const useContributions = () => { const getContributions = async (userName: string) => { const response = await fetch(`/api/contributions/${userName}`); return (await response.json()) as Contributions; // asは良くなさそう }; return { getContributions }; };
const { getContributions } = useContributions();
みたいな感じで使うことができる。
自分の欲しい情報のみ取得できるので便利ですね。
目次