arXiv毎日チェックするの大変だから自動化したい！

# はじめに
こんにちは！現在情報系の修士2年で画像系の深層学習の研究をしているKaitolabです。
今回は、<b>「arXivの新着記事を自動でチェックしてSlackに通知してくれるBot」</b>を作成した話をシェアしたいと思います。

## 背景 : arXivチェックの大変さ
私の研究分野（コンピュータビジョン、機械学習）では、[arXiv](https://arxiv.org/)という論文投稿サイトに毎日数百本の新しい論文が投稿されます。![スクリーンショット 2024-12-04 16.23.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3305858/0068e851-b948-ba78-9260-593b5d3fb1fd.png)その中から自分の研究に関連する論文を見つける作業はとても重要ですが、**毎日手動で精査するのは非常に大変です。**
「もっと効率化できないか？」と考え、
特定のキーワードに引っかかった論文だけを自動で通知してくれるBotを作ることにしました。


# arXivの新着記事を自動でチェックしてSlackに通知してくれるBot
このBotは、以下の手順で動作します：
1. arXivから過去24時間分の論文を取得
2. タイトルやアブストラクトに、指定したキーワード含まれる論文を抽出
3. 論文情報をSlackに投稿
 
Slack通知のイメージはこんな感じです👇

![arXivbot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3305858/f5229a39-2902-8698-5b2d-fe1b31e4a1c6.png)


# 技術的な実装
### 初期実装：Google Apps Script（GAS）
最初は、自分のGoogle Drive内で動作する小さなプロジェクトとして、**Google Apps Script (GAS)** を使って作成しました。
GASは手軽にスクリプトをかける一方で、以下の課題がありました。
- 研究室内でコードの共有・保守が難しい
- 複数人で利用するには不便
### Pythonで再実装＋GitHub Actions
研究室内で継続的に使えるツールにするため、研究室全員が使える**Pythonで再実装**し、Githubを活用して以下を実現しました。
- `Python` データの取得・フィルタリング・翻訳・通知処理
- `GitHub Actions` 毎日決まった時間に自動実行
- `Google Cloud Translation API` 論文の概要を翻訳
- `Slack Webhook` 通知を送信

## 実際の詳細
### 1. arXivデータの取得
以下のコードで、指定カテゴリ（例: cs.CV）の論文データを取得します。
```Python:Python
import requests
import xml.etree.ElementTree as ET

def fetch_arxiv_data(search_category: str, max_results: int = 150):
    api_url = f'http://export.arxiv.org/api/query?search_query=cat:{search_category}&start=0&max_results={max_results}&sortBy=submittedDate'
    response = requests.get(api_url)
    root = ET.fromstring(response.text)

    ns = {'ns': 'http://www.w3.org/2005/Atom'}
    papers = []

    for entry in root.findall('ns:entry', ns):
        papers.append({
            "title": entry.find('ns:title', ns).text.strip(),
            "summary": entry.find('ns:summary', ns).text.strip(),
            "link": entry.find('ns:id', ns).text.strip(),
            "published_date": entry.find('ns:published', ns).text.split('T')[0],
        })
    return papers
```
### 2. フィルタリングと翻訳
取得した論文データをキーワードと日付でフィルタリングし、翻訳します。
```Python:Python
import re
from datetime import datetime, timedelta

def filter_papers(papers, keywords, target_date):
    target_date_str = target_date.strftime('%Y-%m-%d')
    keyword_pattern = re.compile('|'.join(keywords), re.IGNORECASE)
    return [paper for paper in papers if paper['published_date'] == target_date_str and 
            (keyword_pattern.search(paper['title']) or keyword_pattern.search(paper['summary']))]

from google.cloud import translate_v2 as translate

def translate_text(text, target_language='ja'):
    translate_client = translate.Client()
    return translate_client.translate(text, target_language=target_language)['translatedText']
```
### 3. Github Actionsの設定
以下のコードで、GitHub Actionsを利用して毎日自動実行します。
```yaml:Github Actions
name: ArXiv Paper Notification

on:
  schedule:
    - cron: '0 3 * * *'  # 日本時間12時に実行
  workflow_dispatch:  # 手動実行も可能

jobs:
  run_script:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v3

      - name: Set up Python
        uses: actions/setup-python@v4
        with:
          python-version: '3.9'

      - name: Install dependencies
        run: |
          pip install --upgrade pip
          pip install -r requirements.txt

      - name: Set up Google Cloud credentials
        run: |
          echo "${{ secrets.GOOGLE_CREDENTIALS_BASE64 }}" | base64 --decode > credentials.json
          echo "GOOGLE_APPLICATION_CREDENTIALS=${{ github.workspace }}/credentials.json" >> $GITHUB_ENV
        shell: bash

      - name: Run script
        env:
          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
        run: python src/main.py
```
### 4. Secretsの設定
- `SLACK_WEBHOOK_URL` SlackのWebhook URLをGithub Secretsに登録
- `GOOGLE_CREDENTIALS_BASE64` Google Cloudの認証情報（JSON形式）をBase64エンコードして登録

:::note info
**ヒント**
GitHub Secretsの設定は、リポジトリのSettings > Secrets and variables > Actionsで行います。
:::

# まとめと今後の展望
このBotのおかげで、毎日投稿される膨大なarXiv論文から重要なものを効率よくキャッチできるようになりました。また、GitHub Actionsを活用することで、手間をかけずに研究室内で継続的に利用できる仕組みを実現しました。

今後の改善案として、以下のアイデアを検討しています：

1. 機械翻訳ではなく、GPTを活用した要約生成機能の追加
2. キーワードを外部ファイルで柔軟に管理
3. キーワードごとにSlackユーザーをメンションする機能

***
**質問やフィードバックは大歓迎です！** この記事が同じ課題を抱える方の役に立てば幸いです。ぜひコメントで感想や質問をお聞かせください！
***