[Spring] Spring Boot에서 Google Meet API 적용해보기

2024. 10. 6. 22:30·Back-end/Spring
반응형

회의 요약 서비스 플랫폼 프로젝트를 기획 중 Google Meet를 서비스 내에서 구현할 수 있어야 하는 문제가 생겼다...

실제로 써본 적이 없는 API이기 때문에, 사용법 숙지를 위해 테스트 프로젝트를 생성했다.

 

Google Meet은 자체적인 API가 없어서 Google Calendar 이벤트를 생성할 때 Meet 회의를 추가하는 방식으로 URL을 발급받을 수 있다고 한다.

 

흐름

1. Google OAuth2 인증을 통해 구글 계정에 대한 인가 코드를 받는다.

2. 해당 인가 코드를 통해 사용자의 Google Calendar 의 Hangout 타입의 이벤트를 생성한다 (Google Meet) .

3. 해당 Google Meet의 URL을 발급한다.

 

1. Google Cloud Platform 설정

먼저 Google Cloud Platform에서 프로젝트를 설정하고 Google Calendar API를 활성화해야 한다.

  • Google Cloud Console에 로그인하여 새로운 프로젝트를 생성해준다.
  • API 및 서비스 -> 라이브러리로 이동하여 Google Calendar API를 검색한 후 활성화해준다.

  • API 및 서비스 -> 사용자 인증 정보로 이동하여 OAuth 2.0 클라이언트 ID를 생성하기 전에 먼저 동의 화면을 구성해준다.

 

  • User Type은 외부로 설정해주고 생성한다.

 

 

  •  oauth 동의 화면에서 앱 이름과 사용자 지원 이메일을 설정해두고 다음으로 넘어간다.

 

 

  • 범위 화면에서 범위 추가 또는 삭제 버튼을 누른 뒤 등록할 구글 서비스에서 사용할 범위를 선택한다.
    (기본 범위인 email, profile, openid 선택)

 

  • 이렇게 동의 화면을 생성했다면, 이제 사용자 인증 정보 -> 사용자 인증 정보 만들기 -> OAuth 클라이언트 ID 를 통해 생성해준다.

 

  • 스프링 시큐리티에서는 기본적으로{도메인}/login/oauth2/code/{소셜서비스코드}로 Redirect URL을 지원한다.
    따라서 사용자가 리다이렉트 URL에 대한 컨트롤러를 생성해줄 필요가 없다.

 

 

이후 생성해주면 클라이언트 인증 정보를 볼 수 있다.

 

이렇게 만들어둔 Redirect URI, 생성된 Client ID, Client Secret을 Spring boot에 적용해야 한다.

 

2. Spring Boot 설정

- build.gradle 설정

implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'com.google.api-client:google-api-client:2.0.0'
implementation 'com.google.oauth-client:google-oauth-client-jetty:1.34.1'
implementation 'com.google.apis:google-api-services-calendar:v3-rev20220715-2.0.0'

 

google calendar api를 사용하기 위한 라이브러리와, oauth를 사용하기 위한 라이브러리를 추가한다.

 

- application.properties 설정

필자는 yaml 확장자로 변경하여 작성했다.

  • application.yml
spring:
  profiles:
    include: oauth
  • application-oauth.yml
spring:
  security:
    oauth2:
      client:
        registration:
          google:
            client-id: [client-id]
            client-secret: [client-secret-key]
            scope:
              - email
              - profile

 

 

 

 

- Google OAuth 2.0 설정 및 서비스 작성

OAuth 2.0 인증을 처리하고, Google Meet 회의 생성을 위한 Google Calendar API를 사용하는 코드를 작성합니다.

 

package test.googlemeetapi.googlemeet;

import com.google.api.client.auth.oauth2.BearerToken;
import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.googleapis.auth.oauth2.*;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.gson.GsonFactory;
import com.google.api.client.util.DateTime;
import com.google.api.services.calendar.Calendar;
import com.google.api.services.calendar.model.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import test.googlemeetapi.googlemeet.GoogleCalendarService;

import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.Collections;
import java.util.Objects;

@Service
public class DistributeService {

    // 애플리케이션에서 사용하는 Google 클라이언트 ID를 주입받음
    @Value("${spring.security.oauth2.client.registration.google.client-id}")
    private String clientId;

    // 애플리케이션에서 사용하는 Google 클라이언트 시크릿을 주입받음
    @Value("${spring.security.oauth2.client.registration.google.client-secret}")
    private String clientSecret;

    // 애플리케이션 이름 설정
    private static final String APPLICATION_NAME = "Google Calendar API Java Quickstart";

    // JSON 처리에 사용할 JsonFactory 설정 (Gson 사용)
    private static final JsonFactory JSON_FACTORY = GsonFactory.getDefaultInstance();

    // OAuth 클라이언트 파일 경로
    private static final String CREDENTIALS_FILE_PATH = "/credentials.json";

    /**
     * Google OAuth 인증 URL을 생성하는 메서드
     * 사용자에게 인증 URL을 제공하여 Google 계정으로 로그인하고 권한을 부여받음
     * @return Google OAuth 인증 URL
     * @throws Exception 예외 처리
     */
    public String getAuthorizationUrl() throws Exception {
        // credentials.json 파일을 로드하여 Google 클라이언트 비밀 정보를 얻음
        InputStream in = GoogleCalendarService.class.getResourceAsStream(CREDENTIALS_FILE_PATH);
        GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(Objects.requireNonNull(in)));

        // GoogleAuthorizationCodeFlow를 사용하여 OAuth 인증 흐름을 설정
        GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
                GoogleNetHttpTransport.newTrustedTransport(), JSON_FACTORY, clientSecrets, Collections.singletonList("https://www.googleapis.com/auth/calendar"))
                .setAccessType("offline") // 오프라인 접근 권한 설정
                .build();

        // 사용자가 Google 계정으로 인증할 수 있는 URL 생성 및 반환
        return flow.newAuthorizationUrl().setRedirectUri("http://localhost:8888/Callback").build();
    }

    /**
     * OAuth 2.0 인증 코드를 사용하여 Google Meet 이벤트를 생성하는 메서드
     * @param code OAuth 2.0 인증 코드
     * @param summary 이벤트 제목
     * @param description 이벤트 설명
     * @param location 이벤트 위치
     * @param startDateTime 이벤트 시작 시간
     * @param endDateTime 이벤트 종료 시간
     * @param attendeesEmails 참석자 이메일 목록
     * @return 생성된 Google Meet URL
     * @throws Exception 예외 처리
     */
    public String createEventWithCode(String code, String summary, String description, String location, String startDateTime, String endDateTime, String[] attendeesEmails) throws Exception {
        // 인증 코드를 사용하여 액세스 토큰을 얻음
        GoogleTokenResponse tokenResponse = new GoogleAuthorizationCodeTokenRequest(
                new NetHttpTransport(),
                GsonFactory.getDefaultInstance(),
                "https://oauth2.googleapis.com/token",
                clientId,  // Google API Console에서 얻은 클라이언트 ID
                clientSecret,  // Google API Console에서 얻은 클라이언트 시크릿
                code,
                "http://localhost:8888/Callback")  // 리디렉션 URI
                .execute();

        // BearerToken을 사용하여 Credential 객체를 생성하고 액세스 토큰을 설정
        Credential credential = new Credential(BearerToken.authorizationHeaderAccessMethod()).setAccessToken(tokenResponse.getAccessToken());

        // Google Calendar API 서비스 객체를 생성
        Calendar service = new Calendar.Builder(GoogleNetHttpTransport.newTrustedTransport(), JSON_FACTORY, credential)
                .setApplicationName(APPLICATION_NAME)
                .build();

        // 이벤트 객체 생성 및 기본 정보 설정
        Event event = new Event()
                .setSummary(summary) // 이벤트 제목 설정
                .setLocation(location) // 이벤트 위치 설정
                .setDescription(description); // 이벤트 설명 설정

        // 이벤트 시작 시간 설정 (KST 타임존 사용)
        EventDateTime start = new EventDateTime()
                .setDateTime(new DateTime(startDateTime)) // 시작 날짜 및 시간 설정
                .setTimeZone("Asia/Seoul");  // 한국 표준시(KST) 설정
        event.setStart(start);

        // 이벤트 종료 시간 설정 (KST 타임존 사용)
        EventDateTime end = new EventDateTime()
                .setDateTime(new DateTime(endDateTime)) // 종료 날짜 및 시간 설정
                .setTimeZone("Asia/Seoul"); // 한국 표준시(KST) 설정
        event.setEnd(end);

        // 참석자 목록 생성 및 설정
        EventAttendee[] attendees = new EventAttendee[attendeesEmails.length];
        for (int i = 0; i < attendeesEmails.length; i++) {
            attendees[i] = new EventAttendee().setEmail(attendeesEmails[i]); // 각 참석자의 이메일 설정
        }
        event.setAttendees(Arrays.asList(attendees));

        // Google Meet 회의 데이터를 설정
        ConferenceData conferenceData = new ConferenceData();
        ConferenceSolutionKey conferenceSolutionKey = new ConferenceSolutionKey();
        conferenceSolutionKey.setType("hangoutsMeet"); // Google Meet 회의 타입 설정
        CreateConferenceRequest createConferenceRequest = new CreateConferenceRequest();
        createConferenceRequest.setRequestId("some-random-string"); // 유니크한 요청 ID 설정
        createConferenceRequest.setConferenceSolutionKey(conferenceSolutionKey); // 회의 솔루션 키 설정
        conferenceData.setCreateRequest(createConferenceRequest); // 회의 데이터에 요청 설정
        event.setConferenceData(conferenceData); // 이벤트에 회의 데이터 설정

        // Google Calendar API를 통해 이벤트를 삽입하고 생성된 이벤트를 반환
        Event createdEvent = service.events().insert("primary", event)
                .setConferenceDataVersion(1) // 회의 데이터 버전 설정
                .execute(); // 이벤트 생성 요청 실행

        // Google Meet URL을 추출
        ConferenceData createdConferenceData = createdEvent.getConferenceData();
        String googleMeetLink = null;
        if (createdConferenceData != null && createdConferenceData.getEntryPoints() != null) {
            for (EntryPoint entryPoint : createdConferenceData.getEntryPoints()) {
                if ("video".equals(entryPoint.getEntryPointType())) {  // Google Meet 링크인지 확인
                    googleMeetLink = entryPoint.getUri();  // Google Meet URL 추출
                    break;
                }
            }
        }

        // Google Meet URL 반환 (없을 경우 기본 메시지 반환)
        return googleMeetLink != null ? googleMeetLink : "No Google Meet link available";
    }
}

 

1. getAuthorizeURL()

해당 사용자의 구글 Oauth2 인증을 받기 위한 URL을 발급한다.

사용자는 해당 URL에 접속하게 되면, 쿼리 파라미터로 code를 발급받게 된다.   

 

2. createEventWithCode()

위 메서드에서 발급된 code를 파라미터에 담아 실행하면, Google Calendar Event를 생성한다. Hangout 타입으로 생성하게 되면 Google Meet가 생성되는데 해당 화상 회의의 공유 URL을 리턴해주는 로직을 작성했다.

참고

https://developers.google.com/calendar/api/quickstart/java?hl=ko

 

자바 빠른 시작  |  Google Calendar  |  Google for Developers

이 페이지는 Cloud Translation API를 통해 번역되었습니다. 의견 보내기 자바 빠른 시작 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. 빠른 시작에서는 Google Work

developers.google.com

 

반응형

'Back-end > Spring' 카테고리의 다른 글

[Spring] self-hosted Runner를 통한 CI/CD 배포  (0) 2024.11.21
[Spring] @RequestPart vs @RequestParam vs @RequestBody  (1) 2024.10.11
[Spring] JWT + Redis를 활용한 로그아웃 구현 (Jwt BlackList)  (4) 2024.10.06
[Spring] Query Parameter vs Path Variable  (3) 2024.10.02
[Spring] Security + JWT + Redis를 활용한 로그인 구현 (2)  (0) 2024.08.30
'Back-end/Spring' 카테고리의 다른 글
  • [Spring] self-hosted Runner를 통한 CI/CD 배포
  • [Spring] @RequestPart vs @RequestParam vs @RequestBody
  • [Spring] JWT + Redis를 활용한 로그아웃 구현 (Jwt BlackList)
  • [Spring] Query Parameter vs Path Variable
류건
류건
개발 일지
  • 류건
    건's Dev
    류건
  • 전체
    오늘
    어제
    • 분류 전체보기 (96) N
      • Back-end (56) N
        • Spring (31) N
        • Nest.js (3)
        • Next.js (2)
        • Node.js (3)
      • Infra & Cloud (5) N
        • Cloud Computing (6)
        • Docker (3)
        • AWS (7)
      • Java (2)
      • Computer Science (12)
        • Computer Network (0)
        • Operating System (0)
        • 정보 보호와 시스템 보안 (12)
      • 회고록 (1)
        • 우아한테크코스 (3)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    Docker
    오블완
    티스토리챌린지
    db
    어노테이션
    express.js
    고가용성
    CD
    node.js
    Lock
    Webflux
    JPA
    https
    정보보호
    Spring
    보안
    Nest.js
    nginx
    Github Actions
    WebClient
    public key
    CORS
    ssl
    JWT
    CI/CD
    Spring Boot
    EC2
    aws
    Kafka
    ddl-auto
  • 최근 댓글

  • 최근 글

  • 반응형
  • hELLO· Designed By정상우.v4.10.0
류건
[Spring] Spring Boot에서 Google Meet API 적용해보기
상단으로

티스토리툴바