メールをチェックして返信が必要なメールを教えてくれる秘書がいたら便利ですよね。
そこで、ChatGPT APIを用いて、メールの返信が必要か判定してSlackに通知するツールを作成してみました。
※ より判定の精度が上がるプロンプトを作成出来たら、コメントで教えて頂けますととても嬉しいです!
今回のツールは常に稼働中にした方が良いので、AWSのインスタンスにのせます。
この記事で使用するインスタンスのインスタンスイメージはubuntuです。
手順は以下です。
- Gmailのアプリパスワードを取得する
- Slack APIのダッシュボードで botを作成して、スコープを設定してBot User OAuth Tokenを取得する
- インスタンスでメール返信判定ツールを実行中にする
1. Gmailのアプリパスワードを取得する
はじめに、この返信判定ツールでは、ツールがメールを既読にしてしまうので、判定するメールを転送するメールを設定して、転送先のメールアドレスでこちらの設定をすることをおすすめします。
まず、返信を判定するメールのGoogleアカウントの設定のセキュリティを開いて、2段階認証を設定します。
2段階認証を設定したら、設定ページの検索欄で、アプリパスワードと検索して、アプリパスワードの設定ページにいきます。
アプリパスワードの設定ページで、アプリを作成します。
その他を押して、好きな名前を入れて、作成を押します。すると、16桁のアプリパスワードが発行されるので、こちらをメモします。
これで、⒈Gmailのアプリパスワードを取得するは完了です。
2. Slack APIのダッシュボードで botを作成して、スコープを設定してBot User OAuth Tokenを取得する
まず、 botのアプリを作成します。
メール返信判定ツールの通知を受け取りたいチャンネルのあるワークスペースにログインしてから、Slack APIのダッシュボードにアクセスして、ページの上の方にある緑の「Create New App」のボタンを押します。
開いたメニューで、from scratchの方を選択します。アプリ名は好きな名前、ワークスペースは通知を受け取るチャンネルのあるワークスペースにして、Create Appを押します。
アプリが出来たら、左のメニューからOAuth & Permissionsを押します。
OAuth & Permissionsのページが開いたら、Bot Token Scopesのところまで下にスクロールして、以下のスコープを設定します。
必要なスコープ
chat:write
スコープを設定したら、上にスクロールして、OAuth Tokens for Your Workspaceからアプリをワークスペースにインストールします。
アプリをインストールしたら、OAuth Tokens for Your Workspaceの欄にBot User OAuth Tokenが生成されるので、こちらをコピーしてメモします。
ついでに、作成したbotをbotから通知を送るチャンネルに追加しておきます。
これで、2. Slack APIのダッシュボードで botを作成して、スコープを設定してBot User OAuth Tokenを取得する、は完了です!
3. インスタンスでメール返信判定ツールを実行中にする
まず、インスタンスにSSH接続します。
インスタンスのコンソールが開いたら以下をインストールします。
aptのアップデート
sudo apt update
pipのインストール
sudo apt install python3-pip
slack sdkのインストール
sudo pip install slack-sdk
openaiのインストール
sudo pip install openai
次にpythonのファイルを保存するディレクトリを作成します。
mkdir ディレクトリ名
作成したディレクトリに移動します。
cd ディレクトリ名
作成したディレクトリでファイルを作成します。
nano ファイル名
作成したファイルの中に下記のbotのコードを入れて、ctrl oでファイルを保存して、ctrl xでファイルを閉じます。
コードには、以下を入れてください。
EMAIL_ADDRESSは、⒈で設定したメールアドレス
EMAIL_PASSWORD は、⒈で取得したアプリパスワード
SLACK_BOT_TOKEN は、⒉で取得したトークン
SLACK_CHANNEL_ID は、ツールが通知を送るチャンネル。テストというチャンネルであれば、#テスト。botを指定したチャンネルに入れておく。
openai.api_key は、openaiのキー
import imaplib
import email
from email.header import decode_header
import base64
import openai
import os
import time
from slack_sdk import WebClient
from slack_sdk.errors import SlackApiError
# Email settings
EMAIL_ADDRESS = "YOUR_EMAIL_ADDRESS"
EMAIL_PASSWORD = "YOUR_EMAIL_PASSWORD"
# Slack settings
SLACK_BOT_TOKEN = "YOUR_SLACK_BOT_TOKEN"
SLACK_CHANNEL_ID = "YOUR_SLACK_CHANNEL_ID"
# OpenAI API Key
openai.api_key = "your_openai_api_key"
def process_email(email_body):
truncated_email_body = email_body[:1000]
response = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=[
{"role": "system", "content": "下記のメールを返信が「必要」か「不要」か一言で答える。必要な場合「必要」、不要の場合「不要」と答える。"},
{"role": "user", "content": truncated_email_body},
]
)
t = response["choices"][0]["message"]["content"]
print(t)
return response["choices"][0]["message"]["content"]
def send_slack_message(title, body):
client = WebClient(token=SLACK_BOT_TOKEN)
try:
response = client.chat_postMessage(
channel=SLACK_CHANNEL_ID,
text=f"タイトル: {title}\n本文: {body}\n返信が必要なメールです。"
)
except SlackApiError as e:
print(f"Error sending message: {e}")
def check_new_emails():
# Connect to IMAP server
mail = imaplib.IMAP4_SSL("imap.gmail.com")
mail.login(EMAIL_ADDRESS, EMAIL_PASSWORD)
mail.select("inbox")
_, search_data = mail.search(None, "UNSEEN")
for num in search_data[0].split():
_, msg_data = mail.fetch(num, "(RFC822)")
for response_part in msg_data:
if isinstance(response_part, tuple):
msg = email.message_from_bytes(response_part[1])
subject, encoding = decode_header(msg["Subject"])[0]
if isinstance(subject, bytes):
subject = subject.decode(encoding)
if msg.is_multipart():
for part in msg.walk():
content_type = part.get_content_type()
content_disposition = str(part.get("Content-Disposition"))
try:
body = part.get_payload(decode=True).decode()
except:
pass
if content_type == "text/plain" and "attachment" not in content_disposition:
email_body = body
break
else:
email_body = msg.get_payload(decode=True).decode()
email_decision = process_email(email_body)
if "必要" in email_decision:
send_slack_message(subject, email_body)
# Logout and close the connection to the IMAP server
mail.logout()
if __name__ == "__main__":
while True:
try:
check_new_emails()
print("Checked for new emails.")
except Exception as e:
print(f"Error while checking emails: {e}")
time.sleep(600) # Check for new emails every 10 minutes (600 seconds)
一度、上手くファイルが作成されているか下記のコマンドで確認します。
find ~
上手くファイルが作成されていたら、screenを作成します。
screen -S スクリーン名
screen内でpythonで作成したファイルを実行します。
python3 ファイル名.py
ここまで出来たら10分おきにメールがチェックされますので、「返信して」などの返信が必要となるメールを先程設定したメールアドレスに送ってみて下さい。
メールがチェックされ以下のようにSlackに通知があれば、成功です!
最後に
これで誰にでも秘書を使えるようになりますね。
未だに私はGPT4がウェイティングなので、ドジっ子秘書を雇ってしまった感じになっていますが、これはこれでいいです。
また何か作ってみます。