🍣

IEEEの論文をChatGPTで要約して毎朝Slackに共有してくれるbotを作る!

2023/03/19に公開
1

前回の記事ではarxivの論文をChatGPTで要約して毎朝Slackに共有してくれるbotを作りました。

https://zenn.dev/ozushi/articles/ebe3f47bf50a86

しかし、arxivの論文は投稿スピードが早く、流行を追うことができる分、質のあまり良くない論文も紛れている可能性があります。

そこで、工学系で質の良い論文を採択しているIEEEのAPIを使って世界的に評価の高い論文を取得しようと考えました!

目標

こんな感じで、IEEE論文を要約したものをシェアしてくれるSlackbotを作ります。

手順

  1. IEEE Xplore API portal のアカウントを作る
  2. SlackBotのためのAPIトークンを生成
  3. OpenAIのAPIを取得
  4. Pythonコードを作成
  5. Google Cloud Platform(GCP)で実行を自動化
  6. 完成!

1. IEEE Xplore API portal のアカウントを作る

IEEEでは、論文のスクレイピングを可能にするAPIlキーを認証した人に与えています。

ここでは、そのAPIキーの取得方法について説明します。

まず、IEEE Xplore API portalのアカウントを作るためにサイトにアクセスします。

https://developer.ieee.org/

ページを開くと下のような画面が表示されるので、画面右上の「Register」をクリック

すると、必要項目を書くフォームが表示されるので、埋めていきます。

登録が完了したら、「My Account」からAPIキーを作成します。

私は「Application」には「IEEE paper to slack bot」とし、

「Metadata Search」用のキーを作成しました。

最初は「Status」の場所が「waiting」とかになっていると思いますが、しばらくするとこれが「activate」になるはずです。「activate」状態になったらいつでもIEEEのAPIを使用することができるようになります。

「activate」になったかどうかはメールでお知らせしてくれます。

自分の場合は休日に申請したため、「activate」になるまで1、2日ほどかかりました。

2. SlackBotのためのAPIトークンを生成とOpenAIのAPIを取得

次に、Slack APIのページからbotを作成する必要があります。

この方の記事で詳しいやり方が紹介されているので、参考にしながらアプリ作成、APIトークン生成、ワークスペースにアプリをインストール、メッセージ送信のテストまでやってみてください。
https://zenn.dev/kou_pg_0131/articles/slack-api-post-message

3. OpenAIのAPIを取得

取得した論文を要約するために、ChatGPTのAPIを使います。

ChatGPTのAPIを使用するためには、まずOpen AIのAPIキーを取得する必要があります。

以下のページからOpenAIのアカウント作成、APIキーの取得までを行いましょう。
https://platform.openai.com/account/api-keys

このような画面が出てきたら、+ Create new secret keyをクリックするとAPIキーを取得することができます。

コピーはキーを発行した時にしかできないので、コピーして、どこかに保存しておきましょう。

ただ、コピーし忘れてしまっても、もう一度ボタンを押すことで再発行することができます。

4. Pythonコードを作成

次にコードを作成していきます。

外部ライブラリにはopenai,slack-sdkの二つを使用します

Google Cloud Platform(GCP)のCloud Functionsでpyファイルを実行するので、main関数にはeventcontextの二つの引数を渡します。

main.py
import requests
import json
import os
from slack_sdk import WebClient
from slack_sdk.errors import SlackApiError
import openai
import random

#IEEEのapiキー
IEEE_API_KEY = 'IEEEのapiキー'

# IEEE APIのエンドポイント
base_url = 'http://ieeexploreapi.ieee.org/api/v1/search/articles'

#OpenAIのapiキー
openai.api_key = 'openAIのapiキー'
# Slack APIトークン
SLACK_API_TOKEN = 'SlackのAPIトークン'
# Slackに投稿するチャンネル名を指定する
SLACK_CHANNEL = "#general"

def get_summary(result):
    system = """与えられた論文の要点を3点のみでまとめ、以下のフォーマットで日本語で出力してください。```
    タイトルの日本語訳
    ・要点1
    ・要点2
    ・要点3
    ```"""

    text = f"title: {result['title']}\nbody: {result['abstract']}"
    response = openai.ChatCompletion.create(
                model="gpt-3.5-turbo",
                messages=[
                    {'role': 'system', 'content': system},
                    {'role': 'user', 'content': text}
                ],
                temperature=0.25,
            )
    summary = response['choices'][0]['message']['content']
    title_en = result['title']
    title, *body = summary.split('\n')
    body = '\n'.join(body)
    date_str = result['publication_date']
    message = f"発行日: {date_str}\n{result['pdf_url']}\n{title_en}\n{title}\n{body}\n"

    return message


def main(event, context):
    # Slack APIクライアントを初期化する
    client = WebClient(token=SLACK_API_TOKEN)
    #queryを用意
    query = 'deep learning'
    
    # クエリパラメータを指定してAPIを呼び出す
    params = {
        'apikey': IEEE_API_KEY,
        'format': 'json',
        'max_records': 3,
        'start_record': 1,
        'sort_order': 'asc',
        'sort_field': 'article_number',
        'abstract': query
    }

    response = requests.get(base_url, params=params)

    if response.status_code == 200:
        print("API call successful")
    else:
        print("API call unsuccessful with status code:", response.status_code)

    # APIからのレスポンスをJSON形式で取得
    result = json.loads(response.text)

    #ランダムにnum_papersの数だけ選ぶ
    num_papers = 3
    results = random.sample(result['articles'], k=num_papers)

    # 論文情報をSlackに投稿する
    for i,result in enumerate(results):
        try:
            # Slackに投稿するメッセージを組み立てる
            message = "今日の論文です! " + str(i+1) + "本目\n" + get_summary(result)
            # Slackにメッセージを投稿する
            response = client.chat_postMessage(
                channel=SLACK_CHANNEL,
                text=message
            )
            print(f"Message posted: {response['ts']}")
        except SlackApiError as e:
            print(f"Error posting message: {e}")

requirement.txtやローカルで試す用のpyファイルなどはこちらのリポジトリにありますのでこちらからクローンしてください。

https://github.com/zushi0516/ieee_paper2slack

4. Google Cloud Platform(GCP)で実行を自動化

最後に、作成したpyファイルをGoogle Functionsというツールを使って実行を自動化します。

設定の仕方はこちらの方の記事を参考にしてください。

https://gammasoft.jp/blog/schdule-running-python-script-by-serverless/

注意点として、ランタイムにはPython3.10を選択、main.pyrequirement.txtは私のgithubリポジトリからクローンしてきたものを使ってください。

論文の取得頻度はCloud Schedulerで調整してください。

例えば0 7 1 * *とすることで毎朝7時に論文を取得してくれるようになります。

5. 完成!

これで完成!前回から変わったのはIEEEのAPIを取得することと、コードをちょっと変えるだけでしたね

IEEEのAPIの細かい使い方についてはまた別記事で解説します!

この調子でどんどん研究室のDX化を推し進めていきたいですね〜

参考文献

前回に引き続き、偉大な先人達の知恵とChatGPT様のお陰で作成できました。ここに感謝の意を表します。

https://zenn.dev/kou_pg_0131/articles/slack-api-post-message

https://qiita.com/GleamingCake/items/e8c53fb0c1508ba1449e

https://qiita.com/KMD/items/bd59f2db778dd4bf6ed2

https://gammasoft.jp/blog/schdule-running-python-script-by-serverless/

Discussion

Eathan LickeyEathan Lickey

公開ありがとうございます。参考にしました。

「例えば0 7 1 * *とすることで毎朝7時に論文を取得してくれるようになります。」
ここの部分ですが、毎朝7時だと"0 7 * * * "ではないでしょうか?

加えて質問なのですが、取得する論文のソートの方法は現状"article_number"で行うのがベストでしょうか?
"publication_date"あたりでソートできれば新しいものを引っ張りやすいとは思ったのですが、
IEEE APIのユーザマニュアルを確認しても、良さそうなオプションが見当たりませんでした。
もし、ご存知でしたら教えていただけると助かります。