ai-creator

구글 OpenAPI 활용 - 캘린더 (2. 개념 : 함수/데이터 편) 본문

오늘 배워 오늘 쓰는 OpenAPI/프로젝트

구글 OpenAPI 활용 - 캘린더 (2. 개념 : 함수/데이터 편)

ai-creator 2020. 2. 22. 14:02
반응형

앞서 구글 캘린더 API가 제공하는 자원들을 살펴보았습니다. 

참고 : [오늘 배워 오늘 쓰는 OpenAPI] - 구글 API_캘린더 (1. 개념 : 자원편)

 

이번 글에서는 일정 자원을 사용하는

- 함수(Insert, List, Update, Delete)와 조건을 주는 파라미터(calendarId, timeMin 등)

그리고 자원을 표현하는

- 데이터 형식({"summary" : "캘린더 제목"} 등)

을 알아보겠습니다.

 

* 파라미터와 데이터 형식의 차이(예 : 특정 캘린더의 일정을 조회할 때)

용어
파라미터 어떤 캘린더에 있는 일정을 조회할 것인지(calendarId), 그 캘린더의 일정을 몇 개 까지 가져올 것인지(maxResults), 일정을 언제부터 언제까지 조회할 것인지(timeMintimeMax) 등
데이터 형식 요청한 캘린더의 제목({"summary" : "캘린더 제목"}), 요청한 캘린더의 상세 설명({"description" : "캘린더 설명"}), 요청한 캘린더에 등록된 일정들({"items": ...}) 등

 

** 이번 글에서는 일정(Event)을 중심으로 생성(Insert), 조회(List), 수정(Update), 삭제(Delete)하는 것에 대해서 다룰 것입니다. 다른 자원들에 관한 내용은 공식 문서를 참고하세요.

 

<< 목표 >>

  • 일정 생성하기 - Insert 함수, 파라미터, 데이터 형식
  • 일정 조회하기 - List 함수, 파라미터, 데이터 형식
  • 일정 수정하기 - Update 함수, 파라미터, 데이터 형식
  • 일정 삭제하기 - Delete 함수, 파라미터, 데이터 형식

 

<< 사전 준비 >>

OAuth 2.0 클라이언트 ID 인증 파일 - [오늘 배워 오늘 쓰는 OpenAPI] - (완료) 카카오 API 사용하기 - 준비 사항

 

언어 & 환경(IDE) : Python3.6 & Jupter notebook

<< 순서 >>

Step 1

구글 API 인증(Python)

Step 2

일정 생성(Insert)

Step 3

일정 조회(List)

Step 4

일정 수정(Update)

Step 5

일정 삭제(Delete)

 

Step 1) 구글 API 인증(Python)

구글은 API들을 쉽게 사용할 수 있도록 Python 라이브러리를 제공하고 있습니다.

 

Python 라이브러리 설치

pip install --upgrade google-api-python-client google-auth-httplib2 google-auth-oauthlib

 

인증

from google_auth_oauthlib.flow import InstalledAppFlow

# 구글 클라우드 콘솔에서 다운받은 OAuth 2.0 클라이언트 파일경로
creds_filename = 'credentials.json'

# 사용 권한 지정
# https://www.googleapis.com/auth/calendar	               캘린더 읽기/쓰기 권한
# https://www.googleapis.com/auth/calendar.readonly	       캘린더 읽기 권한
SCOPES = ['https://www.googleapis.com/auth/calendar']

# 파일에 담긴 인증 정보로 구글 서버에 인증하기
# 새 창이 열리면서 구글 로그인 및 정보 제공 동의 후 최종 인증이 완료됩니다.
flow = InstalledAppFlow.from_client_secrets_file(creds_filename, SCOPES)
creds = flow.run_local_server(port=0)

OAuth 클라이언트 ID JSON 파일 경로를 지정해주고 코드를 실행하면, 새 창으로 연결되어 로그인과 정보 제공 동의를 요구합니다.

 

해당 과정을 완료하면 마지막으로 창을 닫아도 된다는 메시지가 나옵니다. 그러면, 인증 완료!!

 

서비스 객체 생성

import datetime
# 구글 캘린더 API 서비스 객체 생성
from googleapiclient.discovery import build

today = datetime.date.today().isoformat()
service = build('calendar', 'v3', credentials=creds)

Step1) 일정 생성(Insert)

참고 : https://developers.google.com/calendar/v3/reference/events/insert

Step 1-1) Python 예제

event = {
        'summary': 'itsplay의 OpenAPI 수업', # 일정 제목
        'location': '서울특별시 성북구 정릉동 정릉로 77', # 일정 장소
        'description': 'itsplay와 OpenAPI 수업에 대한 설명입니다.', # 일정 설명
        'start': { # 시작 날짜
            'dateTime': today + 'T09:00:00', 
            'timeZone': 'Asia/Seoul',
        },
        'end': { # 종료 날짜
            'dateTime': today + 'T10:00:00', 
            'timeZone': 'Asia/Seoul',
        },
        'recurrence': [ # 반복 지정
            'RRULE:FREQ=DAILY;COUNT=2' # 일단위; 총 2번 반복
        ],
        'attendees': [ # 참석자
            {'email': 'lpage@example.com'},
            {'email': 'sbrin@example.com'},
        ],
        'reminders': { # 알림 설정
            'useDefault': False,
            'overrides': [
                {'method': 'email', 'minutes': 24 * 60}, # 24 * 60분 = 하루 전 알림
                {'method': 'popup', 'minutes': 10}, # 10분 전 알림
            ],
        },
    }

# calendarId : 캘린더 ID. primary이 기본 값입니다.
event = service.events().insert(calendarId='primary', body=event).execute()
print('Event created: %s' % (event.get('htmlLink')))

예제에서는 "itsplay의 OpenAPI 수업" 이라는 제목과 장소, 설명, 날짜, 반복여부, 알림 등의 정보를 담은 데이터 형식을 가지고 일정을 생성합니다.

 

파라미터로 calendarId를 'primary'로 준 것은 기본 캘린더를 사용하겠다는 뜻입니다. 실행에 문제가 발생하지 않았다면 생성된 일정의 정보를 담은 결과가 반환이 되며, 생성된 일정의 상세 페이지로 이동할 수 있는 링크인 htmlLink를 출력해주고 있습니다.

 

Step 1-2) 파라미터

Insert 함수를 사용할 때, 주요 파라미터는 다음과 같습니다.

이름 설명
필수 파라미터
calendarId 일정을 생성할 캘린더 ID. 기본 값은 'primary'.
선택 파라미터
maxAttendees  응답에 가져올 참석자의 명수
sendUpdates 

새 일정을 생성할 때, 알림에 대한 설정

- all : 모든 참석자에게 알림이 보내집니다.

- externalOnly : 구글 캘린더를 사용하지 않는 참석자에게만 알림이 보내집니다.

- none : 알림을 사용하지 않습니다.


 

나머지 파라미터 보기

 

* 캘린더 ID를 확인하려면 [더보기]를 눌러주세요.

더보기

1. 우측 상단 [설정] 클릭

2. 좌측에서 원하는 캘린더를 선택 후, [캘린더 통합]으로 이동 > [캘린더 ID] 우측에 표시됨을 확인 

 

 

Step 2-2) 생성 요청(request) 시 사용되는 데이터 형식

 

위 코드에서 event에 담긴 JSON 형식의 데이터처럼 일정을 생성할 때 사용하는 주요 데이터를 자세히 살펴보겠습니다.

속성 이름

데이터 타입

설명

쓰기여부

필수 속성들
start nested object 해당 일정의 시작 시간입니다. (x >= start time)  
end nested object 해당 일정의 종료 시간입니다. (x < end time)  
선택 속성들
summary string 일정의 제목을 뜻합니다. writable
location string 위치 정보를 나타냅니다. writable
description string 일정의 설명입니다. HTML을 포함할 수 있습니다. 선택사항 writable
start.dateTime datetime 종일 일정이 아닌 특정 날짜와 시간 값(datetime)을 가진 시작시간을 말합니다. writable
start.timeZone string 시작 시간의 시간대를 뜻합니다. writable
end.dateTime datetime 종일 일정이 아닌 특정 날짜와 시간 값(datetime)을 가진 종료시간을 말합니다. writable
end.timeZone string 종료 시간의 시간대를 뜻합니다. writable
recurrence[] list 일정을 반복할 때 사용하는 규칙입니다. 본 글에서는 RRULE를 사용할 것이며, RFC5545에 정의된 규칙을 따라서 정의하면 됩니다. writable
attendees[]
list 일정 참석자입니다. writable
attendees[].email string 일정 참석자의 이메일 주소입니다. writable
reminders object 인증된 사용자를 위한 일정의 알림에 대한 정보입니다.   
reminders.useDefault
boolean 해당 일정을 소유한 캘린더에 적용된 기본 알림을 사용할지의 여부입니다. writable
reminders.overrides[] list 해당 일정이 기본 알림을 사용하지 않는다면, 이 속성은 해당 일정에 할당된 알림 들을 나열합니다.
writable
reminders.overrides[].method string 알림을 위해 사용되는 방식을 정의합니다. 이메일, SMS, Popup 알림이 있습니다. writable
reminders.overrides[].minutes
integer 해당 일정의 알림이 몇 분 전에 울릴지 설정합니다. 0 ~ 40320 사이로 입력합니다. writable

 

Step 2-3) 생성 응답(response) 시 사용되는 데이터 형식

생성(Insert) 요청을 통해 작업이 성공적으로 수행하게 되면 일정 결과 값을 받게 됩니다.

 

위의 Python 예제를 통해 받게 된 결과 값을 중심으로 각 속성들을 살펴보겠습니다.

{
  "kind": "calendar#event",
  "etag": "3163187849198222",
  "id": "fraof7dh0g0ene8kdcfl3h2222",
  "status": "confirmed",
  "htmlLink": "https://www.google.com/calendar/event?eid=ZnJhb2Y3ZGgwZzBlbmU4a2RjZmwzaGc0cDRfMjAyMDAyMTNUMDAwMDAwWiBpYW1leGFtcGxl2222",
  "created": "2020-02-13T11:38:44.000Z",
  "updated": "2020-02-13T11:38:44.679Z",
  "summary": "itsplay의 OpenAPI 수업",
  "description": "itsplay와 OpenAPI 수업에 대한 설명입니다.",
  "location": "서울특별시 성북구 정릉동 정릉로 77",
  "creator": {
    "email": "example@gmail.com",
    "self": True
  },
  "organizer": {
    "email": "example@gmail.com",
    "self": True
  },
  "start": {
    "dateTime": "2020-02-13T09:00:00+09:00",
    "timeZone": "Asia/Seoul"
  },
  "end": {
    "dateTime": "2020-02-13T10:00:00+09:00",
    "timeZone": "Asia/Seoul"
  },
  "recurrence": [
    "RRULE:FREQ=DAILY;COUNT=2"
  ],
  "iCalUID": "fraof7dh0g0ene8kdcfl3h2222@google.com",
  "sequence": 0,
  "attendees": [
    {
      "email": "sbrin@example.com",
      "responseStatus": "needsAction"
    },
    {
      "email": "lpage@example.com",
      "responseStatus": "needsAction"
    }
  ],
  "reminders": {
    "useDefault": False,
    "overrides": [
      {
        "method": "popup",
        "minutes": 10
      },
      {
        "method": "email",
        "minutes": 1440
      }
    ]
  }
}

 

속성 이름 데이터 타입 설명 쓰기여부
kind string 자원의 유형을 뜻합니다. ("calendar#event")  
etag etag Etag 값. 해당 컨텐츠가 변경됬는지를 판별할 수 있는 값입니다.  
id string 각 캘린더마다 일정을 구분할 수 있는 식별자입니다. writable
status string

해당 일정의 상태입니다. 선택사항.

- "confirmed" : 일정이 확정됨. 기본값

- "tentative" : 일정이 잠정적으로 확정됨.

- "cancelled" : 일정이 취소됨(삭제됨)

writable
htmlLink string 읽기 전용의 구글 캘린더 웹 UI 상 일정에 대한 주소.  
created datetime 일정이 생성된 시각입니다.  
updated datetime 마지막으로 수정된 시각입니다.  
summary string 일정의 제목을 뜻합니다. writable
description string 일정의 설명입니다. HTML을 포함할 수 있습니다. 선택사항 writable
location string 위치 정보를 나타냅니다. writable
creator object 일정을 생성한 사용자입니다. 읽기 전용 writable
creator.email string 일정을 생성한 사용자의 이메일 주소입니다. writable
creator.self boolean 일정을 생성한 사용자가 본인인지의 여부입니다.  
organizer object 일정의 주최자입니다. (생성자와 일정을 주최하는 자는 다를 수 있습니다.) writable
organizer.email string 일정의 주최자의 이메일 주소입니다. writable
organizer.self boolean 일정의 주최자가 본인인지의 여부입니다.  
start nested object 해당 일정의 시작 시간입니다. (x >= start time)  
start.date date 종일 일정일 경우 "yyyy-mm-dd" 형식을 지닌 시작 날짜입니다. writable
start.dateTime datetime 종일 일정이 아닌 특정 날짜와 시간 값(datetime)을 가진 시작 시간을 말합니다. writable
start.timeZone string 시작 시간의 시간대를 뜻합니다. writable
end nested object 해당 일정의 종료 시간입니다. (x < end time)  
end.date date 종일 일정일 경우 "yyyy-mm-dd" 형식을 지닌 종료 날짜입니다. writable
end.dateTime datetime 종일 일정이 아닌 특정 날짜와 시간 값(datetime)을 가진 종료 시간을 말합니다. writable
end.timeZone string 종료 시간의 시간대를 뜻합니다. writable
recurrence[] list 일정을 반복할 때 사용하는 규칙입니다. 본 글에서는 RRULE를 사용할 것이며, RFC5545에 정의된 규칙을 따라서 정의하면 됩니다. writable
iCalUID string RFC5545에 정의된 일정의 고유 식별자입니다. 일정 관리 시스템에서 사용될 수 있습니다. id와는 중복해서 쓸 수 없으며 두 속성의 차이 점은 반복 일정을 생성한 경우 모든 일정은 id값이 다르지만 icalUID 값은 동일합니다.  
sequence integer iCalendar(일정 관리 프로그램들 사이에서 통용되는 스펙)에 따른 순서 번호 입니다. writable
attendees[]
list 일정 참석자입니다. writable
attendees[] .email string 일정 참석자의 이메일 주소입니다. writable
attendees[].responseStatus string

참석자의 응답 상태입니다.

- "needsAction" : 참석자가 초대에 응하지 않은 상태

- "declined" : 참석자가 초대를 거절한 상태

- "tentative" : 참석자가 잠정적으로 초대를 승낙한 상태

- "accepted" : 참석자가 초대를 승낙한 상태

writable
reminders object 인증된 사용자를 위한 일정의 알림에 대한 정보입니다.   
reminders.useDefault
boolean 해당 일정을 소유한 캘린더에 적용된 기본 알림을 사용할지의 여부입니다. writable
reminders.overrides[] list 해당 일정이 기본 알림을 사용하지 않는다면, 이 속성은 해당 일정에 할당된 알림 들을 나열합니다.
writable
reminders.overrides[].method string 알림을 위해 사용되는 방식을 정의합니다. 이메일, SMS, Popup 알림이 있습니다. writable
reminders.overrides[].minutes
integer 해당 일정의 알림이 몇 분 전에 울릴지 설정합니다. 0 ~ 40320 사이로 입력합니다. writable
recurringEventId string 반복 일정의 모든 일정들이 속한 인스턴스 ID 값입니다.  

 

 

Step 3) 일정 조회(List)

참고 : https://developers.google.com/calendar/v3/reference/events/list

Step 3-1) Python 예제 코드

import datetime

calendar_id = 'primary'
today = datetime.date.today().isoformat()
time_min = today + 'T00:00:00+09:00'
time_max = today + 'T23:59:59+09:00'
max_results = 5
is_single_events = True
orderby = 'startTime'

events_result = service.events().list(calendarId = calendar_id,
                                      timeMin = time_min,
                                      timeMax = time_max,
                                      maxResults = max_results,
                                      singleEvents = is_single_events,
                                      orderBy = orderby
                                     ).execute()

Step 3-2) 파라미터

이름 설명
필수 파라미터
calendarId 일정을 생성할 캘린더 ID. 기본 값은 'primary'.
선택 파라미터
timeMin 결과로 요청할 날짜 시작 범위.
timeMax 결과로 요청할 날짜 종료 범위.
maxResults 한 번의 결과에 가져올 최대 일정 수. 기본 값 250
singleEvents

반복 일정을 묶은 하나의 객체로 가져올 것인지 아니면, 각 일정을 단일로 가져올 지 여부. 기본 값 False (단일로 가져옴)

orderBy

결과로 반환된 일정들의 순서 정렬.

- startTime : 시작 날짜/시간으로 정렬(단일 일정만 해당)

- updated : 최근 수정된 날짜로 정렬(오름차순)

나머지 파라미터 보기

 

 

Step 3-3) 조회 요청(request) 시 사용되는 데이터 형식

일정의 조회 요청 시에는 사용되지 않습니다.

 

Step 3-4) 응답(response) 시 사용되는 데이터 형식

일정들을 조회하게 되면, 일정들의 모음(collection)인 해당 캘린더의 정보가 반환됩니다. 그 정보들 중에서 "items" 속성 값으로 일정들이 반환됩니다. event_result.get('items')

Property name Value Description Notes
kind string 모음(collection)의 유형을 뜻합니다. ("calendar#events").  
summary string 캘린더의 제목입니다. 읽기 전용 값입니다.  
description string 캘린더의 설명입니다.  
updated datetime 최종적으로 수정된 시간입니다.  
timeZone string 캘린더의 시간대입니다.  
accessRole string

해당 캘린더의 사용자 접근 권한입니다. 읽기 전용 값입니다.

- "none" : 사용자는 접근할 수 없습니다.

- "freeBusyReader" - 사용자는 약속 있음/없음 정보만 조회할 수 있습니다.

- "reader" : 사용자는 캘린더 조회 권한을 가집니다. 비공개 일정에 대한 상세 내용은 숨겨집니다.

- "writer" :  사용자는 읽기 쓰기 권한을 가집니다. 비공개 일정에 대한 상세 내용이 표출됩니다.

- "owner" : 사용자는 캘린더의 소유 권한(모든 권한)을 가집니다.

 
defaultReminders[] list 인증된 사용자의 캘린더에 설정된 기본 알림입니다. 이 알림들은 override 속성을 부여하지 않은 모든 일정들에 적용됩니다.  
defaultReminders[].method string 캘린더에서 알림을 위해 사용되는 기본 방식을 정의합니다. 이메일, SMS, Popup 알림이 있습니다. writable
defaultReminders[].minutes integer 해당 캘린더의 일정의 알림이 몇 분 전에 울릴지 기본 값을 설정합니다. 0 ~ 40320 사이로 입력합니다. writable
nextPageToken string 결과를 페이징 할 때 사용되는 토큰 값입니다.  
items[] list 캘린더의 모든 일정들의 목록입니다.  

 

Step 4) 일정 수정(Update)

참고 : https://developers.google.com/calendar/v3/reference/events/update

 

Step 4-1) Python 예제

# eventId : 일정을 조회한 후 얻은 id 값을 말합니다.
# 먼저 수정할 일정을 가져옵니다.
# 방법 1 : get 함수를 통해서 가져오기
# eventId = 'fraof7dh0g0ene8kdcfl3hg4p4_20200213T000000Z'
# event = service.events().get(calendarId='primary', eventId=eventId).execute()
# 방법 2 : list 함수에서 반환된 일정 사용하기
event = events_result.get('items')[0]
event_id = event.get('id')

# 원하는 일정의 속성 값을 변경합니다.
event['summary'] = "(수정된)" + event['summary']

# 일정 수정 요청하기
updated_event = service.events().update(calendarId='primary', eventId=event_id, body=event).execute()

updated_event
# 제목이 "(수정된)itsplay의 OpenAPI 수업"로 바뀌었습니다.

Step 4-2) 파라미터

이름 설명
필수 파라미터
calendarId 일정을 생성할 캘린더 ID. 기본 값은 'primary'.
eventId
일정의 고유한 ID 값.
선택 파라미터
sendUpdates 

새 일정을 생성할 때, 알림에 대한 설정

- all : 모든 참석자에게 알림이 보내집니다.

- externalOnly : 구글 캘린더를 사용하지 않는 참석자에게만 알림이 보내집니다.

- none : 알림을 사용하지 않습니다.


Step 4-3) 요청(request) 시 사용되는 데이터

Step 2. 일정 생성(Insert)에서 사용된 데이터 형식과 동일합니다.

Step 4-4) 응답(response) 시 사용되는 데이터

Step 2. 일정 생성(Insert)에서 사용된 파라미터와 동일합니다.

 

위 Python 예제의 결과로 나온 값을 보시면 "updated"와 "summary" 값이 바뀐 것을 확인할 수 있습니다.

{
  "kind": "calendar#event",
  "etag": "3163191126892222",
  "id": "fraof7dh0g0ene8kdcfl3hg4p4_20200213T0002222",
  "status": "confirmed",
  "htmlLink": "https://www.google.com/calendar/event?eid=ZnJhb2Y3ZGgwZzBlbm2222RjZmwzaGc0cDRfMjAyMDAyMTNUMDAwMDAwWiBpYW1leGFtcGxlMkBt",
  "created": "2020-02-13T11:38:44.000Z",
  "updated": "2020-02-13T12:06:03.526Z",
  "summary": "(수정된)itsplay의 OpenAPI 수업",
  "description": "itsplay와 OpenAPI 수업에 대한 설명입니다.",
  "location": "서울특별시 성북구 정릉동 정릉로 77",
  "creator": {
    "email": "example@gmail.com",
    "self": True
  },
  "organizer": {
    "email": "example@gmail.com",
    "self": True
  },
  "start": {
    "dateTime": "2020-02-13T09:00:00+09:00",
    "timeZone": "Asia/Seoul"
  },
  "end": {
    "dateTime": "2020-02-13T10:00:00+09:00",
    "timeZone": "Asia/Seoul"
  },
  "recurringEventId": "fraof7dh0g0ene8kdcfl3hg4p4",
  "originalStartTime": {
    "dateTime": "2020-02-13T09:00:00+09:00",
    "timeZone": "Asia/Seoul"
  },
  "iCalUID": "fraof7dh0g0ene8kdcfl3h2222@google.com",
  "sequence": 0,
  "attendees": [
    {
      "email": "lpage@example.com",
      "responseStatus": "needsAction"
    },
    {
      "email": "sbrin@example.com",
      "responseStatus": "needsAction"
    }
  ],
  "reminders": {
    "useDefault": False,
    "overrides": [
      {
        "method": "email",
        "minutes": 1440
      },
      {
        "method": "popup",
        "minutes": 10
      }
    ]
  }
}

Step 5) 일정 삭제(Delete)

Step 5-1) Python 예제

# 위에서 수정된 일정
updated_event

# eventId : 일정을 조회한 후 얻은 id 값을 말합니다.
eventId = updated_event.get('id')
service.events().delete(calendarId='primary', eventId=eventId).execute()

Step 5-2) 파라미터

Step 4. 일정 수정(Update)에서 사용된 파라미터와 동일합니다.

Step 5-3) 요청(request) 시 사용되는 데이터

요청에 사용되는 속성은 없습니다.

Step 5-4) 응답(response) 시 사용되는 데이터

삭제 요청이 성공적으로 처리되었다면 값을 반환하지 않습니다.

 

 

이것으로 일정을 다루는 4가지의 기본 함수에 대해서 모두 살펴보았습니다.

 

 

<< trouble shooting >>

# 아래 함수 수행시 에러 발생시

events_result = service.events().list(calendarId = calendar_id,
                                      timeMin = time_min,
                                      timeMax = time_max,
                                      maxResults = max_results,
                                      singleEvents = is_single_events,
                                      orderBy = orderby).execute()

 

에러에 주어진 링크를 클릭하여, api 활성화를 시켜준다.

 

 


저작물의 저작권은 작성자에게 있습니다.

공유는 자유롭게 하시되 댓글 남겨주세요~

상업적 용도로는 무단 사용을 금지합니다.

끝까지 읽어주셔서 감사합니다^^

반응형
Comments