ChatGPTのAPIでメールを作成してSendGridで送信する方法

ChatGPTのAPIでメールを作成してSendGridで送信する方法

こんにちは、Twilio SendGridサポートエンジニアの吉田(@kkenyoshi)です。ChatGPTが2022年11月末にリリースされて以降、LLM(Large Language Model; 大規模言語モデル)の活用が急速に進んでいますね。単にChatGPTというアプリ自体の流行りに留まらず、GPTを他のアプリケーションに組み込んで、ChatGPTだけではできないタスクも自然言語で解決する試みが広まっているようです。GPTシリーズを開発しているOpenAI社も頻繁にAPIをアップデートしており、その流れを加速させています。

直近では2023年6月13日に「Function calling」という機能がAPIに追加されました。これは関数の定義をGPTにあらかじめ与えておけば、それを用いるべき質問が来た時に、その関数に与えるべき引数を返答するものです(関数を実行するわけではありません)。OpenAIのドキュメントでは、例として天気予報やメール送信が挙げられています。メール送信を例にとると、「〇〇さんに××というメールを送信してくれ」と頼めば、メール送信に必要なパラメータ(To、Subject、本文など)を返答してくれます。GPT自体がメール送信や天気予報を行えるわけではないので、GPTから返されたパラメータを使ってアプリケーション側で関数を実行することになります。

今回は、GPTの返答を元にメールを送信する簡単なアプリケーションを、SendGridのメール送信APIを用いて作っていきます。

アプリケーションの作成

実装にはPythonを利用します。Webアプリケーションを簡単に構築できるライブラリStreamlitを用い、「メールの概要を記述するだけでGPTにメール文面を作成してもらい、それをSendGridで送信するアプリケーション」を作成します。完成形は以下のようになります。

メールの概要を記述するだけでGPTにメール文面を作成してもらい、それをSendGridで送信するアプリケーション

準備

まず、利用するライブラリをインストールします。Streamlitのほかに、GPTのAPIを使うためにopenaiライブラリ、SendGridを用いてメール送信するためにsendgridライブラリが必要です。パッケージ管理ツールにpipを利用している場合は以下のようになります。

pip install openai streamlit sendgrid

今回私が使用したバージョンは以下の通りです。

  • Python 3.10.8
  • openai 0.27.8
  • streamlit 1.23.1
  • sendgrid 6.10.0

また、OpenAIとSendGridのAPIキーを環境変数に登録しておきます。

OPENAI_API_KEY=sk-XXXXXXXXXX
SENDGRID_API_KEY=SG.XXXXXXXXXX

実装

1つのPythonスクリプトの中にコードを書いていきます。ここでは名前をapp.pyとします。
最初は必要なパッケージのインポートです。

import os
import json
import openai
import streamlit as st
from sendgrid import SendGridAPIClient
from sendgrid.helpers.mail import Mail

次にGPTのAPIを呼び出す関数を定義します。

functions = [
    {
        "name": "generate_email",
        "description": "Generate an email from a given context",
        "parameters": {
            "type": "object",
            "properties": {
                "to": {
                    "type": "string",
                },
                "subject": {
                    "type": "string"
                },
                "body": {
                    "type": "string"
                }
            },
            "required": ["to", "subject", "body"]
        },
    }
]

def generate_email(content):
    response = openai.ChatCompletion.create(
        model="gpt-3.5-turbo-0613",
        messages=[
            {"role": "user", "content": content}
        ],
        functions=functions,
        function_call={"name": "generate_email"}
    )
    return json.loads(response["choices"][0]["message"]["function_call"]["arguments"])

初めのfunctions配列はGPTのAPIに指定する関数を定義しています。GPTの返答として、メール送信に必要なパラメータであるto(宛先)、subject(件名)、body(本文)を返却するように指定します。本来は各パラメータの意味をそれぞれdescriptionで定義するべきなのですが、今回は名前から意味が明白だったためか、descriptionがなくても動作しました。

generate_email関数はユーザの入力を元にGPTの返答を得る処理をします。内部では、openaiライブラリのChat Completion APIを使っています。functions引数を指定することで、指定された関数を用いるべき質問が入力された時、定義された形式で返答してくれます。またfunction_call引数で関数名を明示的に指定することで、その関数の使用を強制することができます。今回、関数の戻り値はto、subject、bodyからなるdictionaryとしました。

続いてメール送信を行う関数を定義します。

def send_email(to, subject, body):
    sg = SendGridAPIClient(api_key=os.environ.get("SENDGRID_API_KEY"))
    mail = Mail(from_email="test@example.com", to_emails=to, subject=subject, plain_text_content=body)
    response = sg.send(mail)
    return response

send_mail関数では、指定されたto、subject、bodyのメールをSendGridで送信する処理を定義しています。ここでは送信元Fromアドレスをtest@example.comとしています。このように、SendGridでは実質3行のコードでメール送信が可能です。

これで各APIを呼び出す関数が定義できたので、ここからはStreamlitを組み合わせてアプリケーションを構築していきます。

st.title("Mail Generator")
st.write("自然言語でメールを生成して送信するアプリです")

with st.form("generate_email"):
    text = st.text_area("メールの概要を記述してください")
    submitted = st.form_submit_button("生成")
if submitted:
    try:
        with st.spinner("生成中..."):
            response_json = generate_email(text)
        for key, value in response_json.items():
            st.session_state[key] = value
    except Exception as e:
        st.error(f"エラーが発生しました: {e}")

この部分ではユーザがフォームに入力した内容をgenerate_email関数に渡して、メール送信に必要なパラメータのdictionaryを受け取り、セッションに保持しています。

最後にメールの送信部分です。

if "body" in st.session_state:
    with st.form("send_email"):
        st.write("以下の内容でメールを送信します")
        to_text = st.text_input("To", key="to")
        subject_text = st.text_input("Subject", key="subject")
        body_text = st.text_area("Content", key="body", height=320)
        sent = st.form_submit_button("送信")
    if sent:
        try:
            with st.spinner("送信中..."):
                res = send_email(to_text, subject_text, body_text)
            st.success("送信しました")
        except Exception as e:
            st.error(f"エラーが発生しました: {e}")

セッションに値が入っているかどうかをifで判断し、GPTから受け取ったto、subject、bodyの値をフォームとして表示しています。これによりユーザが再編集できるようにします。「送信」ボタンが押されたら、その内容をsend_mail関数に渡してSendGridでメール送信します。

実行

スクリプトはこれで完成です。早速実行してみましょう。ターミナルで「streamlit run app.py」を走らせると、Webブラウザでアプリケーションが立ち上がります。上の動画のようにメールの概要を入力するとGPTが文面を作成してくれ、適宜修正した上でメール送信できます。
動画では宛先メールアドレスを指定していませんが、GPTはyoshida@example.comと出力していました。GPTにメール生成(generate_email関数の使用)を強制しているので、適切な指示がないと勝手に補完するようです。きちんとメールアドレスを指示すればToにその宛先が入ります。存在するアドレスに送れば、SendGridからメールが届くことが確かめられます。

上記はローカル上での実行方法ですが、StreamlitはGitHubリポジトリを連携させてアプリケーションをデプロイできるCommunity Cloudというサービスも提供しており、外部公開も簡単にできます。

おわりに

100行に満たないコードで、GPTのAPIとSendGridのAPIを組み合わせたアプリケーションを構築できました。ただし、本記事で紹介したGPTのAPI呼び出し処理やエラーハンドリングなどは最小限の実装なので、詳細は各種ドキュメントをご確認ください。

ChatGPTの登場により様々な場面で業務生産性が上がっています。外部APIとの連携はそれをさらに加速させることでしょう。特にメールの作成と送信は、ChatGPTの高い文章生成能力と組み合わせて大きく効率を上げることができます。メール送信APIが必要になったらぜひSendGridをお試しください!

アーカイブ

メールを成功の原動力に

開発者にもマーケターにも信頼されているメールサービスを利用して、
時間の節約、スケーラビリティ、メール配信に関する専門知識を手に入れましょう。