0. package 설치및 . GPT APi 키 발급받기 .
https://platform.openai.com/api-keys
https://pub.dev/packages/chat_gpt_flutter
api 키만 따로 클래스를 만들어 저장해 둔다.
class APIKey {
static const apiKey = "*********************************";
}
1. 한글깨짐 문제 해결 : 및 . 기존방식으로 안되는 부분 수정 . 현재 업데이트된 방식입니다.
기존 코드들은 다빈치용 인줄 모르고 고생좀 했습니다.
({
"model": "gpt-3.5-turbo",
"messages": [
{"role": "user", "content": message}
],
"max_tokens": 500,
}),
var parsedReponse = jsonDecode(utf8.decode(response.bodyBytes));
2. 스크롤 업데이트로 하단 유지하기
var scrollController = ScrollController();
scrollMethod() { // autoScroll for list builder
scrollController.animateTo(scrollController.position.maxScrollExtent,
duration: Duration(milliseconds: 500), curve: Curves.easeOut);
}
3. 사용된 패키지. 와 모델 .
import 'package:speech_to_text/speech_to_text.dart';
import 'package:avatar_glow/avatar_glow.dart';
import 'package:http/http.dart' as http;
enum ChatMessageType {user,bot}
class ChatMessage{
String text;
ChatMessageType type;
ChatMessage({required this.text, required this.type});
}
4. api_service.dart
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:noti_local/gpt_chat/api_key.dart';
class GptApiService {
String baseUrl = 'https://api.openai.com/v1/chat/completions';
Map<String, String> header = {
'Content-Type': 'application/json',
'Authorization': 'Bearer ${APIKey.apiKey}',
};
sendMessage(String message) async {
print('sendmsg = $message');
var response = await http.post(
Uri.parse(baseUrl),
headers: header,
body: jsonEncode({
"model": "gpt-3.5-turbo",
"messages": [
{"role": "user", "content": message}
],
"max_tokens": 500,
}),
);
print(response.body);
var replyRes = jsonDecode(utf8.decode(response.bodyBytes));
String reply = replyRes['choices'][0]['message']['content'];
print('json model msg : $reply');
return reply;
}
}
.5. 메인 스크린 페이지 소스.
import 'package:avatar_glow/avatar_glow.dart';
import 'package:flutter/material.dart';
import 'package:noti_local/a_drawer.dart';
import 'package:noti_local/gpt_chat/api_service.dart';
import 'package:noti_local/gpt_chat/model_chat.dart';
import 'package:speech_to_text/speech_to_text.dart';
class ChatGptHome extends StatefulWidget {
const ChatGptHome({super.key});
@override
State<ChatGptHome> createState() => _ChatGptHomeState();
}
class _ChatGptHomeState extends State<ChatGptHome> {
SpeechToText speechToText = SpeechToText();
String textChat = 'Chat Gpt Test';
bool isListening = false;
final List<ChatMessage> message = []; // for chat
//
String textVoice = " Click Hold for Speech to Text";
GptApiService gptApiService = GptApiService();
var scrollController = ScrollController();
scrollMethod() { // autoScroll for list builder
scrollController.animateTo(scrollController.position.maxScrollExtent,
duration: Duration(milliseconds: 500), curve: Curves.easeOut);
}
@override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
floatingActionButton: AvatarGlow(
glowColor: Colors.blue,
endRadius: 90.0,
repeat: true,
showTwoGlows: true,
repeatPauseDuration: const Duration(milliseconds: 100),
animate: isListening,
duration:const Duration(milliseconds: 100),
child: GestureDetector(
onTapDown: (voice) async {
if (!isListening) {
var available = await speechToText.initialize();
if (available) {
setState(() {
scrollMethod();
isListening = true;
speechToText.listen(onResult: (result) {
setState(() {
//결과를 다시 setState해야 화면이 갱신된다.
textVoice = result.recognizedWords;
print('textVoice : $textVoice');
scrollMethod();
});
});
});
}
}
},
onTapUp: (voice) async {
speechToText.stop();
setState(() {
isListening = false;
scrollMethod();
});
message.add(ChatMessage(text: textVoice, type: ChatMessageType.user));
var msg = await gptApiService.sendMessage(textVoice); // 안되면 Static 으로 변경한다.
print('msg : $msg');
setState(() {
message.add(ChatMessage(text: msg, type: ChatMessageType.bot));
scrollMethod();
});
},
child: CircleAvatar(radius: 35, child: Icon(isListening ? Icons.mic : Icons.mic_none, color: Colors.white)),
),
),
drawer: ADrawer(),
appBar: AppBar(title: Text('chat gpt')),
body: Container(
alignment: Alignment.center,
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
margin: EdgeInsets.only(bottom: 150),
padding: EdgeInsets.symmetric(horizontal: 10, vertical: 10),
child: Column(
children: [
Text(textVoice, style: TextStyle(color: isListening ? Colors.white70 : Colors.white38, fontSize: 28)),
SizedBox(height: 12),
//
Expanded(
child: Container(
decoration: BoxDecoration(color: Colors.brown, borderRadius: BorderRadius.circular(20)),
child: ListView.builder(
controller: scrollController,
physics: const BouncingScrollPhysics(),
shrinkWrap: true,
itemCount: message.length,
itemBuilder: (context, index) {
var chat = message[index];
return chatBubble(chatText: chat.text, type: chat.type);
}),
)),
],
),
),
);
}
Widget chatBubble({required chatText, required ChatMessageType type}) {
scrollMethod();
return Row(
children: [
CircleAvatar(
child: Icon(Icons.person, color: Colors.white),
),
const SizedBox(height: 12),
Container(
width:MediaQuery.of(context).size.width*0.8,
padding: EdgeInsets.all(10),
margin: EdgeInsets.only(bottom: 10),
decoration: const BoxDecoration(color: Colors.white38),
child: Text('$chatText', style: TextStyle(fontSize: 15)),
),
],
);
}
//
}
'Flutter' 카테고리의 다른 글
동화책 만들기? OnBoardingScreen with GPT. (0) | 2023.12.15 |
---|---|
WebView 로 bard gpt chat 만들기? .. (1) | 2023.12.15 |
flutter Speech To Text // dart 3 (0) | 2023.12.10 |
Dark & Light Mode with Provider (0) | 2023.12.10 |
Flutter Voice to Text 음성입력.#2 (2) | 2023.12.05 |