서비스 계정으로 구글 사용자의 캘린더에 일정을 추가해보자! 🤗
(GCP 프로젝트를 생성했다는 전제하에 진행한다.)
IAM 및 관리자-서비스 계정
메뉴를 들어간다.서비스 계정 만들기
를 클릭해 계정을 생성해준다.
1) 원하는 계정 ID를 입력한다.
2) 역할을 추가해준다. 내 경우엔 저 2개만 추가해줘도 원하는 기능을 사용할 수 있었다.
서비스 계정에 키를 생성해준다.
1) 생성한 서비스 계정에서 키 관리를 클릭한다.
2) 키 추가를 클릭해 JSON 유형으로 키를 만들어준다.
3) 생성된 키가 json 파일로 저장된다. 이 파일을 잘 보관해둔다. 😊
보안-API 관리-도메인 전체 위임 관리
메뉴에 접속한다.범위 | 의미 |
---|---|
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 | 캘린더 추가 기능으로 실행 |
설정 및 공유
메뉴를 클릭한다.위에서 생성한 서비스 계정의 id를 추가해준다. Calendar API를 호출해 일정을 추가해줄 예정이므로 권한을 일정 변경
으로 지정해준다.
+) 참석자 추가를 위해 서비스 계정을 생성한 Google 계정을 같은 권한으로 추가해주어야 한다.
메뉴 하단의 캘린더 통합-캘린더 ID
를 저장해둔다.(소스 코드 작성시 필요)
<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>
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("..")
를 추가해준 후 캘린더 권한에 해당 메일을 추가해주니 해결되었다.
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/
구글 admin 접속하실 때 그냥 구글 ID로는 안되던데 구글 workspace용 ID가 따로 있으신건가요?