Node.jsでChatGPTのAPIを呼び出すエンドポイントを作成する

# はじめに
ChatGPTのAPIを呼び出すためにはAPI Keyの情報が必要となりますが、JavaScriptに直打ちすると**誰でもAPI Keyを見られる**ようになってしまい、とても良くないです。
今回はChatGPTのAPIを呼び出すことができるエンドポイント（API）を、Node.jsを使って作っていきます。

API Keyの作成については、以下の記事を参照ください。

https://qiita.com/AS_atsushi/items/b3453544c9e9679a4b72

# 完成物
以下のように、bodyにtextを入れて送ることでChatGPTからの返答を得られるエンドポイントを作成します。

```javascript
const response = await fetch('http://localhost:3000/message', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json'
    },
    body: JSON.stringify({ text: text })
});
```

# コード

まずはNode.jsでプロジェクトを作成します。
```zsh
npm init -y
npm install express openai dotenv body-parser cors
```

`package.json`が作成されたら、このように`index.js`を作成します。

![スクリーンショット 2024-12-12 22.08.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2823873/3eda2880-9713-ca28-7590-994473db4c08.png)

```javascript:script.js
require('dotenv').config();
const http = require('http');
const express = require('express');
const OpenAIApi = require('openai');
const bodyParser = require('body-parser');
const cors = require('cors');
const path = require('path');

const app = express();

const corsOptions = {
    origin: '*',
    methods: ['GET', 'POST'],
    allowedHeaders: ['Content-Type', 'Authorization'],
    credentials: true
};
app.use(cors(corsOptions));

app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());

app.use(express.static(path.join(__dirname)));

const client = new OpenAIApi({
    apiKey: process.env['OPENAI_API_KEY']
});

app.post("/message", async (req, res) => {
    const { text } = req.body;
    const prompt = `${text}`; //もしプロンプトに定形文を追加したければここに記述

    try {
        const response = await client.chat.completions.create({
            model: "gpt-3.5-turbo",
            messages: [{ role: "user", content: prompt }]
        });

        const gptResponse = response.choices[0].message.content;

        res.json({ result: gptResponse });
    } catch (error) {
        console.error("Error with ChatGPT API:", error.message);
        res.status(500).json({ error: "エラーが発生しました。再度お試しください。" });
    }
});

const server = http.createServer(app);
server.listen(3000, () => {
    console.log("Server is running on http://localhost:3000");
});
```

次に、同じ位置に`.env`ファイルを作成します。

![スクリーンショット 2024-12-12 22.12.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2823873/ccdcaa51-1d84-36a7-2b33-96e81e73285c.png)

ここに次のようにChatGPTのAPI Keyを記述します。

```:.env
OPENAI_API_KEY=API Keyをここに記述
```

ここまでできたらサイトを起動します。

```zsh
node server.js
```

これで、サーバーの起動中に他のサイトから`localhost:3000/message`を呼び出すことができるようになります。

# コードの解説

ここでCORSの設定をしています。簡単にいえばどのサイトから呼び出せるか、の設定です。
現在はどのサイトからでも呼び出せる`'*'`と設定していますが、必要に応じて設定を変更してください。

```javascript
const corsOptions = {
    origin: '*',
    methods: ['GET', 'POST'],
    allowedHeaders: ['Content-Type', 'Authorization'],
    credentials: true
};
app.use(cors(corsOptions));
```

openaiのクライアントを作成します。ここで、`.env`ファイルに書き込んだAPI Keyを参照しています。

```javascript
const client = new OpenAIApi({
    apiKey: process.env['OPENAI_API_KEY']
});
```

ChatGPTにリクエストを送信します。
`model`を設定することで

```javascript
const response = await client.chat.completions.create({
    model: "gpt-3.5-turbo",
    messages: [{ role: "user", content: prompt }]
});
```

ここでレスポンスからメッセージのみを抜き出し、JSONで返しています。

```javascript
const gptResponse = response.choices[0].message.content;

res.json({ result: gptResponse });
```

:::note
ChatGPTからのレスポンスは`response.data`としなくても取得できるようになりました。
:::

# まとめ

このようにエンドポイントを作成することでHTML/CSSだけのサイトからでもChatGPTを呼び出せます！みんなも使ってみてくださいね！