Next.js × GraphQL で GitHubからcontributions数を取得

Next.js

TypeScript

GitHub

はじめに

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].ts
import { 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.ts
export 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();

みたいな感じで使うことができる。

自分の欲しい情報のみ取得できるので便利ですね。

みきどーざん

@take_cantik

目次