본문 바로가기
안드로이드 자바

[JAVA][Android] ChatGPT API로 챗봇 만들기 - (3) Retrofit2 사용해서 챗봇에게 응답받기

by teamnova 2024. 6. 3.
728x90

안녕하세요.

오늘은 ChatGPT API로 챗봇 만들기 마지막 시간입니다.

 

이전 시간에는 ChatGPT API를 사용 설정하는 방법에 대해 알아보고, 안드로이드에서 채팅을 주고 받는 것처럼 화면에 띄우기 위한 리사이클러뷰를 만들었습니다.

관련된 내용은 다음 링크를 확인해주세요.

 

2024.05.02 - [안드로이드 자바] - [JAVA][Android] ChatGPT API로 챗봇 만들기 - (1) ChatGPT API 사용하기

 

[JAVA][Android] ChatGPT API로 챗봇 만들기 - (1) ChatGPT API 사용하기

안녕하세요.안드로이드에서 ChatGPT API를 사용해서 챗봇을 만드는 예제를 구현해보려고 합니다. 이 글에서는 postman을 사용해서 ChatGPT API 사용법에 대해서 먼저 알아보겠습니다. postman 은 간단하

stickode.tistory.com

2024.05.09 - [안드로이드 자바] - [JAVA][Android] ChatGPT API로 챗봇 만들기 - (2) 리사이클러뷰 만들기

 

[JAVA][Android] ChatGPT API로 챗봇 만들기 - (2) 리사이클러뷰 만들기

안녕하세요.ChatGPT API로 챗봇 만들기 두번째 시간입니다. 지난 시간에는 ChatGPT API를 사용하기 위한 설정 후 postman에서 api에 요청을 보내고 응답을 받는 방법에 대해 알아보았습니다.해당 내용은

stickode.tistory.com

 

 

이번 시간에는 이전에 작성한 코드를 바탕으로 실제 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/

 

Retrofit

A type-safe HTTP client for Android and Java

square.github.io

 

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. 시연영상

위 예제가 정상적으로 동작한다면 다음 시연 영상처럼 작동할 것입니다.