728x90
안녕하세요.
오늘은 ChatGPT API로 챗봇 만들기 마지막 시간입니다.
이전 시간에는 ChatGPT API를 사용 설정하는 방법에 대해 알아보고, 안드로이드에서 채팅을 주고 받는 것처럼 화면에 띄우기 위한 리사이클러뷰를 만들었습니다.
관련된 내용은 다음 링크를 확인해주세요.
2024.05.02 - [안드로이드 자바] - [JAVA][Android] ChatGPT API로 챗봇 만들기 - (1) ChatGPT API 사용하기
2024.05.09 - [안드로이드 자바] - [JAVA][Android] ChatGPT API로 챗봇 만들기 - (2) 리사이클러뷰 만들기
이번 시간에는 이전에 작성한 코드를 바탕으로 실제 ChatGPT API에 질문을 보내고 응답을 받아서 리사이클러뷰에 띄워보는 작업까지 진행해보겠습니다.
1. Retrofit2 의존성 추가
이 예제에서는 http 통신을 위해 Retrofit2 라이브러리를 사용합니다. 앱 수준의 build.gradle에 다음과 같이 의존성을 추가해줍니다.
// Retrofit 라이브러리
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
// Gson 변환기 라이브러리
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
Retrofit 과 Gson 변환기에 대한 자세한 내용을 알고 싶다면, 다음 공식문서를 참고하시면 됩니다.
https://square.github.io/retrofit/
2. API 인터페이스 정의
ChatGPT API를 호출하기 위한 인터페이스를 정의합니다.
import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.Headers;
import retrofit2.http.POST;
public interface ChatGPTApi {
@Headers({
"Content-Type: application/json",
"Authorization: Bearer 여기에api키입력" // api키는 Bearer 뒤에 공백 한칸 띄고 입력합니다.
})
@POST("v1/chat/completions")
Call<ChatGPTResponse> getChatResponse(@Body ChatGPTRequest request);
}
3. 요청 및 응답 데이터 모델 클래스 생성
import java.util.List;
public class ChatGPTRequest {
private String model;
private List<ChatMsg> messages;
public ChatGPTRequest(String model, List<ChatMsg> messages) {
this.model = model;
this.messages = messages;
}
}
import java.util.List;
public class ChatGPTResponse {
private List<Choice> choices;
public List<Choice> getChoices() {
return choices;
}
public static class Choice {
private ChatMsg message;
public ChatMsg getMessage() {
return message;
}
}
}
4. Retrofit 인스턴스 생성
Retrofit 인스턴스를 생성하고, ChatGPT API 인터페이스를 초기화합니다.
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class ApiClient {
private static final String BASE_URL = "https://api.openai.com/";
public static ChatGPTApi getChatGPTApi() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
return retrofit.create(ChatGPTApi.class);
}
}
5. MainActivity 에서 API 호출하기
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
import java.util.List;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
public class MainActivity extends AppCompatActivity {
RecyclerView recyclerView;
ChatMsgAdapter adapter;
Button btnSend;
EditText etMsg;
ProgressBar progressBar;
List<ChatMsg> chatMsgList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//뷰 객체 연결
recyclerView = findViewById(R.id.recyclerView);
btnSend = findViewById(R.id.btn_send);
etMsg = findViewById(R.id.et_msg);
progressBar = findViewById(R.id.progressBar);
//채팅 메시지 데이터를 담을 list 생성
chatMsgList = new ArrayList<>();
//리사이클러뷰 초기화
recyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
adapter = new ChatMsgAdapter();
adapter.setDataList(chatMsgList);
recyclerView.setAdapter(adapter);
//EditText 객체에 text가 변경될 때 실행될 리스너 설정
etMsg.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
//입력창에 메시지가 입력되었을 때만 버튼이 클릭 가능하도록 설정
btnSend.setEnabled(s.length() > 0);
}
});
//메시지 전송버튼 클릭 리스너 설정 (람다식으로 작성함)
btnSend.setOnClickListener(v -> {
//etMsg에 쓰여있는 텍스트를 가져옵니다.
String msg = etMsg.getText().toString();
//새로운 ChatMsg 객체를 생성하여 어댑터에 추가합니다.
ChatMsg chatMsg = new ChatMsg(ChatMsg.ROLE_USER, msg);
adapter.addChatMsg(chatMsg);
//etMsg의 텍스트를 초기화합니다.
etMsg.setText(null);
//키보드를 내립니다.
InputMethodManager manager = (InputMethodManager)getSystemService(INPUT_METHOD_SERVICE);
manager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
//응답 기다리는 동안 로딩바 보이게 하기
progressBar.setVisibility(View.VISIBLE);
//응답 기다리는 동안 화면 터치 막기
getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
//Retrofit으로 요청 보내고 응답받기
sendMsgToChatGPT();
});
}
private void sendMsgToChatGPT() {
ChatGPTApi api = ApiClient.getChatGPTApi();
ChatGPTRequest request = new ChatGPTRequest(
"gpt-3.5-turbo",
chatMsgList
);
api.getChatResponse(request).enqueue(new Callback<ChatGPTResponse>() {
@Override
public void onResponse(Call<ChatGPTResponse> call, Response<ChatGPTResponse> response) {
//응답을 성공적으로 받은 경우
if (response.isSuccessful() && response.body() != null) {
//응답에서 gpt 답변 가져오기
String chatResponse = response.body().getChoices().get(0).getMessage().content;
//리사이클러뷰에 답변 추가하기
adapter.addChatMsg(new ChatMsg(ChatMsg.ROLE_ASSISTANT, chatResponse));
//로딩바 숨기기
progressBar.setVisibility(View.GONE);
//화면 터치 차단 해제
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
} else {
//응답 오류
Log.e("getChatResponse", "Error: " + response.message());
}
}
@Override
public void onFailure(Call<ChatGPTResponse> call, Throwable t) {
//응답 오류
Log.e("getChatResponse", "onFailure: ", t);
}
});
}
}
6. 시연영상
위 예제가 정상적으로 동작한다면 다음 시연 영상처럼 작동할 것입니다.
'안드로이드 자바' 카테고리의 다른 글
[JAVA][Android]<string> 태그 활용하기 (0) | 2024.06.08 |
---|---|
[JAVA][Android]textwatcher 활용해 글 변경 반응하기 (0) | 2024.06.04 |
[JAVA][Android] 네이버 회원 프로필 조회 API 사용하기 (2) | 2024.06.02 |
[JAVA][Android] 네이버 로그인 API 사용하기 (0) | 2024.05.15 |
[JAVA][Android]글자크기 맞춰 drawbleStart 이미지 크기 자동조절하기 (0) | 2024.05.11 |