GoTrip) AI 여행지 추천

김민수·2024년 7월 24일

GoTrip 프로젝트

목록 보기
2/4

API route

//route.ts
import { NextResponse } from 'next/server';
import OpenAI from 'openai';

export const maxDuration = 60;
export const dynamic = 'force-dynamic';

const openai = new OpenAI({
  apiKey: process.env.OPENAI_API,
});

const content = process.env.OPENAI_MAIN_API;
function isError(error: unknown): error is Error {
  return error instanceof Error;
}

export async function POST(request: Request) {
  const { prompt } = await request.json();

  try {
    const response = await openai.chat.completions.create({
      model: 'gpt-4o',
      messages: [
        {
          role: 'system',
          content: content || '',
        },
        { role: 'user', content: prompt },
      ],
      temperature: 1,
      max_tokens: 1000,
    });

    if (
      response.choices &&
      response.choices[0] &&
      response.choices[0].message &&
      response.choices[0].message.content
    ) {
      return NextResponse.json({
        result: response.choices[0].message.content.trim(),
      });
    } else {
      return NextResponse.json(
        { error: 'Invalid response from OpenAI API' },
        { status: 500 },
      );
    }
  } catch (error) {
    if (isError(error)) {
      return NextResponse.json({ error: error.message }, { status: 500 });
    } else {
      return NextResponse.json(
        { error: 'An unknown error occurred' },
        { status: 500 },
      );
    }
  }
}

API 호출

  const handleSendClick = async (prompt: string) => {
    if (!prompt.trim()) {
      setShowAlert(true);
      return;
    }
    setInputValue('');
    setLoading(true);
    try {
      const response = await fetch('/api/main', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({ prompt }),
      });

      const data = await response.json();
      const [countryName, countryDescription] = data.result
        .split(':')
        .map((str: string) => str.trim());

      const targetCountry = Object.values(countriesData).find(
        (country) => country.name === countryName,
      );

      if (targetCountry) {
        handleLabelClick(targetCountry as CountryLabel);
        setDescription(countryDescription);
      }
    } catch (error) {
      console.error('OpenAI API 요청 중 오류 발생:', error);
    } finally {
      setLoading(false);
    }
  };

음성인식

const startListening = () => {
    if (typeof window === 'undefined') return;

    if (
      !('webkitSpeechRecognition' in window) &&
      !('SpeechRecognition' in window)
    ) {
      alert('음성인식 기능을 지원하지 않는 브라우저 입니다.');
      return;
    }

    const SpeechRecognition =
      (window as any).webkitSpeechRecognition || window.SpeechRecognition;
    const recognition = new SpeechRecognition();
    recognition.lang = 'ko-KR';
    recognition.interimResults = false;
    recognition.maxAlternatives = 1;

    recognition.onstart = () => {
      setIsRecording(true);
      console.log('Listening...');
    };

    recognition.onresult = async (event: any) => {
      const transcript: string = event.results[0][0].transcript;
      console.log('Transcript:', transcript);
      setInputValue(transcript);
      setIsRecording(false);
      await handleSendClick(transcript);
    };

    recognition.onerror = () => {
      setIsRecording(false);
    };

    recognition.onend = () => {
      setIsRecording(false);
    };

    recognition.start();
  };

0개의 댓글