diff --git a/build.gradle b/build.gradle index 603bf06..d2c1c8e 100644 --- a/build.gradle +++ b/build.gradle @@ -49,6 +49,10 @@ dependencies { testImplementation 'org.springframework.security:spring-security-test' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' + implementation 'com.google.apis:google-api-services-sheets:v4-rev516-1.23.0' + implementation 'com.google.auth:google-auth-library-oauth2-http:0.20.0' + + implementation 'io.jsonwebtoken:jjwt-api:0.12.6' runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.12.6' runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.12.6' diff --git a/src/main/java/dmu/dasom/api/domain/common/exception/ErrorCode.java b/src/main/java/dmu/dasom/api/domain/common/exception/ErrorCode.java index ac0a036..472da76 100644 --- a/src/main/java/dmu/dasom/api/domain/common/exception/ErrorCode.java +++ b/src/main/java/dmu/dasom/api/domain/common/exception/ErrorCode.java @@ -16,7 +16,8 @@ public enum ErrorCode { ARGUMENT_NOT_VALID(400, "C007", "요청한 값이 올바르지 않습니다."), TOKEN_NOT_VALID(400, "C008", "토큰이 올바르지 않습니다."), INTERNAL_SERVER_ERROR(500, "C009", "서버에 문제가 발생하였습니다."), - NOT_FOUND(404, "C010", "해당 리소스를 찾을 수 없습니다.") + NOT_FOUND(404, "C010", "해당 리소스를 찾을 수 없습니다."), + WRITE_FAIL(400, "C011", "데이터를 쓰는데 실패하였습니다.") ; private final int status; diff --git a/src/main/java/dmu/dasom/api/domain/google/controller/GoogleController.java b/src/main/java/dmu/dasom/api/domain/google/controller/GoogleController.java new file mode 100644 index 0000000..984ed66 --- /dev/null +++ b/src/main/java/dmu/dasom/api/domain/google/controller/GoogleController.java @@ -0,0 +1,38 @@ +package dmu.dasom.api.domain.google.controller; + +import dmu.dasom.api.domain.google.service.GoogleApiService; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Collections; +import java.util.List; + +@RestController +@RequestMapping("/google") +@RequiredArgsConstructor +public class GoogleController { + + private final GoogleApiService googleApiService; + @Value("${google.spreadsheet.id}") + private String spreadsheetId; + + private static final String RANGE = "A1"; + + @PostMapping("/write") + public ResponseEntity writeToSheet(@RequestParam String word){ + try{ + List> values = List.of(Collections.singletonList(word)); + + googleApiService.writeToSheet(spreadsheetId, RANGE, values); + return ResponseEntity.ok("Data written successfully to the spreadsheet" + word); + } catch (Exception e){ + e.printStackTrace(); + return ResponseEntity.internalServerError().body("Failed to write data to the spreadsheet" + e.getMessage()); + } + } +} diff --git a/src/main/java/dmu/dasom/api/domain/google/service/GoogleApiService.java b/src/main/java/dmu/dasom/api/domain/google/service/GoogleApiService.java new file mode 100644 index 0000000..921deba --- /dev/null +++ b/src/main/java/dmu/dasom/api/domain/google/service/GoogleApiService.java @@ -0,0 +1,66 @@ +package dmu.dasom.api.domain.google.service; + +import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport; +import com.google.api.client.json.JsonFactory; +import com.google.api.client.json.jackson2.JacksonFactory; + +import com.google.api.services.sheets.v4.Sheets; +import com.google.api.services.sheets.v4.model.UpdateValuesResponse; +import com.google.api.services.sheets.v4.model.ValueRange; +import com.google.auth.http.HttpCredentialsAdapter; +import com.google.auth.oauth2.GoogleCredentials; +import dmu.dasom.api.domain.common.exception.CustomException; +import dmu.dasom.api.domain.common.exception.ErrorCode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.core.io.ClassPathResource; +import org.springframework.stereotype.Service; + +import java.io.IOException; +import java.security.GeneralSecurityException; +import java.util.Collections; +import java.util.List; + +@Service +public class GoogleApiService { + + private static final Logger logger = LoggerFactory.getLogger(GoogleApiService.class); + private static final String APPLICATION_NAME = "Recruit Form"; + private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance(); + @Value("${google.credentials.file.path}") + private String credentialsFilePath; + private Sheets sheetsService; + + // 해당 메소드는 sheets의 인스턴스를 얻는데 사용 + private Sheets getSheetsService() throws IOException, GeneralSecurityException{ + if(sheetsService == null){ + GoogleCredentials credentials = GoogleCredentials + .fromStream(new ClassPathResource(credentialsFilePath).getInputStream()) + .createScoped(Collections.singletonList("https://www.googleapis.com/auth/spreadsheets")); + sheetsService = new Sheets.Builder(GoogleNetHttpTransport.newTrustedTransport(), JSON_FACTORY, new HttpCredentialsAdapter(credentials)) + .setApplicationName(APPLICATION_NAME) + .build(); + } + return sheetsService; + } + + public void writeToSheet(String spreadsheetId, String range, List> values) { + try { + Sheets service = getSheetsService(); + ValueRange body = new ValueRange().setValues(values); + UpdateValuesResponse result = service.spreadsheets().values() + .update(spreadsheetId, range, body) + .setValueInputOption("USER_ENTERED") + .execute(); + logger.info("Updated rows: {}", result.getUpdatedRows()); + } catch (IOException e) { + logger.error("Failed to write data to the spreadsheet", e); + throw new CustomException(ErrorCode.WRITE_FAIL); + } catch (GeneralSecurityException e) { + logger.error("Failed to write data to the spreadsheet", e); + throw new CustomException(ErrorCode.INTERNAL_SERVER_ERROR); + } + } + +} diff --git a/src/main/resources/application-credentials.yml b/src/main/resources/application-credentials.yml index b63ae1a..d718107 100644 --- a/src/main/resources/application-credentials.yml +++ b/src/main/resources/application-credentials.yml @@ -19,3 +19,8 @@ jwt: secret: ${JWT_SECRET} access-token-expiration: ${JWT_ACCESS_TOKEN_EXPIRATION} refresh-token-expiration: ${JWT_REFRESH_TOKEN_EXPIRATION} +google: + credentials: + path: ${GOOGLE_CREDENTIALS_PATH} + spreadsheet: + id: ${GOOGLE_SPREADSHEET_ID} \ No newline at end of file