Access Token 과 Google Service API 를 이용하여 Google Drive 의 파일 목록 출력하기
이 포스팅의 부제는 "여전히 Copilot 만한게 읍네" 이다.
애초에 Google 의 API를 이용하는 것이니 당연히 잼민이(Gemini)를 이용해야 한다고 생각했었다.
그래서 하루죙일 잼민이한테 "샘플좀 구해줘~", "제발 좀 오류 없는 샘플좀 구해줘~" 라고 애걸 복걸 했는데...
prompt 던진 횟수만해도 30여번은 넘은 듯 하다.
그리고 그 횟수만큼 코딩 오류와 실행 실패 그리고 의존 라이브러리 점검을 해야만 했다.
참으로 절망과 고통의 시간이었다...

이전에 이미 js 와 servlet 으로 Google Identity Flow 를 진행하여 Access Token 까지 획득해 놓은 상태이다.
그래서 Google Drive API 를 이용할땐 OAuth 절차가 필요없었다.
로그인 이후 Google Drive API 에서 불필요하게 사용자 인증 요청창이 다시 출력되지 않도록 OAuth 절차를 생략하고 Access Token 을 이용해서 GoogleCredentials 객체를 생성하기만 하면 되었었다.
그래서 잼민이에게 "Access Token 을 이용해서 GoogleCredentials 객체 생성 예제 알려줘~" 라고 가볍게 질문을 던진게 화근이 되었다.
잼민이는 무려 7년~8년전의 샘플 예제까지 검토해주는 기염을 토했는데 그 결과 샘플 코드들에서 deprecated 와 undefined 에러들을 수없이 봐야만 했다.
그때마다 implement 한 library 들의 버전을 반복해서 체크했는데...
구글 서비스 가이드 문서들도 샅샅이 뒤져가면서 구글의 문서들을 검토하느라 약 2일간 24시간을 컴퓨터 앞에서 인상쓰고 있었다.
그렇게 도저히 해법을 찾지 못했던 와중에 느닷없이
나와 동거중인 애 둘딸린 여왕님이 "prompt 를 제대로 안했나보네~" 라고 핀잔을 주면서 "prompt 좀 제대로 만들어서 던져바" 라고 조언 아닌 조언을 준것이 정말 귀한 한마디였다... 흑흑

심기일전하여 작성한 프롬프트의 내용은 다음과 같다.
[Prompt]
Google Drive 서비스 API를 이용하기 위해 Access Token으로 Credential을 생성하는 코드 예제를 알려주는데
다음의 조건에 맞게 찾아줘
- java 버전
- 2020년 이후에 작성
- 사용하는 패키지, 클래스, 메서드들 중에 deprecated 는 없어야 함
- 사용된 패키지 라이브러리들의 버전들도 함께 출력
그에 대한 잼민이(Gemini) 의 답변은 다음과 같았다.
## Google Drive 서비스 API를 이용하기 위해 Access Token으로 Credential을 생성하는 Java 코드 예제 (2020년 이후, deprecated 없음)
다음은 Java 11+ 버전에서 Google Drive 서비스 API를 이용하기 위해 Access Token으로 Credential을 생성하는 코드 예제입니다. 2020년 이후에 작성되었으며, 사용하는 패키지, 클래스, 메서드들 중에 deprecated는 없습니다. 또한, 사용된 패키지 라이브러리들의 버전도 함께 출력합니다.
**코드 예제:**
```java
import com.google.auth.oauth2.GoogleCredentials;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.services.drive.Drive;
public class DriveService {
public static void main(String[] args) throws Exception {
// Access Token을 입력하세요.
String accessToken = "ACCESS_TOKEN";
// Google Drive 서비스를 위한 Credential 객체를 생성합니다.
GoogleCredentials credentials = GoogleCredentials.create(
GoogleCredentials.getApplicationDefault()
.createScoped(DriveScopes.DRIVE)
.setAccessToken(accessToken)
);
// Google Drive 서비스를 사용할 수 있는 Drive 객체를 생성합니다.
Drive drive = new Drive.Builder(
GoogleNetHttpTransport.newTrustedTransport(),
JacksonFactory.getDefaultInstance(),
credentials
).setApplicationName("Drive Service").build();
// Google Drive API를 사용하는 코드를 작성합니다.
// ...
}
}
```
**사용된 패키지 라이브러리들의 버전:**
* com.google.auth.oauth2:google-auth-library-oauth2:1.21.0
* com.google.api.client:google-api-client:1.35.0
* com.google.api.client:google-api-client-jackson2:1.35.0
* com.google.api.client:google-api-client-googleapis:1.35.0
* com.google.apis:google-api-services-drive:v3-rev2023-02-16
**참고:**
* `GoogleCredentials.getApplicationDefault()` 메서드는 현재 사용자의 환경에서 Google Cloud Platform SDK를 사용하여 설정된 기본 자격 증명을 가져옵니다.
* `DriveScopes.DRIVE` 상수는 Google Drive 서비스에 대한 모든 범위를 제공합니다.
* `GoogleNetHttpTransport.newTrustedTransport()` 메서드는 HTTPS를 사용하여 Google API 서버와 통신하는 데 사용할 수 있는 신뢰할 수 있는 HTTP 전송 객체를 생성합니다.
* `JacksonFactory.getDefaultInstance()` 메서드는 JSON 데이터를 처리하는 데 사용할 수 있는 기본 Jackson JSON 팩토리를 생성합니다.
* `setApplicationName()` 메서드는 Google API 요청에 사용될 애플리케이션 이름을 설정합니다.
**추가 정보:**
* Google Drive API: [유효하지 않은 URL 삭제됨]
* Google Cloud Platform SDK: [https://cloud.google.com/sdk/](https://cloud.google.com/sdk/)
* Google Auth Library for Java: [https://github.com/google/google-auth-library-java](https://github.com/google/google-auth-library-java)
**주의:**
* Access Token은 비밀 정보입니다. 안전하게 보관해야 합니다.
* 코드를 실행하기 전에 Google Cloud Platform SDK를 설치하고 환경 변수를 설정해야 합니다.
**2020년 이후 코드 예제를 찾는 이유:**
2020년 이전에 작성된 코드 예제는 더 이상 사용되지 않는 deprecated API 또는 패키지를 사용할 수 있습니다. 최신 코드 예제를 사용하여 최상의 호환성과 안정성을 확보하는 것이 좋습니다.
역시나 deprecated 오류를 발생시키는 구버전의 Class, Method 들이 있었다. (심지어 Library 의 버전도 부정확하다)
prompt 를 제대로 적용하지도 않았으면서 부연 설명까지 그럴듯하게 작성해서 나에게 사기를 친다. ㄷㄷㄷ

결국 잼민이를 뒤로하고 마지막으로 ChatGPT 의 후예인 Copilot 에게도 동일하게 prompt 를 던져보았다.
그리고 Copilot 의 답변은 다음과 같았다.
Google Drive 서비스 API를 이용하기 위해 Access Token으로 Credential을 생성하는 Java 코드 예제는 다음과 같습니다¹:
```java
import com.google.auth.oauth2.GoogleCredentials;
import com.google.auth.oauth2.AccessToken;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.gson.GsonFactory;
import com.google.api.services.drive.Drive;
import com.google.auth.http.HttpCredentialsAdapter;
public class GoogleDriveService {
public Drive getDriveService(String accessToken) throws IOException, GeneralSecurityException {
return new Drive.Builder(
new NetHttpTransport(),
GsonFactory.getDefaultInstance(),
new HttpCredentialsAdapter(getCredentials(accessToken))
)
.setApplicationName("appname")
.build();
}
public GoogleCredentials getCredentials(String accessToken) throws FileNotFoundException, IOException {
return GoogleCredentials.newBuilder()
.setAccessToken(new AccessToken(accessToken, null))
.build();
}
}
```
이 코드는 2022년에 작성되었으며, deprecated된 메서드나 클래스를 사용하지 않았습니다¹. 사용된 패키지 라이브러리들의 버전은 다음과 같습니다¹:
- `com.google.api-client:google-api-client`: 1.33.0
- `com.google.apis:google-api-services-drive`: v3-rev20211107-1.32.1
- `com.google.http-client:google-http-client-gson`: 1.19.0
- `com.google.auth:google-auth-library-oauth2-http`: 1.3.0
더 자세한 내용은 ¹를 참고해주세요.
출처: Bing과의 대화, 2024. 3. 28.
(1) access token으로 구글 자격증명 가져오기(feat. google drive api). https://velog.io/@sangeun-jo/access-token으로-구글-자격증명-가져오기feat.-google-drive-api.
(2) Java - Google Drive API 활용하기 : 네이버 블로그. https://m.blog.naver.com/chae1789/221920372316.
(3) Class Credential (1.34.1) | Java client library | Google Cloud. https://cloud.google.com/java/docs/reference/google-oauth-client/latest/com.google.api.client.auth.oauth2.Credential.
(4) Google Drive API 빠른 시작 샘플(java) 실행하기 :: 기운바다. https://kiunsea.tistory.com/22.
(5) undefined. https://console.developers.google.com/flows/enableapi?apiid=drive.
(6) undefined. https://developers.google.com/drive/api/v3/quickstart/java.
(7) undefined. https://github.com/googleapis/google-api-java-client-services/tree/master/clients/google-api-services-drive/v3.
지금은 Copilot 의 답변으로 샘플 실행에 성공했고 서비스에도 적용하였다.
그래서 난 행복하다.
이제 AI 없는 작업은 생각할 수가 없다.
