APC 技術ブログ

株式会社エーピーコミュニケーションズの技術ブログです。

株式会社 エーピーコミュニケーションズの技術ブログです。

普段コードを書かない管理職がChatGPTを使ってメール送信UIを作ってみる

はじめに

こんにちは、ACS事業部の東出です。
このブログはエーピーコミュニケーションズ Advent Calendar 202310日目の投稿です。

今回は普段コードを書かない管理職ChatGPTを使ってメール送信UIを作ってみました。

なぜかというと、私の部署では現在、Autify関連のブログを連載中で、12/11(月)の投稿担当が私になります。
そこでメールテスト機能に関する内容を投稿するからです。
で、12/10(日)がアドカレの日なので、11日の準備がてら、上記のテーマでやってみることにしました。

条件面の説明

私自身のコンディションについて

  • 今は部長職やってまして、コードはほぼ書かないです。スライド職人です。
  • 十数年、Delphiで書かれた業務アプリに携わっていましたが、PjM業務がメインでコードを書くことはあまりなかったです。
  • PL/SQLとバッチファイルばかり書いていました。

今回作るアプリの概要

  • Next.jsで作りました(うちのチームでNext.js使ってるのでちょっとは触っておこうと思いまして、、、)
  • メール送信機能はAzure Communication Servicesを使いました

結果

出来上がりのイメージ

こんな感じのUIができました。

ChatGPTくんには以下のようなオーダーを出しましたが、レスポンスの表示もやってくれるコードになっています。

- メールの宛先・件名・本文を入力するテキスト入力フィールドを設ける
- メール送信ボタンを設ける
- メール送信ボタンをクリックすると、以下の動作をする
    - Azure Communication ServicesのAPIを呼び出してメールを送信する
        - APIにわたす値として、テキスト入力フィールドの入力値を用いる
    - APIのレスポンス(メール送信結果)をUIに表示する

メールも送信できました。

所要時間

何だかんだで、3時間ぐらいかかりました(^_^;) (色々トラシューをしていると時間が溶けました)

やったこと(時系列)

アプリ開発環境の準備

※詳細はこちらのチャット内容を参照ください(こんな感じでChatGPTのログを共有できるの、便利ですね)。

  • Azure Communication ServicesとEメールリソースの準備(手順については、過去にブログ化していましたので、それを元に準備しました)
  • node/npmのバージョンアップ
  • create-next-app実行後に(ChatGPTくんは自動生成されると言う)pages ディレクトリがないので、再度create-next-appをやってみるが変わらず、自分でディレクトリを作った

アプリコードを書いて実際に動かしてみる

※サンプルコード出力の詳細についてはこちらのチャット内容をご参照ください。

  • UI・機能イメージをChatGPTに伝えてサンプルコードを出してもらう
  • Azure Communication ServicesのSDKの使い方を調べる(こちらの記事を参考にした)
  • APIアクセスのルーティングが何だかうまくいかないので、プロジェクト作り直し
  • プロジェクト作り直したらエラー内容が変わった(進展した)
    • なぜ進展したかは謎、、、
    • Azure Communication Services のSDK実行サンプルが、接続文字列をdotenvで環境変数として持たせる方式だったが、これがダメだったようで、ベタ書きしたらメール送信が成功した

最終的に動く状態になったサンプルコード

app/page.tsx

'use client'

import { useState, ChangeEvent, FormEvent } from 'react';

interface Email {
    to: string;
    subject: string;
    body: string;
}

export default function Home() {
    const [email, setEmail] = useState<Email>({ to: '', subject: '', body: '' });
    const [response, setResponse] = useState<string>('');

    const handleChange = (e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
        setEmail({ ...email, [e.target.name]: e.target.value });
    }

    const handleSubmit = async (e: FormEvent<HTMLFormElement>) => {
        e.preventDefault();
        const res = await fetch('/api/send-email', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify(email),
        });
        const result = await res.json();
        setResponse(result.message);
    }

    return (
        <div>
            <h2>Email Sender</h2>
            <form onSubmit={handleSubmit}>
                <label htmlFor="to">To:</label><br />
                <input type="email" id="to" name="to" value={email.to} onChange={handleChange} /><br />
                <label htmlFor="subject">Subject:</label><br />
                <input type="text" id="subject" name="subject" value={email.subject} onChange={handleChange} /><br />
                <label htmlFor="body">Body:</label><br />
                <textarea id="body" name="body" value={email.body} onChange={handleChange} /><br />
                <button type="submit">Send Email</button>
            </form>
            {response && <p>{response}</p>}
        </div>
    );
}

pages/api/send-email.ts

import type { NextApiRequest, NextApiResponse } from 'next';

interface Email {
    to: string;
    subject: string;
    body: string;
}

interface ApiResponse {
    message: string;
    error?: string;
}

const { EmailClient } = require("@azure/communication-email");
require("dotenv").config();

// This code demonstrates how to fetch your connection string
// from an environment variable.
const connectionString = "**********************";
const emailClient = new EmailClient(connectionString);

export default async function handler(req: NextApiRequest, res: NextApiResponse<ApiResponse>) {
    if (req.method === 'POST') {
        const { to, subject, body } = req.body as Email;
        
        try {
            const emailMessage = {
                senderAddress: "*******************",
                content: {
                    subject: subject,
                    plainText: body,
                },
                recipients: {
                    to: [{ address: to }],
                },
            };
        
            const poller = await emailClient.beginSend(emailMessage);
            const result = await poller.pollUntilDone();

            console.log(result);
    
            res.status(200).json({ message: 'Email sent successfully' });
        } catch (error: any) {
            res.status(500).json({ message: 'Error sending email', error: error.toString() });
        }
    } else {
        res.status(405).json({ message: 'Method not allowed' });
    }
}

まとめ

  • 機能要件については、ChatGPTくんはいい感じの答えを返してくれました
  • 結局、エラーは色々出るので1つずつ潰していくしかない
  • 一方、ChatGPTがエラーメッセージを解釈してくれるので、ググってエラーの意味を調べるよか楽でした
  • Next.js触ったことない人でも、一応メール送信できるところまでは作れました

ACS事業部のご紹介

私達ACS事業部はAzure・AKSなどのクラウドネイティブ技術を活用した内製化やGitHub Enterpriseの導入のご支援をしております。
www.ap-com.co.jp www.ap-com.co.jp また、一緒に働いていただける仲間も募集中です!
今年もまだまだ組織規模拡大中なので、ご興味持っていただけましたらぜひお声がけください。 www.ap-com.co.jp

本記事の投稿者: 東出恵次
内製化支援・モダナイゼーション等のコンサルティング・アプリケーション開発をおこなう部署の責任者をやっております。
スパイス&ハーブ検定2級。
ムッスメ(3歳)がプリキュアにハマりだしました。