2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【docker】簡易的なチャットボットのReactアプリをdocker-composeで動かす

Last updated at Posted at 2023-07-17

概要

Chatbotを作成するためのAPIである「A3RT Talk API」とReactを利用した簡易的なチャットボットアプリを作成し、それをdocker-composeで動かします。

  • 動作確認
$ docker ps
CONTAINER ID   IMAGE                   COMMAND                  CREATED       STATUS       PORTS                                       NAMES
c3f1a4a5cced   chatbot-sample:latest   "docker-entrypoint.s…"   3 hours ago   Up 3 hours   0.0.0.0:3000->3000/tcp, :::3000->3000/tcp   docker-compose_app_1
$ 
  • サンプル画面
    image.png

事前準備

API KEYの発行

リクルートから提供されているチャットボットを作成するためのAPIである「A3RT Talk API」の「API KEY発行」に進みます。メールアドレス入力やプライバシーポリシーの同意後、確認メールが送信されます。確認後、「API KEY発行完了のお知らせ」のメールを受領します。

A3RT Talk API

ユーザー/ボットの画像

いらすとやから入手しました。

コード作成

src/App.js

App.js
import React, { useState, useEffect } from 'react';
import './App.css';

const Chatbot = () => {
  const [input, setInput] = useState('');
  const [messages, setMessages] = useState([]);

  useEffect(() => {
    setMessages([{ text: '何か文章を書いてね', sender: 'bot' }]);
  }, []);

  const handleInputChange = (event) => {
    setInput(event.target.value);
  }

  const handleSubmit = async (event) => {
    event.preventDefault();
    setMessages(messages => [...messages, { text: input, sender: 'user' }]);
    setInput('');
    try {
      const response = await fetch(process.env.REACT_APP_API_ENDPOINT, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded'
        },
        body: new URLSearchParams({
          apikey: process.env.REACT_APP_API_KEY,
          query: input
        })
      });
      const data = await response.json();
      if (data.status === 0) {
        setMessages(messages => [...messages, { text: data.results[0].reply, sender: 'bot' }]);
      } else {
        setMessages(messages => [...messages, { text: 'Error: Unable to generate response', sender: 'bot' }]);
      }
    } catch (error) {
      setMessages(messages => [...messages, { text: 'Error: Failed to fetch data from API', sender: 'bot' }]);
    }
  }

  return (
    <div className="chatbot">
      <ul className="messages">
        {messages.map((message, index) => (
          <li key={index} className={message.sender}>
            <img src={`/${message.sender}.png`} alt={message.sender} />
            <span>{message.text}</span>
          </li>
        ))}
      </ul>
      <form onSubmit={handleSubmit}>
        <input type="text" value={input} onChange={handleInputChange} />
        <button type="submit">Send</button>
      </form>
    </div>
  );
}

export default Chatbot;

App.css

App.css
body {
  background-color: lightblue;
}

.chatbot {
  display: flex;
  flex-direction: column;
  height: 100%;
}

.messages {
  flex-grow: 1;
  overflow-y: scroll;
}

.messages::-webkit-scrollbar {
  width: 12px;
}

.messages::-webkit-scrollbar-track {
  background-color: transparent;
}

.messages::-webkit-scrollbar-thumb {
  background-color: #00bfff;
  border-radius: 6px;
}

.messages li {
  display: flex;
  align-items: center;
}

.messages li img {
  width: 32px;
  height: 32px;
}

.messages li span {
  margin-left: 8px;
  border-radius: 16px;
  padding: 8px;
}

.messages li.user {
  justify-content: flex-end;
}

.messages li.user span {
  background-color: lightgreen;
}

.messages li.bot span {
  background-color: #00bfff;
}

form {
  display:flex;
}

form input[type="text"]{
   flex-grow :1;
   border-radius :16px;
   padding :8px;
   margin-right :8px;
   border :1px solid gray;
   outline :none;
   box-shadow :0px 0px 10px rgba(0,0,0,0.1);
   background-color :#f0fff0;
}
form button{
   background-color :#ff6961;
   border-radius :16px;
   padding :8px;
   border :none;
   outline :none;
   box-shadow :0px 0px 10px rgba(0,0,0,0.1);
}

.env

REACT_APP_API_ENDPOINT=<A3RT Talk APIのエンドポイント>
REACT_APP_API_KEY=<取得したAPI KEY>

その他

public/配下にユーザー画像のuser.png、ボット画像のbot.pngを配置します。

ローカル上での動作確認

yarn startを実行し、http://localhost:3000 にアクセスします。テキストボックスに適当な文章を入力後「send」をクリックすることでボットが返答することを確認します。

image.png

Dockerfile作成

軽量なLinuxあるalpine Linuxをベースとしたnode16のDockerImageを使用してDockerImageを作成します。

FROM node:16-alpine3.17
COPY . /app
WORKDIR /app
RUN npm install --production
EXPOSE 3000
CMD ["npm", "start"]

DockerImage作成

chatbot-sampleのDockerImageを作成します。

$ docker build -t chatbot-sample:latest .
$ docker image ls
REPOSITORY       TAG       IMAGE ID       CREATED       SIZE
chatbot-sample   latest    6c11b1dc726a   3 hours ago   514MB

docker-compose.yml作成

REACT_APP_API_KEY及びREACT_APP_API_ENDPOINTの環境変数の値は別途「.env」に記載します。

version: '3.3'
services:
  app:
    image: "chatbot-sample:latest"
    environment:
      - REACT_APP_API_KEY=${REACT_APP_API_KEY}
      - REACT_APP_API_ENDPOINT=${REACT_APP_API_ENDPOINT}
    ports:
      - 3000:3000

DockerImageを利用した動作確認

docker-compose upにてchatbot-sampleのコンテナが立ち上がったか、また http://localhost:3000 に接続してチャットボットが利用できるか確認します。

$ docker-compose up
$ docker ps
CONTAINER ID   IMAGE                   COMMAND                  CREATED       STATUS          PORTS
                  NAMES
c3f1a4a5cced   chatbot-sample:latest   "docker-entrypoint.s…"   3 hours ago   Up 11 minutes   0.0.0.0:3000->3000/tcp, :::3000->3000/tcp   docker-compose_app_1

image.png

最後に

「A3RT Talk API」を使用することで簡易的なチャットボットUI画面を作成することができます。またdocker-composeを利用することで、様々な環境の際による違い(nodeのバージョン差異など)が発生することなくチャットボットUI画面を利用することができます。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?