Google Cloud Functions로 Gmail 받은편지함 강화하기

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 계정 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를 사용 설정하려면 화면 왼쪽 상단의 햄버거 메뉴를 클릭하여 왼쪽 탐색 사이드바를 엽니다.

f457988e33594bb6.png

탐색 메뉴에서 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 모드 선택을 클릭합니다.

98012c91fd4080d4.png

이 실습에서는 모든 데이터베이스 위치를 사용할 수 있습니다. 데이터베이스 만들기를 클릭하여 Google Cloud Datastore를 사용 설정합니다. 완료되는 데 몇 분 정도 걸릴 수 있습니다.

Google Cloud Vision

Google Cloud Vision API는 선행 학습된 모델을 사용하여 이미지에서 유용한 정보를 도출하는 강력한 머신러닝 서비스입니다.

Google Cloud Vision API를 사용 설정하는 방법에 대한 자세한 내용은 아래 안내를 참조하세요.

Gmail API, Google Sheets API, Google Cloud Vision API 사용 설정

다시 왼쪽 탐색 사이드바를 열고 API 및 '서비스'로 이동합니다. 라이브러리를 클릭합니다. Search for APIs & 서비스 입력란에 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 활성화 버튼을 클릭합니다.

fd5c2925ca9cdfdd.png

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

34f498402e910802.png

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

10f8631ef48bed22.png

Cloud Shell 코드 편집기가 새 창에서 열립니다.

코드 다운로드

Cloud Shell에서 아래 명령어를 실행하여 프로젝트를 클론합니다.

git clone https://github.com/googlecodelabs/gcf-gmail-codelab.git

cd gcf-gmail-codelab

Cloud Shell 코드 편집기에 새 폴더 gcf-gmail-codelab이 표시됩니다.

3. 아키텍처 개요

이 실습의 워크플로는 다음과 같습니다.

79c5d3e43f674b33.png

  1. 사용자가 Gmail 푸시 알림을 설정합니다. 새 메일이 받은편지함에 도착할 때마다 Gmail에서 Cloud Pub/Sub에 알림을 전송합니다.
  2. Cloud Pub/Sub가 새 메시지 알림을 Google Cloud Functions에 전송합니다.
  3. 새 메일 알림이 도착하면 Cloud Functions 인스턴스가 Gmail에 연결하여 새 메일을 검색합니다.
  4. 메일에 첨부파일로 이미지가 있는 경우 Cloud Functions 인스턴스는 Cloud Vision API를 호출하여 첨부파일을 분석합니다.
  5. Cloud Functions 인스턴스는 선택한 Google 시트를 업데이트하여 메시지를 보내는 사람과 첨부파일을 다운로드할 위치를 지정합니다.

4. Gmail에 대한 액세스 승인

이메일을 자동으로 읽도록 Cloud 함수를 설정하기 전에 Gmail에 대한 액세스를 승인해야 합니다. Google에 OAuth 클라이언트를 등록하고 연결된 클라이언트 ID를 만들어야 합니다.

OAuth 클라이언트 등록

Google Cloud 콘솔의 왼쪽 탐색 메뉴에서 API 및 '서비스'로 이동합니다. OAuth 동의 화면을 클릭합니다.

91b2a3bac30bb2c5.png

Application name 입력란에 이름을 입력합니다(예: GCF + Gmail Codelab). 다른 설정은 그대로 두고 페이지를 아래로 스크롤하여 저장을 클릭합니다.

연결된 클라이언트 ID 만들기

사용자 인증 정보 탭으로 전환합니다. 사용자 인증 정보 만들기를 클릭하고 OAuth 클라이언트 ID를 선택합니다. 웹 애플리케이션 유형을 선택하고 이름을 지정한 다음 (여기에서 다시 GCF + Gmail Codelab을 사용할 수도 있음) 만들기를 클릭합니다. 지금은 제한 필드를 비워둡니다.

팝업 창에 반환된 클라이언트 ID와 클라이언트 비밀번호를 기록해 둡니다. 페이지에서 고객 이름을 클릭하면 이러한 값을 다시 볼 수 있습니다.

1160d8027ea52d90.png

승인 프로세스 실행

샘플 코드에서 auth/index.js는 방금 만든 클라이언트 ID와 클라이언트 보안 비밀번호를 사용하여 함께 작동하여 승인 프로세스를 수행하는 두 가지 Cloud Functions, auth_initauth_callback를 지정합니다.

코드를 검사하려면 Cloud Shell 코드 편집기에서 auth/index.js를 엽니다.

승인 과정에서 액세스 토큰갱신 토큰이라는 두 가지 유형의 토큰이 반환됩니다.

  • 액세스 토큰은 단기적인 신원 증명으로, 이 토큰을 가진 사람이라면 누구나 자신의 데이터에 대해 범위가 지정된 액세스 권한을 부여할 수 있습니다. auth_callback는 이를 Cloud Datastore에 저장합니다.
  • 갱신 토큰은 새 액세스 토큰을 가져오는 데 사용되며 수명이 매우 깁니다.

일반적으로 토큰은 암호화되거나 액세스 토큰과 별도로 저장됩니다.

Cloud Shell 코드 편집기에서 auth/env_vars.yaml을 수정합니다. YOUR-GOOGLE-CLIENT-IDYOUR-GOOGLE-CLIENT-SECRET를 각자의 값으로 바꿉니다. 자세한 내용은 이전 단계를 참조하세요. 지금은 YOUR-GOOGLE-CLIENT-CALLBACK-URLYOUR-PUBSUB-TOPIC 값을 변경하지 않고 그대로 둡니다.

a2b4853c39a78bc6.png

auth/env_vars.yaml를 수정한 후 Cloud Shell에서 다음 명령어를 실행하여 Cloud Functions를 배포합니다.

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를 클릭하고 트리거 탭으로 전환합니다.

cb094bd341f9b299.png

45678a327c80e0f1.png

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

939ca3bd38047282.png

배포를 클릭하여 변경사항을 적용합니다. 이 프로세스를 반복하고 auth_callback도 업데이트합니다.

마지막으로 왼쪽 탐색 메뉴를 열고 API 및 서비스 > 도메인 확인. 승인된 도메인을 추가하려면 도메인 추가를 클릭합니다. 예를 들어 앞서 복사한 URL이

https://us-central1-my-project.cloudfunctions.net/auth_callback

다음을 승인된 도메인으로 추가해야 합니다.

us-central1-my-project.cloudfunctions.net

도메인 추가를 눌러 확인합니다.

4348748f232ceb87.png

사용자 인증 정보 페이지로 돌아갑니다. 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/

159bad719432582c.png

Enter 키를 눌러 확인하고 저장을 클릭하여 변경사항을 적용합니다.

5. Gmail 푸시 알림 설정

승인 프로세스에 성공하면 auth_callback에서 자동으로 Gmail API를 호출하여 푸시 알림을 설정합니다.

Gmail 푸시 알림을 받으려면 Pub/Sub 주제를 만들어야 합니다. 해당 주제의 구독자는 Gmail에서 수신되는 메시지 알림을 자동으로 받게 됩니다.

Pub/Sub 주제를 만들려면 Google Cloud 콘솔로 이동하여 Pub/Sub > 주제를 클릭합니다. 주제 만들기를 클릭합니다. 주제 이름(예: gmail-watch)을 입력하고 만들기를 클릭합니다. 또한 Pub/Sub 주제에 메시지를 보낼 수 있는 권한을 Gmail에 부여해야 합니다. 방금 만든 주제의 컨텍스트 메뉴 (세로로 놓인 점 3개)를 클릭하고 권한을 선택합니다. 구성원 추가를 클릭하고 gmail-api-push@system.gserviceaccount.com을 새 구성원으로 지정한 후 Pub/Sub > Pub/Sub 게시자 마지막으로 저장을 클릭하여 변경사항을 적용합니다.

Cloud 함수 auth_callback를 업데이트하여 사용할 Pub/Sub 주제를 지정합니다. 왼쪽 탐색 메뉴에서 Cloud Functions를 클릭하고 Cloud Functions 목록에서 auth_callback를 선택합니다. 일반 탭에서 수정을 클릭합니다. 더보기를 클릭하고 PUBSUB_TOPIC 값을 방금 만든 Pub/Sub 주제의 이름으로 바꿉니다. 저장을 클릭하여 변경사항을 적용합니다.

이제 Gmail 푸시 알림을 승인하고 설정할 준비가 되었습니다. 새 변경사항이 완료될 때까지 기다린 다음 Cloud Functions 페이지로 돌아가서 Cloud Functions 목록에서 auth_init를 선택한 후 트리거 탭으로 전환합니다. URL을 클릭하면 Google 계정으로 로그인 페이지로 리디렉션됩니다.

348ab0a7e0c9cd03.png

소유한 Gmail 계정으로 로그인합니다. 계정의 받은편지함에 새 메일이 도착하면 푸시 알림이 실행됩니다. 로그인하면 아래와 같은 페이지가 표시됩니다.

cfdad62fd02de004.png

허용을 클릭하여 액세스를 승인합니다. auth_callback에서 승인 절차를 완료하고, 액세스 토큰을 저장하고, Gmail 푸시 알림을 설정합니다. 이 프로세스가 완료되면 브라우저에 Successfully set up Gmail push notifications 메시지가 표시됩니다.

이 Codelab에서는 @google-cloud/express-oauth2-handlers 패키지를 사용하여 승인 워크플로를 자동화합니다. 자세한 내용은 GitHub의 저장소를 참조하세요.

6. 수신 메일 처리

앞서 언급했듯이 새로 만든 Pub/Sub 주제의 구독자는 새 메시지가 받은편지함으로 도착하면 알림을 받게 됩니다. pubsub/index.js는 주제의 구독자로 배포되면 새 메시지를 읽고, 첨부된 이미지를 분류하고, 해당 카테고리를 Google 시트로 내보내는 watchGmailMessages Cloud 함수를 지정합니다.

코드를 검사하려면 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는 blue, sky, nature 태그를 반환할 수 있습니다.

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 Sheets 업데이트

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 시트가 몇 초 후 내가 제공한 정보로 자동 업데이트됩니다.