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 ;
20- import org .springframework .core .io .ClassPathResource ;
2119import org .springframework .stereotype .Service ;
2220
21+ import java .io .ByteArrayInputStream ;
2322import java .io .IOException ;
2423import java .security .GeneralSecurityException ;
2524import java .util .ArrayList ;
25+ import java .util .Base64 ;
2626import java .util .Collections ;
2727import java .util .List ;
2828
2929@ RequiredArgsConstructor
3030@ Service
31+ @ Slf4j
3132public class GoogleApiService {
3233
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 ;
34+ @ Value ("${google.credentials.json}" )
35+ private String credentialsJson ;
36+
3837 @ Value ("${google.spreadsheet.id}" )
3938 private String spreadSheetId ;
39+
40+ private static final String APPLICATION_NAME = "Recruit Form" ;
41+ private static final JsonFactory JSON_FACTORY = JacksonFactory .getDefaultInstance ();
42+
4043 private Sheets sheetsService ;
4144
4245 // Google Sheets API 서비스 객체를 생성하는 메소드
43- private Sheets getSheetsService () throws IOException , GeneralSecurityException {
44- if (sheetsService == null ){
45- ClassPathResource resource = new ClassPathResource (credentialsFilePath );
46+ private Sheets getSheetsService () throws IOException , GeneralSecurityException {
47+ if (sheetsService == null ) {
48+ ByteArrayInputStream decodedStream = new ByteArrayInputStream (Base64 .getDecoder ()
49+ .decode (credentialsJson ));
50+
4651 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 ();
52+ .fromStream (decodedStream )
53+ .createScoped (Collections .singletonList ("https://www.googleapis.com/auth/spreadsheets" ));
54+
55+ sheetsService = new Sheets .Builder (
56+ GoogleNetHttpTransport .newTrustedTransport (),
57+ JSON_FACTORY ,
58+ new HttpCredentialsAdapter (credentials )
59+ )
60+ .setApplicationName (APPLICATION_NAME )
61+ .build ();
5562 }
5663 return sheetsService ;
5764 }
@@ -60,12 +67,13 @@ public void writeToSheet(String spreadsheetId, String range, List<List<Object>>
6067 try {
6168 Sheets service = getSheetsService ();
6269 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 );
70+ service .spreadsheets ()
71+ .values ()
72+ .update (spreadsheetId , range , body )
73+ .setValueInputOption ("USER_ENTERED" )
74+ .execute ();
75+ } catch (IOException | GeneralSecurityException e ) {
76+ log .error ("시트에 데이터를 쓰는 데 실패했습니다." );
6977 throw new CustomException (ErrorCode .WRITE_FAIL );
7078 }
7179 }
@@ -78,32 +86,34 @@ public void updateSheet(List<Applicant> applicants) {
7886 processSheetsUpdate (applicants , false );
7987 }
8088
81- public int findRowIndexByStudentNo (String spreadSheetId , String sheetName , String studentNo ){
89+ public int findRowIndexByStudentNo (String spreadSheetId , String sheetName , String studentNo ) {
8290 try {
8391 List <List <Object >> rows = readSheet (spreadSheetId , sheetName + "!A:L" ); // A열부터 L열까지 읽기
8492
85- for (int i = 0 ; i < rows .size (); i ++){
93+ for (int i = 0 ; i < rows .size (); i ++) {
8694 List <Object > row = rows .get (i );
87- if (!row .isEmpty () && row .get (2 ).equals (studentNo )){ // 학번(Student No)이 3번째 열(A=0 기준)
95+ if (!row .isEmpty () && row .get (2 )
96+ .equals (studentNo )) { // 학번(Student No)이 3번째 열(A=0 기준)
8897 return i + 1 ;
8998 }
9099 }
91100 } catch (Exception e ) {
92- logger .error ("구글시트에서 행 찾기 실패" , e );
101+ log .error ("시트에서 행 찾기 실패" );
93102 }
94103 return -1 ;
95104 }
96105
97106 public List <List <Object >> readSheet (String spreadsheetId , String range ) {
98107 try {
99108 Sheets service = getSheetsService ();
100- ValueRange response = service .spreadsheets ().values ()
101- .get (spreadsheetId , range )
102- .execute ();
109+ ValueRange response = service .spreadsheets ()
110+ .values ()
111+ .get (spreadsheetId , range )
112+ .execute ();
103113
104114 return response .getValues ();
105115 } catch (IOException | GeneralSecurityException e ) {
106- logger .error ("시트에서 데이터를 읽어오는데 실패했습니다." , e );
116+ log .error ("시트에서 데이터를 읽어오는 데 실패했습니다." );
107117 throw new CustomException (ErrorCode .SHEET_READ_FAIL );
108118 }
109119 }
@@ -113,7 +123,7 @@ public int getLastRow(String spreadsheetId, String sheetName) {
113123 List <List <Object >> rows = readSheet (spreadsheetId , sheetName + "!A:L" ); // A~L 열까지 읽기
114124 return rows == null ? 0 : rows .size (); // 데이터가 없으면 0 반환
115125 } catch (Exception e ) {
116- logger .error ("Failed to retrieve last row from Google Sheet" , e );
126+ log .error ("시트에서 마지막 행 찾기 실패" );
117127 throw new CustomException (ErrorCode .SHEET_READ_FAIL );
118128 }
119129 }
@@ -124,27 +134,28 @@ public void batchUpdateSheet(String spreadsheetId, List<ValueRange> valueRanges)
124134
125135 // BatchUpdate 요청 생성
126136 BatchUpdateValuesRequest batchUpdateRequest = new BatchUpdateValuesRequest ()
127- .setValueInputOption ("USER_ENTERED" ) // 사용자 입력 형식으로 값 설정
128- .setData (valueRanges ); // 여러 ValueRange 추가
137+ .setValueInputOption ("USER_ENTERED" ) // 사용자 입력 형식으로 값 설정
138+ .setData (valueRanges ); // 여러 ValueRange 추가
129139
130140 // BatchUpdate 실행
131- BatchUpdateValuesResponse response = service .spreadsheets ().values ()
132- .batchUpdate (spreadsheetId , batchUpdateRequest )
133- .execute ();
141+ BatchUpdateValuesResponse response = service .spreadsheets ()
142+ .values ()
143+ .batchUpdate (spreadsheetId , batchUpdateRequest )
144+ .execute ();
134145
135- logger .info ("Batch update completed. Total updated rows: {}" , response .getTotalUpdatedRows ());
146+ log .info ("시트 업데이트 성공. {}" , response .getTotalUpdatedRows ());
136147 } catch (IOException | GeneralSecurityException e ) {
137- logger .error ("Batch update failed" , e );
148+ log .error ("시트 업데이트 실패." );
138149 throw new CustomException (ErrorCode .SHEET_WRITE_FAIL );
139150 }
140151 }
141152
142153
143154 private ValueRange createValueRange (String range , List <List <Object >> values ) {
144155 return new ValueRange ()
145- .setRange (range )
146- .setMajorDimension ("ROWS" ) // 행 단위로 데이터 설정
147- .setValues (values );
156+ .setRange (range )
157+ .setMajorDimension ("ROWS" ) // 행 단위로 데이터 설정
158+ .setValues (values );
148159 }
149160
150161 public void processSheetsUpdate (List <Applicant > applicants , boolean isAppend ) {
@@ -160,7 +171,7 @@ public void processSheetsUpdate(List<Applicant> applicants, boolean isAppend) {
160171 } else {
161172 int rowIndex = findRowIndexByStudentNo (spreadSheetId , "Sheet1" , applicant .getStudentNo ());
162173 if (rowIndex == -1 ) {
163- logger .warn ("구글시트에서 사용자를 찾을 수 없습니다. : {}" , applicant .getStudentNo ());
174+ log .warn ("시트에서 지원자를 찾을 수 없습니다. : {}" , applicant .getStudentNo ());
164175 continue ;
165176 }
166177 range = "Sheet1!A" + rowIndex + ":L" + rowIndex ;
@@ -170,11 +181,10 @@ public void processSheetsUpdate(List<Applicant> applicants, boolean isAppend) {
170181
171182 batchUpdateSheet (spreadSheetId , valueRanges );
172183 } catch (Exception e ) {
173- logger .error ("구글시트 업데이트에 실패했습니다." , e );
184+ log .error ("시트 업데이트에 실패했습니다." , e );
174185 throw new CustomException (ErrorCode .SHEET_WRITE_FAIL );
175186 }
176187 }
177188
178189
179-
180190}
0 commit comments