GitHub API v3で「自分がstarを付けたリポジトリの一覧」を取得する
表題のとおりです。
自分がstarを押したGitHubリポジトリのURLをChromeのブックマークに追加したくなったので、GitHub側で用意されているREST APIを使って情報を取得することにしました。
個人的な備忘録も兼ねて、順を追って方法を解説します。
1. 任意のユーザーの情報を取得するREST APIを使い、自分が押したstarの情報を取得する
1-1. star情報取得APIの叩き方
curl
curl -H "Accept: application/vnd.github.v3+json" https://api.github.com/users/stepney141/starred
wget
wget --no-check-certificate --header="Accept: application/vnd.github.v3+json" -q -O - https://api.github.com/users/stepney141/starred
このように、 GET api.github.com/users/ユーザー名/starred
が該当するエンドポイントとなります。上の例では私のアカウントを指定しています。
情報は普通にjsonで返ってきます。エンドポイント自体の詳しい仕様は、下記参考文献 1.を参照してください。
1-2. とりあえずこうやればOK
curlの使い方をよく知らないので、個人的に使い慣れているwgetを使って叩いてみます。APIというと何かとcurlが使われがちですが、wgetでも普通に行けます。
#!/bin/bash wget --no-check-certificate \ --header="Accept: application/vnd.github.v3+json" \ -q -O - \ https://api.github.com/users/stepney141/starred\?per_page=100\&page={1..3} \ | jq add -s \ | jq '.[] | [ .full_name, .html_url, .description ] | @csv' -r \ > stars_repo.txt
処理の流れとしては
「Bashのブレース展開を使用し、wgetでjsonを一気に3つ入手
-> jqに渡して結合
-> さらにjqに渡して『リポジトリ名』『ブラウザ用URL』『リポジトリ説明文』のみを抽出、CSV化
-> txtに出力」
という感じです。
wgetのオプションについて:
--no-check-certificate
:接続先のSSL証明書のチェックを切る。wgetのSSL関連エラーはこれをつければとりあえず全て解決する
-q
:wgetからのシステム出力(エラー表示やダウンロード情報など)を全てミュートする
-O -
:ダウンロードした内容を標準出力に流す
補足事項
2. 現在認証中のユーザーの情報を取得するREST APIを使い、同じことをする
さて、上の手順ではprivate repositoriesの情報が取得できません。なので、認証してprivate repositoriesの情報も取れるようにします。
というのも、GitHubのユーザーページの表示では「この人は225個のstarを押してますよ」と出ていたにも関わらず、上のAPIで私が取れたのは224個だけだったのです。
このため「もしかしてprivate repositoryが抜けてるのかな?」と考え、認証して試してみることにしました。
GitHubの認証方法にはいくつかあるようですが、今回はネットですぐ情報が集まり、なおかつTwitter APIで触ったことのあるOAuth Appを使うことにしました。
2-1. OAuth Appの認証のやり方
※出典:下記参考文献3.と4.
その1.
https://github.com/settings/applications/new からGitHubアカウントに紐付けられたOAuth Appを作成し、Client IDとClient Secretを入手する。
※Client ID 、Client Secretはそれぞれ環境変数 CLIENT_ID 、CLIENT_SECRET として保存しておくことを推奨します。
※Callback URLの設定は必須です。ぶっちゃけ何のURLを入れようと問題ないっぽいが、一応自分が保有/管理しているURLを使う方がいいかも? 自分は自身のgithub.ioのURLを入力しました。
その2.
https://github.com/login/oauth/authorize?client_id=$CLIENT_ID&scope=repo にブラウザでアクセスする。
そうするとApp Authorizationの画面が出てくるので、ボタンを押して承認する。
その3.
ボタンを押して承認すると、 https://stepney141.github.io/?code=0123456789abcdefg みたいな感じで、自分が指定したCallback URLにリダイレクトされる。
末尾にqueryとしてぶら下がっているCodeをコピペしておく。
※Codeは環境変数 CODE として保存しておくことを推奨します。
その4.
Code、Client ID、Client Secretを https://github.com/login/oauth/access_token にPOSTする(以下はcurlでの例)。
※この例ではCode、Client ID、Client Secretの情報がBashの環境変数として保存されていることを想定しています。適当に読み替えられたし。
curl -X POST \ -d "code=$CODE" \ -d "client_id=$CLIENT_ID" \ -d "client_secret=$CLIENT_SECRET" \ https://github.com/login/oauth/access_token
その5.
POSTすると access_token=0123456789abcdef0123456789abcdef01234567&token_type=bearer
というような形式でアクセストークンが返ってくる。
これをリクエストヘッダに入れてAPIを叩く。
※アクセストークンは例によって環境変数 ACCESS_TOKEN として保存しておくことを推奨
2-2. とりあえずこうやればOK
GET api.github.com/user/starred
が今回の目的に合致するエンドポイントです。詳細は下記参考文献2. を参照してください。
下に私が使った入力を示します。例によってwgetと環境変数を使っているので、適当に読み替えて下さい。
#!/bin/bash wget --no-check-certificate \ --header="Accept: application/vnd.github.v3+json" \ --header="Authorization: bearer $ACCESS_TOKEN"\ -q -O - \ https://api.github.com/user/starred\?per_page=100\&page={1..3} \ | jq add -s \ | jq '.[] | [ .full_name, .html_url, .description ] | @csv' -r \ > stars_repo_auth.txt
これはエンドポイントが変わっただけで、処理の内容自体は上の例と全く変わっていません。
エンドポイントの詳しい仕様は下記参考文献 2.を参照してください。
で、結局このエンドポイントを使っても取れたリポジトリは224個のまま変わりませんでした。つまり、妖怪いちたりないの正体はプライベートリポジトリではありませんでした。
原因は何なのか、結局この取れなかった1個の正体は何だったのかは不明です。
個人的にはGitHub側のバグを疑ってます(実は224個が正しい数字で、GitHubの表示自体が間違っている説)。
とりあえずこの224個を手作業でChromeブックマークに追加するのは御免蒙りたいところですので、Chromeの拡張機能を作ってどうにかしようと考えています。作業完了したらまた備忘録を書きます。
その後
starしたGitHubリポジトリの情報や上で書いたワンライナーは、全部まとめてGitHubリポジトリとして管理することにしました。(Git運用法としてはEvil感がありますが)とりあえずシェルスクリプトスクリプトを実行してパスワードを入力する度にリポジトリの最新情報がpushされるようにしています。
参考文献
- https://docs.github.com/en/rest/reference/activity#list-repositories-starred-by-a-user
- https://docs.github.com/en/rest/reference/activity#list-repositories-starred-by-the-authenticated-user
- https://qiita.com/ngs/items/34e51186a485c705ffdb
- https://qiita.com/developer-kikikaikai/items/5f4f0e2ea274326d7157