서비스 계정으로 구글 사용자의 캘린더에 일정을 추가해보자! 🤗
(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/
안녕하세요 위의 소스 코드를 똑같이 작성하였고, 도메인 전체 위임도 제대로 했는데 "Service accounts cannot invite attendees without Domain-Wide Delegation of Authority."라는 calendar 도메인에 대한 에러가 콘솔로 나왔어요 "소스 코드에서 credential을 선언하는 부분에 createDelegated("..")를 추가해준 후" 라는 부분은 .createDelegated("서비스 계정 생성한 구글 이메일 주소")가 맞나요?
그렇게 작성했는데도 에러가 나네요 ㅠㅠ
구글 admin 접속하실 때 그냥 구글 ID로는 안되던데 구글 workspace용 ID가 따로 있으신건가요?