1414import dmu .dasom .api .domain .common .exception .CustomException ;
1515import dmu .dasom .api .domain .common .exception .ErrorCode ;
1616import lombok .RequiredArgsConstructor ;
17- import org .slf4j .Logger ;
18- import org .slf4j .LoggerFactory ;
17+ import lombok .extern .slf4j .Slf4j ;
1918import org .springframework .beans .factory .annotation .Value ;
2019import org .springframework .core .io .ClassPathResource ;
2120import org .springframework .stereotype .Service ;
2221
22+ import java .io .ByteArrayInputStream ;
2323import java .io .IOException ;
2424import java .security .GeneralSecurityException ;
2525import java .util .ArrayList ;
26+ import java .util .Base64 ;
2627import java .util .Collections ;
2728import java .util .List ;
2829
2930@ RequiredArgsConstructor
3031@ Service
32+ @ Slf4j
3133public class GoogleApiService {
3234
33- private static final Logger logger = LoggerFactory .getLogger (GoogleApiService .class );
34- private static final String APPLICATION_NAME = "Recruit Form" ;
35- private static final JsonFactory JSON_FACTORY = JacksonFactory .getDefaultInstance ();
36- @ Value ("${google.credentials.file.path}" )
37- private String credentialsFilePath ;
35+ @ Value ("${google.credentials.json}" )
36+ private String credentialsJson ;
37+
3838 @ Value ("${google.spreadsheet.id}" )
3939 private String spreadSheetId ;
40+
41+ private static final String APPLICATION_NAME = "Recruit Form" ;
42+ private static final JsonFactory JSON_FACTORY = JacksonFactory .getDefaultInstance ();
43+
4044 private Sheets sheetsService ;
4145
4246 // Google Sheets API 서비스 객체를 생성하는 메소드
43- private Sheets getSheetsService () throws IOException , GeneralSecurityException {
44- if (sheetsService == null ){
45- ClassPathResource resource = new ClassPathResource (credentialsFilePath );
47+ private Sheets getSheetsService () throws IOException , GeneralSecurityException {
48+ if (sheetsService == null ) {
49+ ByteArrayInputStream decodedStream = new ByteArrayInputStream (Base64 .getDecoder ()
50+ .decode (credentialsJson ));
51+
4652 GoogleCredentials credentials = GoogleCredentials
47- .fromStream (resource .getInputStream ())
48- .createScoped (Collections .singletonList ("https://www.googleapis.com/auth/spreadsheets" ));
49-
50- sheetsService = new Sheets .Builder (GoogleNetHttpTransport .newTrustedTransport (),
51- JSON_FACTORY ,
52- new HttpCredentialsAdapter (credentials ))
53- .setApplicationName (APPLICATION_NAME )
54- .build ();
53+ .fromStream (decodedStream )
54+ .createScoped (Collections .singletonList ("https://www.googleapis.com/auth/spreadsheets" ));
55+
56+ sheetsService = new Sheets .Builder (
57+ GoogleNetHttpTransport .newTrustedTransport (),
58+ JSON_FACTORY ,
59+ new HttpCredentialsAdapter (credentials )
60+ )
61+ .setApplicationName (APPLICATION_NAME )
62+ .build ();
5563 }
5664 return sheetsService ;
5765 }
@@ -60,12 +68,13 @@ public void writeToSheet(String spreadsheetId, String range, List<List<Object>>
6068 try {
6169 Sheets service = getSheetsService ();
6270 ValueRange body = new ValueRange ().setValues (values );
63- service .spreadsheets ().values ()
64- .update (spreadsheetId , range , body )
65- .setValueInputOption ("USER_ENTERED" )
66- .execute ();
67- } catch (IOException | GeneralSecurityException e ) {
68- logger .error ("구글 시트에 데이터를 쓰는 데 실패했습니다." , e );
71+ service .spreadsheets ()
72+ .values ()
73+ .update (spreadsheetId , range , body )
74+ .setValueInputOption ("USER_ENTERED" )
75+ .execute ();
76+ } catch (IOException | GeneralSecurityException e ) {
77+ log .error ("시트에 데이터를 쓰는 데 실패했습니다." );
6978 throw new CustomException (ErrorCode .WRITE_FAIL );
7079 }
7180 }
@@ -78,32 +87,34 @@ public void updateSheet(List<Applicant> applicants) {
7887 processSheetsUpdate (applicants , false );
7988 }
8089
81- public int findRowIndexByStudentNo (String spreadSheetId , String sheetName , String studentNo ){
90+ public int findRowIndexByStudentNo (String spreadSheetId , String sheetName , String studentNo ) {
8291 try {
8392 List <List <Object >> rows = readSheet (spreadSheetId , sheetName + "!A:L" ); // A열부터 L열까지 읽기
8493
85- for (int i = 0 ; i < rows .size (); i ++){
94+ for (int i = 0 ; i < rows .size (); i ++) {
8695 List <Object > row = rows .get (i );
87- if (!row .isEmpty () && row .get (2 ).equals (studentNo )){ // 학번(Student No)이 3번째 열(A=0 기준)
96+ if (!row .isEmpty () && row .get (2 )
97+ .equals (studentNo )) { // 학번(Student No)이 3번째 열(A=0 기준)
8898 return i + 1 ;
8999 }
90100 }
91101 } catch (Exception e ) {
92- logger .error ("구글시트에서 행 찾기 실패" , e );
102+ log .error ("시트에서 행 찾기 실패" );
93103 }
94104 return -1 ;
95105 }
96106
97107 public List <List <Object >> readSheet (String spreadsheetId , String range ) {
98108 try {
99109 Sheets service = getSheetsService ();
100- ValueRange response = service .spreadsheets ().values ()
101- .get (spreadsheetId , range )
102- .execute ();
110+ ValueRange response = service .spreadsheets ()
111+ .values ()
112+ .get (spreadsheetId , range )
113+ .execute ();
103114
104115 return response .getValues ();
105116 } catch (IOException | GeneralSecurityException e ) {
106- logger .error ("시트에서 데이터를 읽어오는데 실패했습니다." , e );
117+ log .error ("시트에서 데이터를 읽어오는 데 실패했습니다." );
107118 throw new CustomException (ErrorCode .SHEET_READ_FAIL );
108119 }
109120 }
@@ -113,7 +124,7 @@ public int getLastRow(String spreadsheetId, String sheetName) {
113124 List <List <Object >> rows = readSheet (spreadsheetId , sheetName + "!A:L" ); // A~L 열까지 읽기
114125 return rows == null ? 0 : rows .size (); // 데이터가 없으면 0 반환
115126 } catch (Exception e ) {
116- logger .error ("Failed to retrieve last row from Google Sheet" , e );
127+ log .error ("시트에서 마지막 행 찾기 실패" );
117128 throw new CustomException (ErrorCode .SHEET_READ_FAIL );
118129 }
119130 }
@@ -124,27 +135,28 @@ public void batchUpdateSheet(String spreadsheetId, List<ValueRange> valueRanges)
124135
125136 // BatchUpdate 요청 생성
126137 BatchUpdateValuesRequest batchUpdateRequest = new BatchUpdateValuesRequest ()
127- .setValueInputOption ("USER_ENTERED" ) // 사용자 입력 형식으로 값 설정
128- .setData (valueRanges ); // 여러 ValueRange 추가
138+ .setValueInputOption ("USER_ENTERED" ) // 사용자 입력 형식으로 값 설정
139+ .setData (valueRanges ); // 여러 ValueRange 추가
129140
130141 // BatchUpdate 실행
131- BatchUpdateValuesResponse response = service .spreadsheets ().values ()
132- .batchUpdate (spreadsheetId , batchUpdateRequest )
133- .execute ();
142+ BatchUpdateValuesResponse response = service .spreadsheets ()
143+ .values ()
144+ .batchUpdate (spreadsheetId , batchUpdateRequest )
145+ .execute ();
134146
135- logger .info ("Batch update completed. Total updated rows: {}" , response .getTotalUpdatedRows ());
147+ log .info ("시트 업데이트 성공. {}" , response .getTotalUpdatedRows ());
136148 } catch (IOException | GeneralSecurityException e ) {
137- logger .error ("Batch update failed" , e );
149+ log .error ("시트 업데이트 실패." );
138150 throw new CustomException (ErrorCode .SHEET_WRITE_FAIL );
139151 }
140152 }
141153
142154
143155 private ValueRange createValueRange (String range , List <List <Object >> values ) {
144156 return new ValueRange ()
145- .setRange (range )
146- .setMajorDimension ("ROWS" ) // 행 단위로 데이터 설정
147- .setValues (values );
157+ .setRange (range )
158+ .setMajorDimension ("ROWS" ) // 행 단위로 데이터 설정
159+ .setValues (values );
148160 }
149161
150162 public void processSheetsUpdate (List <Applicant > applicants , boolean isAppend ) {
@@ -160,7 +172,7 @@ public void processSheetsUpdate(List<Applicant> applicants, boolean isAppend) {
160172 } else {
161173 int rowIndex = findRowIndexByStudentNo (spreadSheetId , "Sheet1" , applicant .getStudentNo ());
162174 if (rowIndex == -1 ) {
163- logger .warn ("구글시트에서 사용자를 찾을 수 없습니다. : {}" , applicant .getStudentNo ());
175+ log .warn ("시트에서 지원자를 찾을 수 없습니다. : {}" , applicant .getStudentNo ());
164176 continue ;
165177 }
166178 range = "Sheet1!A" + rowIndex + ":L" + rowIndex ;
@@ -170,11 +182,10 @@ public void processSheetsUpdate(List<Applicant> applicants, boolean isAppend) {
170182
171183 batchUpdateSheet (spreadSheetId , valueRanges );
172184 } catch (Exception e ) {
173- logger .error ("구글시트 업데이트에 실패했습니다." , e );
185+ log .error ("시트 업데이트에 실패했습니다." , e );
174186 throw new CustomException (ErrorCode .SHEET_WRITE_FAIL );
175187 }
176188 }
177189
178190
179-
180191}
0 commit comments