서비스 계정으로 Google Calendar API 사용하기

개발자·2022년 5월 25일
1

서비스 계정으로 구글 사용자의 캘린더에 일정을 추가해보자! 🤗
(GCP 프로젝트를 생성했다는 전제하에 진행한다.)


서비스 계정 생성

  1. GCP 콘솔에서 IAM 및 관리자-서비스 계정 메뉴를 들어간다.

  1. 서비스 계정 만들기를 클릭해 계정을 생성해준다.
    1) 원하는 계정 ID를 입력한다.

    2) 역할을 추가해준다. 내 경우엔 저 2개만 추가해줘도 원하는 기능을 사용할 수 있었다.

  2. 서비스 계정에 키를 생성해준다.
    1) 생성한 서비스 계정에서 키 관리를 클릭한다.

    2) 키 추가를 클릭해 JSON 유형으로 키를 만들어준다.

    3) 생성된 키가 json 파일로 저장된다. 이 파일을 잘 보관해둔다. 😊



도메인 전체 위임

  1. https://admin.google.com/ 에 접속해 로그인한다.
  2. 보안-API 관리-도메인 전체 위임 관리 메뉴에 접속한다.
  3. API 클라이언트를 새로 추가해 필요한 범위를 설정해준다.
    1) 클라이언트 ID는 위에서 만든 json 키 파일에 있는 client_id를 입력한다.

    2) OAuth 범위는 다음 중 필요한 범위를 선택해 추가해준다.
범위의미
https://www.googleapis.com/auth/calendar캘린더에 대한 읽기/쓰기 액세스
https://www.googleapis.com/auth/calendar.readonly캘린더에 대한 읽기 전용 액세스
https://www.googleapis.com/auth/calendar.events이벤트에 대한 읽기/쓰기 액세스
https://www.googleapis.com/auth/calendar.events.readonly이벤트에 대한 읽기 전용 액세스
https://www.googleapis.com/auth/calendar.settings.readonly설정에 대한 읽기 전용 액세스
https://www.googleapis.com/auth/calendar.addons.execute캘린더 추가 기능으로 실행


구글 캘린더 설정

  1. 일정을 추가할 캘린더의 설정 및 공유 메뉴를 클릭한다.
  1. 위에서 생성한 서비스 계정의 id를 추가해준다. Calendar API를 호출해 일정을 추가해줄 예정이므로 권한을 일정 변경으로 지정해준다.
    +) 참석자 추가를 위해 서비스 계정을 생성한 Google 계정을 같은 권한으로 추가해주어야 한다.

  2. 메뉴 하단의 캘린더 통합-캘린더 ID를 저장해둔다.(소스 코드 작성시 필요)




Calendar API를 실행해 일정 추가하기

  1. pom.xml에 dependency를 추가해준다.
<dependency>
	<groupId>com.google.api-client</groupId>
	<artifactId>google-api-client</artifactId>
	<version>1.32.1</version>				
</dependency>

<!-- https://mvnrepository.com/artifact/com.google.api-client/google-api-client-jackson2 -->
<dependency>
	<groupId>com.google.api-client</groupId>
	<artifactId>google-api-client-jackson2</artifactId>
	<version>1.20.0</version>
</dependency>
		
<!-- https://mvnrepository.com/artifact/com.google.apis/google-api-services-calendar -->
<dependency>
	<groupId>com.google.apis</groupId>
	<artifactId>google-api-services-calendar</artifactId>
	<version>v3-rev411-1.25.0</version>
</dependency>
  1. 하단 소스 코드를 작성해 실행해준다.
public GoogleAPIClient(@Value("생성한 json 키 파일명") String keyFileName) throws IOException, GeneralSecurityException {
		/* 
         * 서비스 계정 인증 
        */
        InputStream keyFile = ResourceUtils.getURL("classpath:" + keyFileName).openStream();
        GoogleCredential credential = GoogleCredential.fromStream(keyFile).createScoped(Arrays.asList(CalendarScopes.CALENDAR)).createDelegated("서비스 계정 생성한 구글 이메일 주소");
        
        NetHttpTransport transport = GoogleNetHttpTransport.newTrustedTransport();
        Calendar service = new Calendar.Builder(transport, JacksonFactory.getDefaultInstance(), credential).setApplicationName("app 이름").build();
	
        String calendarId = "등록할 캘린더 아이디";
      
        /* 
         * 캘린더 일정 생성
        */
        Event event = new Event()
				.setSummary("test") // 일정 이름
				.setDescription("teststst"); // 일정 설명

        DateTime startDateTime = new DateTime("2022-05-18T09:00:00-07:00");
		EventDateTime start = new EventDateTime()
				.setDateTime(startDateTime)
				.setTimeZone("Asia/Seoul");
		event.setStart(start);		
		DateTime endDateTime = new DateTime("2022-05-19T09:00:00-07:00");
		EventDateTime end = new EventDateTime()
				.setDateTime(endDateTime)
				.setTimeZone("Asia/Seoul");
		event.setEnd(end);
        
        //이벤트 참석자 추가
        EventAttendee[] attendees = new EventAttendee[] {
			    new EventAttendee().setEmail("minwest61@gmail.com")
		};
		event.setAttendees(Arrays.asList(attendees));
		
		String[] recurrence = new String[] {"RRULE:FREQ=DAILY;COUNT=1"};
		event.setRecurrence(Arrays.asList(recurrence));

		EventReminder[] reminderOverrides = new EventReminder[] {
		    new EventReminder().setMethod("email").setMinutes(24 * 60),
		    new EventReminder().setMethod("popup").setMinutes(10),
		};
		Event.Reminders reminders = new Event.Reminders()
		    .setUseDefault(false)
		    .setOverrides(Arrays.asList(reminderOverrides));
		event.setReminders(reminders);

		//이벤트 실행
		event = service.events().insert(calendarId, event).execute();
		System.out.printf("Event created: %s\n", event.getHtmlLink());

}

참석자를 추가하는 부분에서 Service accounts cannot invite attendees without Domain-Wide Delegation of Authority 라는 Error가 발생했고 도메인 권한을 위임해줘도 해결되지 않았다. 이를 해결하기 위해 소스 코드에서 credential을 선언하는 부분에 createDelegated("..")를 추가해준 후 캘린더 권한에 해당 메일을 추가해주니 해결되었다.

  1. 일정이 추가된 것을 확인할 수 있다.




Ref.

https://cloud.google.com/docs/authentication/production?hl=ko
https://developers.google.com/calendar/api/guides/auth
https://developers.google.com/calendar/api/v3/reference/events/insert
https://mingpd.github.io/2019/03/12/develop/java-google-api/

profile
log.info("공부 기록 블로9")

4개의 댓글

comment-user-thumbnail
2023년 3월 9일

구글 admin 접속하실 때 그냥 구글 ID로는 안되던데 구글 workspace용 ID가 따로 있으신건가요?

1개의 답글