APIでQiitaのいいね数を取得し，推移をグラフ化したらクソオモロくなった件。

## 背景
**【Qiitaの記事の，いいね数の推移をグラフ化できないの？】**
そう思ったのがきっかけでした．

Qiitaにはそういった設定は容易されていません．

しかし，[Qiita API v2](https://qiita.com/api/v2/docs)を用いると，`誰が`，`いつ`，`どの記事にいいね`をしたのか，`コメント`や，`トレンドの記事`等，たくさんのデータにアクセスすることができます．

また，グラフ化したデータを，**GitHubのトップページに貼れば**，記事を投稿するモチベーションがキープできるかもしれません．







## 製作物

 GitHubのトップページにグラフを埋め込みました（下にあるグラフです）．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457930/81c772b0-23cf-33f6-7261-9c68f46ac51d.png)

GitHubのトップページでQiitaの詳細も確認できたら，便利ですよね．

`GitHubAction`を使用し，指定した時刻（今回は，毎日午前3時）に，過去の記事の情報を一括取得し，反映させています．


:::note
ちなみに．
上記で表示されている，【コミット履歴を3Dモデル化してGitHubに表示する方法】は下記からご確認いただけます．

:::


https://qiita.com/kanaji2002/items/04a11f7ef64c70c33c8f



## 作成方法
### ステップ1: QiitaAccessToken の取得
`Qiitaにログイン` ⇒`設定`⇒`アプリケーション設定`⇒`アプリケーション設定`⇒`新しいアクセストークンを発行`⇒`read_qiita（公開されている投稿の閲覧）を選択`

発行されたアクセストークンをどこかに保存しておきます．

### ステップ2: GitHubで，プロフィール用のリポジトリを作る
usernameと同じ名前のpublicリポジトリでを作成してください．この際，READMEファイルも一緒に作成してください．

:::note info
usernameと同じ名前のproject nameを作成することで，そのユーザ自身のプロフィールを管理できる権限が与えられます．
僕の場合だと，kanaji2002というユーザネームなので，kanaji2002というpublicリポジトリを作成しました．
:::

### ステップ3: ワークフローファイルを作る
リポジトリで `Add file` -> `Create new file` を選んで、以下のようなファイル名でワークフローファイルを作成します。

**ファイル名：** `.github/workflows/qiita_likes_to_github.yml`

スケジュールは1日1回開始するように設定されています。
起動時間を都合の良い時間に修正してください。

cron の指定は UTC なので、そこだけ注意してください。
以下のサンプルは日本時間の深夜（早朝）の３時に，動くようになっています。

下記のコードを張り付けてください．


```:.github/workflows/qiita_likes_to_github.yml
name: Qiita-Likes-Graph

on:
  schedule:
    - cron: "0 18 * * *"  # 毎日18:00 UTCに実行
  workflow_dispatch:

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
        env:
          ACTIONS_NODE: '16'  # Nodeのバージョンを指定
        
      - name: Set up Python
        uses: actions/setup-python@v4
        with:
          python-version: '3.x'
        env:
          ACTIONS_NODE: '16'
      
      - name: Install dependencies
        run: |
          pip install requests pandas matplotlib
      
      - name: Run script to generate graph
        env:
          ACCESS_TOKEN: ${{ secrets.QIITA_ACCESS_TOKEN }}
        run: |
          python <<EOF
          import os
          import requests
          import pandas as pd
          import matplotlib.pyplot as plt
          from datetime import datetime

          access_token = os.getenv('ACCESS_TOKEN')
          user_id = 'kanaji2002（➡あなたのQiitaIDに変更)'
          url = f'https://qiita.com/api/v2/users/{user_id}/items'
          headers = {'Authorization': f'Bearer {access_token}'}
          likes_data = []
          page = 1
          while True:
              response = requests.get(f'{url}?page={page}&per_page=100', headers=headers)
              if response.status_code != 200:
                  print("Error fetching data from Qiita API:", response.status_code)
                  break
              items = response.json()
              for item in items:
                  created_at = datetime.strptime(item['created_at'], '%Y-%m-%dT%H:%M:%S%z').date()
                  likes_count = item['likes_count']
                  likes_data.append({'date': created_at, 'likes_count': likes_count})
              if len(items) < 100:
                  break
              page += 1

          df = pd.DataFrame(likes_data)
          df['date'] = pd.to_datetime(df['date'])
          start_date = df['date'].min()
          end_date = df['date'].max()

          daily_likes = df.groupby('date')['likes_count'].sum().cumsum()
          plt.figure(figsize=(10, 5))
          plt.plot(daily_likes.index, daily_likes.values,
                   color='black', linewidth=2.5, linestyle='-', marker='o',
                   markersize=6, markerfacecolor='orange', markeredgecolor='red', alpha=0.8)
          plt.xlabel("Date")
          plt.ylabel("Total Likes")
          plt.title(f"Number of good likes of {user_id}")
          plt.xticks(rotation=45)
          plt.grid()
          plt.tight_layout()
          plt.savefig("output.png")
          EOF
      
      - name: Commit & Push output
        run: |
          git config user.name github-actions
          git config user.email github-actions@github.com
          git add output.png
          git commit -m "Add generated graph for Qiita likes"
          git push
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
```
#### ※変更する点
user_idが，上記のコードではkanaji2002となっていますが，ご自身のQiitaIdに変更してください．

:::note info
補足：user_idは，Qiitaのトップページで確認することができます．@を削除した文字がuser_idです．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457930/42dc7ac3-e478-2e81-fdd3-533b7fec71d4.png)
:::

#### ※変更しなくてもいい点
下記のアクセストークン名は変更しなくても大丈夫です．
- QIITA_ACCESS_TOKEN（Qiitaのアクセストークンが入っている変数）
- GITHUB_TOKEN（GitHubのデフォルトのアクセストークン．特に設定は必要なし）

QIITA_ACCESS_TOKENに関しては，取得したアクセス変数を，登録する必要があります．


### ステップ4: Qiitaのアクセストークンのsecrets化
①作成したプロジェクトに戻り，`settings`
②左側の `Secrets and variables` ⇒ `Actions`
③`new repository secret`
④name ：GIT_HUB_TOKENS (ファイル内で登録した名前），
secret : コピーしておいたアクセストークン
⑤Add secret

間違っても，QiitaのアクセストークンをPublicなコードにそのまま貼り付けないでください．上記のように，シークレット化してください．

### ステップ4: Workflowの書き込み権限の付与 
作成したプロジェクトの`settings` ⇒ `Actions` ⇒ `General`
内の，Workflow permissionsのブロックの，`Read and write permissions`にチェックを入れる．

### ステップ5: READMEファイルの設定

もしREADMEがない方は，新たに作成してください．

``` bash : README
## Qiitaのいいね数の推移
![Qiita Likes Graph](./output.png)

## kanaji2002の[Qiitaプロフィール](https://qiita.com/kanaji2002)

```

上記のコードを張り付けます．
3行目は，Qiitaのページに飛ぶためのリンクです．ご自身のものに変更してください．

**[解説]**
GitHub上で作成したyamlファイルを定期実行，または手動実行すると，output.png（いいねの推移のグラフ）が作成，コミット&プッシュされます．
それを，上記のコードで表示させています．


### 手動での実行テスト
正常に動くのかどうかを，テストする必要があります．
手動での実行方法は，下記です．
作成したプロジェクトの，`Actions` ⇒ `Qiita-Likes-Graph` ⇒ `Run workflow`
成功していれば，自分のプロフィールに反映されていると思います．

手動で動かして問題がないようであれば，指定した時刻に自動で反映されます．

#### 完成
上記の方法で作成した，私のGitHubのプロフィール下記です．

https://github.com/kanaji2002










### 補足：Pythonのコード“のみ”で動かす方法
GitHubに反映させず，ただただ実行してグラフを作成する方法です．

```bash: bash
pip install requests pandas matplotlib
```

下記のトグルリスト内のコードの，`Qiitaのアクセストークン`と，`ユーザID`を書き換え，実行すると，グラフが表示されます．


<details>
  <summary>コードはこちらを展開してください．</summary>

``` pyhon:QiitaLikes.py
import requests
import pandas as pd
import matplotlib.pyplot as plt
from datetime import datetime

# Qiitaアクセストークンを設定（実際のアクセストークンに置き換えてください）
access_token = 'ここにアクセストークンを記載'

# 自分のユーザーIDを指定
user_id = '例：kanaji2002（➡あなたのQiitaIDに変更）'

# APIリクエストの準備
url = f'https://qiita.com/api/v2/users/{user_id}/items'
headers = {'Authorization': f'Bearer {access_token}'}

# データを保存するリスト
likes_data = []

# ページネーション対応（1ページあたり最大100件）
page = 1
while True:
    # 各ページのリクエスト
    response = requests.get(f'{url}?page={page}&per_page=100', headers=headers)
    
    if response.status_code != 200:
        print("Error fetching data from Qiita API:", response.status_code)
        break
    
    items = response.json()
    
    # 各投稿の「いいね」数と日付を取得
    for item in items:
        created_at = datetime.strptime(item['created_at'], '%Y-%m-%dT%H:%M:%S%z').date()
        likes_count = item['likes_count']
        likes_data.append({'date': created_at, 'likes_count': likes_count})
    
    # 次のページがない場合は終了
    if len(items) < 100:
        break
    page += 1

# データフレームに変換
df = pd.DataFrame(likes_data)
df['date'] = pd.to_datetime(df['date'])

# 最初の日付と最新の日付の範囲を取得
start_date = df['date'].min()
end_date = df['date'].max()


# 日ごとの「いいね」数を合計して累積和を計算
daily_likes = df.groupby('date')['likes_count'].sum().cumsum()

# グラフの線を太くする
plt.plot(daily_likes.index, daily_likes.values, 
         color='black',         # 線の色
         linewidth=2.5,           # 線の太さ
         linestyle='-',           # 破線
         marker='o',               # 丸いマーカー
         markersize=6,             # マーカーのサイズ
         markerfacecolor='orange', # マーカーの内部色
         markeredgecolor='red',    # マーカーの枠色
         alpha=0.8,                # 透明度
        )     # ラベル

# # グラフの描画
# plt.figure(figsize=(10, 5))

plt.xlabel("Date")
plt.ylabel("Total Likes")
plt.title(f"Number of good likes of {user_id}")
plt.xticks(rotation=45)
plt.grid()
plt.tight_layout()
plt.show()
```

</details>


## まとめ
転職をする際，GitHubやQiitaの提出を求める会社が増えてきています．
本記事では，`GitHubのトップページ`で`Qiitaのいいね数`も確認できるようになりました．


自分の`アプトプットの量を分かりやすく可視化`し，**就活**，**転職**を有利に進めましょう！