1. 소개
수십억 개의 비즈니스와 개인이 Gmail 및 기타 G Suite 서비스를 사용하여 커뮤니케이션하고 데이터를 처리합니다. Google에서는 이러한 서비스의 정보에 프로그래매틱 방식으로 액세스할 수 있도록 G Suite API를 제공하며, API를 사용하여 일상 워크플로를 쉽게 자동화할 수 있습니다. 이 실습에서는 수신 메일의 이메일을 자동으로 분류하고 이러한 카테고리를 Google 시트에 저장하는 강력한 Gmail 확장 프로그램을 빌드합니다. 이 확장 프로그램은 G Suite의 RESTful API, Google Cloud Functions, 기타 Google Cloud Platform 서비스를 사용합니다.
빌드 대상
이 실습에서는 G Suite API 및 기타 Google Cloud Platform 서비스에 연결된 몇 가지 Cloud Functions를 빌드하고 배포합니다. 이러한 함수는 다음을 수행합니다.
- Gmail 및 Google Sheets 데이터에 대한 보안 액세스 승인
- 수신 메일에 첨부된 이미지 추출
- Cloud Vision API를 사용하여 이미지를 분류합니다.
- 이러한 카테고리, 발신자 주소, 첨부파일 이름을 Google 시트에 작성합니다.
학습할 내용
- G Suite RESTful API 기본사항
- Google Cloud Functions 및 기타 Google Cloud Platform 서비스의 기본사항
- Google Cloud Functions를 사용하여 프로그래매틱 방식으로 Gmail에 액세스하는 방법
필요한 항목
- Gmail 및 Google Sheets 액세스 권한이 있는 Google 계정 계정이 없다면 여기에서 만드세요.
- JavaScript/Node.js에 관한 기본 지식
2. 먼저 할 일
API 사용 설정
이 실습에서는 다음 Google 제품/서비스를 사용합니다.
- Google Cloud Functions
- Google Cloud Pub/Sub
- Google Cloud Vision API
- Google Cloud Datastore
- Gmail API
- Google Sheets API
Google Cloud Functions
Google Cloud Functions는 간단하고 확장 가능한 방식으로 개별 코드 스니펫('함수')을 실행할 수 있는 Google의 서버리스 서비스로서의 기능 플랫폼입니다.
Google Cloud Functions를 사용 설정하려면 화면 왼쪽 상단의 햄버거 메뉴를 클릭하여 왼쪽 탐색 사이드바를 엽니다.

탐색 메뉴에서 Cloud Functions를 찾아 클릭합니다. API 사용 설정을 클릭하여 프로젝트에서 Google Cloud Functions를 사용 설정합니다.
Google Cloud Pub/Sub
Google Cloud Pub/Sub는 데이터 스트리밍 및 이벤트 전송을 위한 간단하고 확장 가능한 기반입니다. 이 실습에서는 Gmail과 Google Cloud Functions 간의 택배 역할을 합니다.
Google Cloud Pub/Sub를 사용 설정하려면 왼쪽 탐색 메뉴를 열고 Pub/Sub를 찾아 클릭합니다. API 사용 설정을 클릭하여 프로젝트에서 Google Cloud Pub/Sub를 사용 설정합니다.
Google Cloud Datastore
Google Cloud Datastore는 확장 가능하고 분산된 서버리스 데이터베이스입니다.
Google Cloud Datastore를 사용 설정하려면 왼쪽 탐색 사이드바에서 Datastore를 찾아 클릭합니다. 새 페이지에서 Datastore 모드 선택을 클릭합니다.

이 실습에서는 데이터베이스 위치를 자유롭게 선택할 수 있습니다. 데이터베이스 만들기를 클릭하여 Google Cloud Datastore를 사용 설정합니다. 이 작업은 몇 분 정도 걸릴 수 있습니다.
Google Cloud Vision
Google Cloud Vision API는 사전 학습된 모델을 사용하여 이미지에서 유용한 정보를 도출하는 강력한 머신러닝 서비스입니다.
Google Cloud Vision API를 사용 설정하는 방법은 아래 안내를 참고하세요.
Gmail API, Google Sheets API, Google Cloud Vision API 사용 설정
다시 왼쪽 탐색 사이드바를 열고 API 및 서비스를 찾습니다. 라이브러리를 클릭합니다. API 및 서비스 검색 필드에 Gmail을 입력합니다. 검색 결과에서 Gmail API를 선택하고 사용 설정을 클릭합니다.
API 라이브러리 페이지로 돌아갑니다. Google Sheets API를 검색하고 사용 설정합니다.
위 과정 반복. Cloud Vision API를 검색하고 사용 설정합니다.
Google Cloud Shell 열기
이 실습에서는 Google Cloud Shell을 사용하여 대부분의 작업을 수행합니다. Cloud Shell을 사용하면 브라우저에서 직접 Google Cloud Platform 리소스에 명령줄로 액세스하여 로컬 머신을 사용하지 않고도 리소스를 관리할 수 있습니다.
Google Cloud Shell을 열려면 상단의 파란색 가로 막대에서 Cloud Shell 활성화 버튼을 클릭합니다.

화면 하단에 새 패널이 표시됩니다.

코드 편집기 실행 버튼을 클릭하여 Cloud Shell 코드 편집기를 시작합니다.

Cloud Shell 코드 편집기가 새 창에서 열립니다.
코드 다운로드
Cloud Shell에서 아래 명령어를 실행하여 프로젝트를 클론합니다.
git clone https://github.com/googlecodelabs/gcf-gmail-codelab.git cd gcf-gmail-codelab
Cloud Shell 코드 편집기에 gcf-gmail-codelab라는 새 폴더가 표시됩니다.
3. 아키텍처 개요
이 실습의 워크플로는 다음과 같습니다.

- 사용자가 Gmail 푸시 알림을 설정합니다. 받은편지함에 새 메시지가 도착할 때마다 Gmail에서 Cloud Pub/Sub에 알림을 보냅니다.
- Cloud Pub/Sub가 새 메시지 알림을 Google Cloud Functions에 전달합니다.
- 새 메일 알림이 도착하면 Cloud Functions 인스턴스가 Gmail에 연결하여 새 메일을 가져옵니다.
- 메일에 이미지가 첨부파일로 있는 경우 Cloud Functions 인스턴스는 Cloud Vision API를 호출하여 첨부파일을 분석합니다.
- Cloud Functions 인스턴스는 선택한 Google Sheets를 업데이트하여 메시지를 보낸 사람과 첨부파일을 다운로드할 위치를 지정합니다.
4. Gmail 액세스 승인
이메일을 자동으로 읽도록 Cloud 함수를 설정하려면 먼저 Gmail에 대한 액세스를 승인해야 합니다. Google에 OAuth 클라이언트를 등록하고 연결된 클라이언트 ID를 만들어야 합니다.
OAuth 클라이언트 등록
Google Cloud 콘솔의 왼쪽 탐색 메뉴에서 API 및 서비스를 찾습니다. OAuth 동의 화면을 클릭합니다.

애플리케이션 이름 필드에 이름을 입력합니다(예: GCF + Gmail Codelab). 다른 설정은 그대로 두고 페이지를 아래로 스크롤하여 저장을 클릭합니다.
연결된 클라이언트 ID 만들기
사용자 인증 정보 탭으로 전환합니다. 사용자 인증 정보 만들기를 클릭하고 OAuth 클라이언트 ID를 선택합니다. 웹 애플리케이션 유형을 선택하고 이름을 지정한 후 (여기서도 GCF + Gmail Codelab을 사용할 수 있음) 만들기를 클릭합니다. 지금은 제한 필드를 비워 둡니다.
팝업 창에 반환된 클라이언트 ID와 클라이언트 보안 비밀번호를 적어 둡니다. 페이지에서 클라이언트 이름을 클릭하여 다음 값을 다시 볼 수 있습니다.

승인 프로세스 실행
샘플 코드에서 auth/index.js는 방금 만든 클라이언트 ID와 클라이언트 보안 비밀을 사용하여 승인 프로세스를 실행하기 위해 함께 작동하는 두 개의 Cloud Functions(auth_init 및 auth_callback)를 지정합니다.
코드를 검사하려면 Cloud Shell 코드 편집기에서 auth/index.js를 엽니다.
인증 프로세스는 액세스 토큰과 갱신 토큰이라는 두 가지 유형의 토큰을 반환합니다.
- 액세스 토큰은 이를 소유한 사용자에게 데이터에 대한 범위가 지정된 액세스 권한을 부여하는 단기 ID 증명입니다.
auth_callback는 이를 Cloud Datastore에 저장합니다. - 갱신 토큰은 새 액세스 토큰을 획득하는 데 사용되며 수명이 훨씬 깁니다.
일반적으로 암호화되거나 액세스 토큰과 별도로 저장됩니다.
Cloud Shell 코드 편집기에서 auth/env_vars.yaml를 수정합니다. YOUR-GOOGLE-CLIENT-ID 및 YOUR-GOOGLE-CLIENT-SECRET를 각자 자신의 값으로 바꿉니다. 자세한 내용은 이전 단계를 참고하세요. 지금은 YOUR-GOOGLE-CLIENT-CALLBACK-URL 및 YOUR-PUBSUB-TOPIC 값을 변경하지 않습니다.

auth/env_vars.yaml를 수정한 후 Cloud Shell에서 다음 명령어를 실행하여 Cloud 함수를 배포합니다.
cd ~ cd gcf-gmail-codelab/auth # Deploy Cloud Function auth_init gcloud functions deploy auth_init --runtime=nodejs8 --trigger-http --env-vars-file=env_vars.yaml # Deploy Cloud Function auth_callback gcloud functions deploy auth_callback --runtime=nodejs8 --trigger-http --env-vars-file=env_vars.yaml
Cloud Functions를 배포하는 데 몇 분 정도 걸릴 수 있습니다. 메시지가 표시되면 Cloud SDK에 베타 명령어를 설치할 권한을 부여합니다.
다음으로 Google Cloud 콘솔로 이동하여 왼쪽 탐색 메뉴에서 Cloud Functions를 클릭합니다. Cloud Functions 목록에서 auth_callback를 클릭하고 트리거 탭으로 전환합니다.


페이지의 URL을 복사합니다. Cloud Functions 페이지로 돌아가서 Cloud Functions 목록에서 auth_init를 클릭합니다. 일반 탭에서 수정을 클릭합니다. 환경 변수, 네트워킹, 제한 시간 등을 클릭하고 GOOGLE_CALLBACK_URL 값을 방금 복사한 URL로 바꿉니다.

배포를 클릭하여 변경사항을 적용합니다. 이 과정을 반복하여 auth_callback도 업데이트합니다.
마지막으로 왼쪽 탐색 메뉴를 열고 API 및 서비스 > 도메인 확인을 클릭합니다. 승인된 도메인을 추가하려면 도메인 추가를 클릭합니다. 예를 들어 이전에 복사한 URL이 다음과 같은 경우
https://us-central1-my-project.cloudfunctions.net/auth_callback
다음 도메인을 승인된 도메인으로 추가해야 합니다.
us-central1-my-project.cloudfunctions.net
도메인 추가를 눌러 확인합니다.

사용자 인증 정보 페이지로 돌아갑니다. OAuth 클라이언트의 이름을 클릭하고 복사한 URL을 승인된 리디렉션 URI로 추가합니다. Enter를 눌러 확인합니다.
URL에서 /auth_callback 부분을 삭제하고 나머지를 승인된 JavaScript 출처로 추가합니다. 예를 들어 URL이 다음과 같은 경우
https://us-central1-my-project.cloudfunctions.net/auth_callback
다음과 같이 출처를 추가해야 합니다.
https://us-central1-my-project.cloudfunctions.net/

Enter를 눌러 확인하고 저장을 클릭하여 변경사항을 적용합니다.
5. Gmail 푸시 알림 설정하기
인증 프로세스가 성공하면 auth_callback에서 Gmail API를 자동으로 호출하여 푸시 알림을 설정합니다.
Gmail 푸시 알림을 받으려면 Pub/Sub 주제를 만들어야 합니다. 주제를 구독하는 모든 사용자는 Gmail에서 도착하는 수신 메일 알림을 자동으로 수신합니다.
Pub/Sub 주제를 만들려면 Google Cloud 콘솔로 이동하여 왼쪽 탐색 메뉴에서 Pub/Sub > 주제를 클릭합니다. 주제 만들기를 클릭합니다. 주제 이름(예: gmail-watch)을 입력하고 만들기를 클릭합니다. 또한 Gmail에 Pub/Sub 주제로 메시지를 보낼 수 있는 권한을 부여해야 합니다. 방금 만든 주제의 컨텍스트 메뉴 (세 개의 세로 점)를 클릭하고 권한을 선택한 다음 구성원 추가를 클릭하고 gmail-api-push@system.gserviceaccount.com를 새 구성원으로 지정하고 Pub/Sub > Pub/Sub 게시자 역할을 부여합니다. 마지막으로 저장을 클릭하여 변경사항을 적용합니다.
사용할 Pub/Sub 주제를 지정하도록 Cloud 함수 auth_callback를 업데이트합니다. 왼쪽 탐색 메뉴에서 Cloud Functions를 클릭하고 Cloud Functions 목록에서 auth_callback를 선택합니다. 일반 탭에서 수정을 클릭합니다. 더보기를 클릭하고 PUBSUB_TOPIC 값을 방금 만든 Pub/Sub 주제의 이름으로 바꿉니다. 저장을 클릭하여 변경사항을 적용합니다.
이제 Gmail 푸시 알림을 승인하고 설정할 수 있습니다. 새 변경사항이 완료될 때까지 기다린 다음 Cloud Functions 페이지로 돌아가 Cloud Functions 목록에서 auth_init를 선택하고 트리거 탭으로 전환합니다. URL을 클릭하면 Google 계정으로 로그인 페이지로 리디렉션됩니다.

내가 소유한 Gmail 계정으로 로그인합니다. 계정의 받은편지함에 도착하는 새 메일은 푸시 알림을 트리거합니다. 로그인하면 아래 페이지가 표시됩니다.

허용을 클릭하여 액세스를 승인합니다. auth_callback가 승인 절차를 완료하고 액세스 토큰을 저장하며 Gmail 푸시 알림을 설정합니다. 이 프로세스가 완료되면 브라우저에 Successfully set up Gmail push notifications 메시지가 표시됩니다.
이 Codelab에서는 @google-cloud/express-oauth2-handlers 패키지를 사용하여 승인 워크플로를 자동화합니다. 자세한 내용은 GitHub의 저장소를 참고하세요.
6. 수신 메시지 처리
앞서 언급한 바와 같이, 생성한 Pub/Sub 주제의 구독자는 받은편지함에 새 메시지가 도착하면 알림을 받게 됩니다. pubsub/index.js는 주제의 구독자로 배포되면 새 메시지를 읽고, 첨부된 이미지를 분류하고, 이러한 카테고리를 Google Sheets로 내보내는 Cloud 함수 watchGmailMessages를 지정합니다.
코드를 검사하려면 Cloud Shell 코드 편집기에서 pubsub/index.js를 엽니다.
메일 가져오기
Gmail 푸시 알림에는 알림과 연결된 이메일 주소와 기록 ID가 포함됩니다. 간단한 설명을 위해 이 Codelab에서는 푸시 알림이 도착할 때 Gmail API에 최신 메시지를 요청합니다. 더 나은 결과를 얻으려면 히스토리 ID를 사용하여 메시지를 조회하세요.
// Look up the most recent message.
const listMessagesRes = await gmail.users.messages.list({
userId: email,
maxResults: 1
});
const messageId = listMessagesRes.messages[0].id;
// Get the message using the message ID.
const message = await gmail.users.messages.get({
userId: email,
id: messageId
});
return message;
이미지 첨부파일 분석
메일에 이미지 첨부파일이 있으면 watchGmailMessages가 Cloud Vision API를 호출하여 이미지에 주석을 추가합니다. 이 Codelab에서는 Cloud Vision API에 이미지를 분류하고 여러 이미지 태그를 반환하도록 요청합니다. 예를 들어 파란 하늘 이미지를 제공하면 Cloud Vision API는 파란색, 하늘, 자연 태그를 반환할 수 있습니다.
watchGmailMessages는 Node.js용 Cloud Vision API 라이브러리를 사용하여 Cloud Vision API를 호출합니다.
// Tag the attachment using Cloud Vision API
const analyzeAttachment = async (data, filename) => {
var topLabels = ['', '', ''];
if (filename.endsWith('.png') || filename.endsWith('.jpg')) {
const [analysis] = await visionClient.labelDetection({
image: {
content: Buffer.from(data, 'base64')
}
});
const labels = analysis.labelAnnotations;
topLabels = labels.map(x => x.description).slice(0, 3);
}
return topLabels;
};
Google 시트 업데이트
watchGmailMessages 이 분석 결과를 Google 시트로 내보냅니다. 여기에는 발신자 이름, 첨부파일 이름, 이미지 첨부파일 태그 (있는 경우)가 포함됩니다.
먼저 Google 시트를 만듭니다. Google Sheets를 열고 새 스프레드시트 시작하기 아래의 비어 있음 템플릿을 클릭합니다. 시트의 ID를 복사합니다. 예를 들어 브라우저의 주소가 다음과 같은 경우
https://docs.google.com/spreadsheets/d/abcdefghij01234567890/edit#gid=0
스프레드시트의 ID는 abcdefghij01234567890입니다. Cloud Shell 코드 편집기에서 gcf-gmail-codelab/pubsub/env_vars.yaml를 업데이트하고 YOUR-GOOGLE-SHEET-ID를 자체 값으로 바꿉니다.
watchGmailMessages는 Google Sheets API와 연결하여 정보를 추가합니다.
const updateReferenceSheet = async (from, filename, topLabels) => {
await googleSheets.spreadsheets.values.append({
spreadsheetId: SHEET,
range: SHEET_RANGE,
valueInputOption: 'USER_ENTERED',
requestBody: {
range: SHEET_RANGE,
majorDimension: 'ROWS',
values: [
[from, filename].concat(topLabels)
]
}
});
};
마지막 단계
Cloud Shell 코드 편집기에서 gcf-gmail-codelab/pubsub/env_vars.yaml을 열고 YOUR-GOOGLE-CLIENT-ID, YOUR-GOOGLE-CLIENT-SECRET, YOUR-GOOGLE-CALLBACK-URL을 자체 값으로 바꿉니다. 이러한 값은 Google Cloud 콘솔에서 확인할 수 있습니다. 왼쪽 탐색 메뉴에서 Cloud Functions를 열고 Cloud Functions 목록에서 auth_init를 선택한 후 환경 변수 섹션을 확인합니다.
코드 배포
아래 명령어를 실행하여 Cloud 함수를 배포합니다.
cd ~ cd gcf-gmail-codelab/pubsub gcloud functions deploy watchGmailMessages --runtime=nodejs8 --trigger-topic=gmail-watch --env-vars-file=env_vars.yaml
Cloud Pub/Sub 주제 이름을 gmail-watch이 아닌 다른 이름으로 지정한 경우 위의 명령어에서 gmail-watch을 주제 이름으로 바꿉니다. Cloud 함수를 배포하는 데 몇 초 정도 걸릴 수 있습니다.
7. 사용해 보기
축하합니다. 모든 단계를 마쳤습니다. 이미지 첨부파일이 포함된 이메일을 자신에게 보냅니다. 몇 초 후 생성한 Google Sheets가 제공한 정보로 자동 업데이트됩니다.