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

개발자·2022년 5월 25일
1
post-custom-banner

서비스 계정으로 구글 사용자의 캘린더에 일정을 추가해보자! 🤗
(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")
post-custom-banner

7개의 댓글

comment-user-thumbnail
2023년 3월 9일

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

1개의 답글
comment-user-thumbnail
2024년 5월 24일

안녕하세요 위의 소스 코드를 똑같이 작성하였고, 도메인 전체 위임도 제대로 했는데 "Service accounts cannot invite attendees without Domain-Wide Delegation of Authority."라는 calendar 도메인에 대한 에러가 콘솔로 나왔어요 "소스 코드에서 credential을 선언하는 부분에 createDelegated("..")를 추가해준 후" 라는 부분은 .createDelegated("서비스 계정 생성한 구글 이메일 주소")가 맞나요?
그렇게 작성했는데도 에러가 나네요 ㅠㅠ

2개의 답글