フルスタックチャンネル
サインアップサインアップ
ログインログイン
利用規約プライバシーポリシーお問い合わせ
Copyright © All rights reserved | FullStackChannel
解決済
【質問】Next.js13とSupabaseでAIチャットアプリ構築(GPT-3)
Next.js
API
データベース
いいね
2023/06/23 03:33

実現したいこと

何故かPOSTテーブルのCONTENTにデータが反映されてない?
<br>
原因・修正箇所など教えていただけますでしょうか。

発生している問題

動画の通り、20分37秒までpost-new.tsxを完成し
<br>
npx run devコマンド実行して、ブラウザを立ち上げて
<br>
CHATGPTとは入力し、Enterすると、エラー発生しまう。

エラー

SyntaxError: Unexpected token 'S', "Something went wrong" is not valid JSON

ソースコード

####pages/api/openai.ts

import { Configuration, OpenAIApi } from 'openai'

import type { NextApiRequest, NextApiResponse } from 'next'

const configuration = new Configuration({
    apiKey: process.env.OPENAI_API_KEY,
})

const openai = new OpenAIApi(configuration)

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
    try {
        const { prompt } = req.body

        const response = await openai.createCompletion({
            model: 'Text-davinci-003',
            prompt: `The following is a conversation with an AI assistant. The assistant is helpful, creative, clever.\nHuman: ${ prompt }\nAI:`,
            max_tokens: 1024,
            temperature: 0.6,
            frequency_penalty: 0.5,
            presence_penalty: 0,
        })

        const text = response.data.choices[0].text

        res.status(200).json({ text })

    } catch (error) {
        console.error(error)
        res.status(500).send('Something went wrong');
    }
    
}

####app/components/post/post-new.tsx

'use client'

import { KeyboardEvent, useState } from 'react'
import { useRouter } from 'next/navigation'
import { useSupabase } from '../supabase-provider'


const PostNew = () => {
    const { supabase } = useSupabase()
    const router = useRouter()
    const [loading, setLoading] = useState(false)
    const [prompt, setPrompt] = useState('')

    const onSubmit = async () => {
        if (prompt) {
            try {
                // Postテーブル追加
                const { data: insertData, error: insertError } = await supabase
                    .from('posts')
                    .insert({
                        prompt,
                    })
                    .select()

                if (insertError) {
                    alert(insertError.message)
                    return
                }

                //入力フォームクリア
                setPrompt('')

                // キャッシュクリア
                router.refresh()

                // GPTローディング開始
                setLoading(true)

                // テキストプロンプトをAPIに送信
                const body = JSON.stringify({ prompt })
                const response = await fetch('/api/openai', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    body,
                })

                const response_data = await response.json()
                
                // Postテーブル更新
                const { error: updateError } = await supabase
                    .from('posts')
                    .update({
                        content: response_data.text,
                    })
                    .eq('id', insertData[0].id)
                
                if (updateError) {
                    alert(updateError.message)
                    setLoading(false)
                    return
                }

                
                // キャッシュクリア
                router.refresh()
            } catch (error) {
                alert(error)
            }
        }
        setLoading(false)
    }
      
    // 入力フォームでEnterが押しされたら送信, shift+ enterは改行
    const enterPress = (e: KeyboardEvent<HTMLTextAreaElement>) => {
        if (e.key == 'Enter' && e.shiftKey == false) {
          e.preventDefault()
          onSubmit()
        }
    }

    return (
        <div className="fixed bottom-0 left-2 right-2 h-40 flex flex-col justify-end items-center bg-[#7494c0] pb-5">
            {loading && (
                <div className="flex items-center justify-center space-x-3 my-2">
                    <div className="h-5 w-5 animate-spin rounded-full border-2 border-yellow-500 border-t-transition"></div>
                    <div className="text-white font-bold">GTP is thinking</div>
                </div>
            )}

            <textarea
                className="w-[752px] bg-gray-50 rounded py-3 px-3 outline-none focus:bg-white"
                id="prompt"
                name="prompt"
                placeholder='How ara you?'
                onChange={(e) => setPrompt(e.target.value)}
                onKeyDown={(e) => enterPress(e)}
                value={prompt}
                rows={2}
                required
            />

            <div className="text-white text-sm mt-2">Shift+Enter: 改行, Enter: 送信</div>
        </div>
    )
}

export default PostNew

自分で試したこと

■修正前

    const enterPress = (e: KeyboardEvent<HTMLTextAreaElement>) => {
        if (e.key == 'Enter' && e.shiftKey == false) {
          e.preventDefault()
          onSubmit()
        }
    }

■修正前

    const enterPress = (e: KeyboardEvent<HTMLTextAreaElement>) => {
        if (e.key === 'Enter' && !e.shiftKey) {
          e.preventDefault();
          onSubmit();
        }
      };

入力フォームでEnterが押しされたら送信、エラーがあったと思っています。
上記コードを試してみて、直せないので、修正前のコードに戻りました。

回答 6件
login
回答するにはログインが必要です
はる@講師
2年以上前

APIが動いていないですね。

APIキーなどコードの見直しをお願いします。

1
いいね
2年以上前

やはり、openai.tsの問題があった。解決しました.
なんですかね。' ⇒ " ?

const response = await openai.createCompletion({
            model: 'Text-davinci-003',

   ↓

  model: "Text-avinci-003",
2
はる@講師
2年以上前

promptを少し長くして入力するとどうなるでしょうか?

あまり短すぎるとpromptだと、APIエラーが発生する現象は確認しています。

1
いいね
2年以上前

https://gyazo.com/ed163020159bd1ba5bfd37f2d3959234
<br>
https://gyazo.com/25a6f9be00326a787213c9ab3dd3cf9f

いいね
2年以上前

メッセージ  Postテーブル

いいね
2年以上前

ありがとうございます。</br>先ほど、長い文章を入力してみました。エラー発生しまう。</br>
supabaseのpostテーブルにID、prompt ,
craeted_at、updated_at データが反映されておりますが、</br>CONTENTのみ、NULLになっています。