開発情報・ナレッジ

投稿者: ShiningStar株式会社 2025年2月7日 (金)

カスタムAPIでAIチャットウィンドウを作ってみた

本記事では、ver.2.35でリリースされたカスタムAPIを活用して、OpenAIのチャットAPIを呼び出すチャットボットウィンドウを出力するJavaScriptの構築手法をご紹介します。
この仕組みでは、バックエンド側はPHPでカスタムAPIを実装し、
フロントエンド側はJavaScriptを用いてユーザとの会話を実現しています。

システムは、ユーザから送信される会話履歴を保持し、
その履歴をもとにOpenAI APIへリクエストすることで、文脈を踏まえた回答を返します。

注意点

・カスタムAPI実装時は、PHPの実行制限や利用可能な関数に注意してください。
・OpenAI APIのレスポンスは、JSON形式で返却されるため、レスポンス構造に合わせたパース処理が必要です。
・APIキーなどの機密情報は、安全に管理し外部に漏れないよう注意しましょう。

DB設定

チャットボットの会話履歴を永続化する場合、専用のデータベースを用意すると便利です。
例えば、会話ID、ユーザメッセージ、AIの返答、タイムスタンプなどのフィールドを持つデータベースを作成することで、 過去の会話を参照したり、後から分析することが可能になります。
必要に応じて、チャット内容の保存と読み出しの処理をバックエンドに実装してください。

カスタムAPI設定

サイト設定のサイドバーにカスタムAPIが追加されていますので、
こちらを選択して上部「+」マークを押下し、新規カスタムAPIを作成してください。
今回は特に認証を設けないので認証設定は不要です。
任意の表示名と識別名を入力後下記PHPソースを貼り付けて保存してください。

カスタムAPIコード例

【PHP】
<?php
// リクエスト本文(JSON)を連想配列として取得
$requestBody = $SPIRAL->getCustomApiRequestBody();

// 会話履歴は「messages」というキーで送信する前提
if ( !isset($requestBody['messages']) || !is_array($requestBody['messages']) ) {
    $SPIRAL->setCustomApiResponse([
        'status' => 'failed',
        'errorMessage' => 'messagesパラメータが存在しないか形式が不正です'
    ]);
    return;
}
$messages = $requestBody['messages'];

// OpenAI の API キー(※実際の運用時は環境変数やセキュアな方法で管理してください)
$openai_api_key = 'YOUR_OPENAI_API_KEY';

// OpenAI のチャットAPIエンドポイント
$api_url = 'https://api.openai.com/v1/chat/completions';

// リクエストパラメータ(モデル名や温度などはお好みで調整)
$postData = [
    'model'    => 'gpt-4o',
    'messages' => $messages,
    'temperature' => 0.7
];

// cURL を使って OpenAI API にリクエスト
$ch = curl_init($api_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Content-Type: application/json',
    'Authorization: Bearer ' . $openai_api_key,
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($postData));

$response = curl_exec($ch);
if (curl_errno($ch)) {
    $error_msg = curl_error($ch);
    $SPIRAL->setCustomApiResponse([
        'status' => 'failed',
        'errorMessage' => $error_msg
    ]);
    curl_close($ch);
}
curl_close($ch);

// API のレスポンスを連想配列に変換
$responseData = json_decode($response, true);

// チャットAPIの仕様により、返答は choices 配列内の message に入っています
if (isset($responseData['choices'][0]['message']['content'])) {
    $assistantMessage = $responseData['choices'][0]['message']['content'];
    $SPIRAL->setCustomApiResponse([
        'status'    => 'success',
        'assistant' => $assistantMessage
    ]);
} else {
    // エラー時はレスポンス内容をエラーメッセージとして返す
    $SPIRAL->setCustomApiResponse([
        'status' => 'failed',
        'errorMessage' => 'OpenAI APIから正しい応答が得られませんでした'
    ]);
}
?>
                

チャットウィンドウ設定方法

チャットボットシステムの主要なコード例です。
バックエンドのPHPコードでは、ユーザから送信された会話履歴を元にOpenAI APIにリクエストし、
その返答をJSON形式で返却します。フロントエンドでは、JavaScriptで会話履歴の管理とUIの更新を行います。

【フロント:Javascript】
// 会話履歴を保持する配列(OpenAI API用の形式)
  // 例: { role: "user" | "assistant", content: "メッセージ内容" }
  const conversation = [];

  // カスタムAPIのエンドポイントURL(環境に合わせて変更してください)
  const API_URL = 'https://{アカウント識別名}-{サイト識別名}.spiral-site.com/_program/{custom_api_name}';

  // チャット履歴にメッセージを追加する関数
  function addMessage(role, text) {
    const chatHistory = document.getElementById('chat-history');
    const messageDiv = document.createElement('div');
    messageDiv.className = 'message ' + role;
    messageDiv.textContent = text;
    chatHistory.appendChild(messageDiv);
    // 最新メッセージが見えるようにスクロール
    chatHistory.scrollTop = chatHistory.scrollHeight;
  }

  // 送信ボタン押下時または Enter キー押下時の処理
  function sendMessage() {
    const inputField = document.getElementById('chat-input');
    const userMessage = inputField.value.trim();
    if (!userMessage) return;
    // ユーザメッセージを履歴に追加
    conversation.push({ role: 'user', content: userMessage });
    addMessage('user', userMessage);
    inputField.value = '';

    // カスタムAPIへ POST リクエストを送信
    fetch(API_URL, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
        // ※必要に応じて認証ヘッダーなどを追加
      },
      body: JSON.stringify({ messages: conversation })
    })
    .then(response => response.json())
    .then(data => {
      if (data.status === 'success') {
        const assistantMessage = data.data.assistant;
        // 会話履歴に Assistant の返答を追加
        conversation.push({ role: 'assistant', content: assistantMessage });
        addMessage('assistant', assistantMessage);
      } else {
        // エラー表示
        addMessage('system', 'エラー: ' + data.errorMessage);
      }
    })
    .catch(error => {
      addMessage('system', '通信エラー: ' + error);
    });
  }

document.addEventListener('DOMContentLoaded', function() {
  // 送信ボタンのクリックイベント登録
  document.getElementById('send-btn').addEventListener('click', sendMessage);

  // Enter キーでも送信できるように設定
  document.getElementById('chat-input').addEventListener('keydown', function(e) {
    if (e.key === 'Enter') {
      sendMessage();
    }
  });
});
                
【フロント:HTML】
<div id="chat-container">
  <div id="chat-history">
    <div id="chat-header">サポートデスク</div>
    <!-- ここにチャットメッセージが追加されます -->
  </div>
  <div id="chat-input-container">
    <input type="text" id="chat-input" placeholder="メッセージを入力…" />
    <button id="send-btn">送信</button>
  </div>
</div>
                
【フロント:CSS】
/* チャットウィンドウ全体 */
#chat-container {
  position: fixed;
  bottom: 20px;
  right: 20px;
  width: 320px;
  max-height: 500px;
  box-shadow: 0 0 10px rgba(0,0,0,0.3);
  border-radius: 8px;
  overflow: hidden;
  font-family: Arial, sans-serif;
  display: flex;
  flex-direction: column;
  background-color: #f9f9f9;
}

/* チャット履歴部分(初期高さを設定) */
#chat-history {
  padding: 10px;
  overflow-y: auto;
  background-color: #fff;
  height: 350px;  /* 初期高さを指定 */
  border-bottom: 1px solid #ddd;
}

/* 見出し用スタイル */
#chat-header {
  font-weight: bold;
  margin-bottom: 10px;
  text-align: center;
  border-bottom: 1px solid #ccc;
  padding-bottom: 5px;
}

/* 入力エリア */
#chat-input-container {
  border-top: 1px solid #ddd;
  display: flex;
}
#chat-input {
  flex: 1;
  padding: 10px;
  border: none;
  outline: none;
}
#send-btn {
  padding: 10px 15px;
  border: none;
  background-color: #007bff;
  color: #fff;
  cursor: pointer;
}

/* メッセージバブル */
.message {
  margin-bottom: 10px;
  padding: 8px 12px;
  border-radius: 15px;
  max-width: 80%;
  clear: both;
}
.message.user {
  background-color: #dcf8c6;
  float: right;
}
.message.assistant {
  background-color: #ececec;
  float: left;
}
.message.system {
  background-color: #ffe6e6;
  text-align: center;
  margin: 0 auto;
}
                

最後に

ページに上記のHTML、CSS、JavaScriptを組み込むことで、チャットボットウィンドウを実装できます。
こちらのサンプルではopenAIのAPIのレスポンスをそのまま表示していますが、
応答内容を加工したり、会話の流れを制御するためのロジックを追加することで、
より高度なチャットボットを構築することが可能です。
また、会話履歴の永続化や、ユーザの状況に応じた返答の変更など、
より高度な機能を実装する場合は、カスタムAPIの拡張や、フロントエンドの改修が必要になります。

不具合やほかのやり方が知りたい等あれば、下記の「コンテンツに関しての要望はこちら」からご連絡ください。

解決しない場合はこちら コンテンツに関しての
要望はこちら