1. Введение
Миллиарды компаний и частных лиц используют Gmail и другие сервисы G Suite для обмена данными и их обработки. Google предлагает API для G Suite, позволяющие программно получать доступ к информации в этих сервисах, и вы можете использовать эти API для простой автоматизации своей повседневной работы. В этой лабораторной работе вы создадите мощное расширение для Gmail, которое автоматически классифицирует входящие электронные письма и сохраняет эти категории в таблице Google Sheets. Это расширение будет использовать RESTful API G Suite, Google Cloud Functions и другие сервисы Google Cloud Platform.
Что вы построите
В этой лабораторной работе вы создадите и развернете несколько облачных функций, подключенных к API G Suite и другим сервисам Google Cloud Platform. Эти функции будут:
- Предоставьте защищенный доступ к вашим данным в Gmail и Google Sheets.
- Извлекайте изображения, прикрепленные к входящим письмам.
- Классифицируйте эти изображения с помощью API Cloud Vision.
- Внесите эти категории, адрес отправителя и название вложения в таблицу Google Sheets.
Что вы узнаете
- Основы работы с RESTful API в G Suite
- Основы работы с Google Cloud Functions и другими сервисами Google Cloud Platform.
- Как получить доступ к Gmail программным способом с помощью Google Cloud Functions
Что вам понадобится
- Для работы вам потребуется учетная запись Google с доступом к Gmail и Google Sheets. Если у вас ее нет, создайте ее здесь .
- Базовые знания JavaScript/Node.js.
2. Прежде всего
Включите API
В этой лабораторной работе вы будете использовать следующие продукты/сервисы Google:
- Google Cloud Functions
- Google Cloud Pub/Sub
- API Google Cloud Vision
- Google Cloud Datastore
- API Gmail
- API Google Таблиц
Google Cloud Functions
Google Cloud Functions — это платформа Google для бессерверных функций как услуги, которая позволяет запускать отдельные фрагменты кода («функции») простым и масштабируемым способом.
Чтобы включить Google Cloud Functions, нажмите на значок меню (три горизонтальные полоски) в левом верхнем углу экрана, чтобы открыть боковую панель навигации:

Найдите раздел «Cloud Functions» в меню навигации и нажмите на него. Нажмите «Enable 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» и щелкните по нему. На новой странице нажмите «Select Datastore Mode» .

Для этой лабораторной работы можно использовать любое местоположение базы данных. Нажмите «Создать базу данных» , чтобы включить Google Cloud Datastore; это может занять несколько минут.
Google Cloud Vision
Google Cloud Vision API — это мощный сервис машинного обучения, использующий предварительно обученные модели для извлечения полезной информации из ваших изображений.
Инструкции по включению API Google Cloud Vision приведены ниже.
Включение API Gmail, API Google Sheets и API Google Cloud Vision
Снова откройте левую боковую панель навигации и найдите раздел «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. Архитектурный обзор
Ниже представлен алгоритм выполнения данной лабораторной работы:

- Пользователь настраивает push-уведомления Gmail: каждый раз, когда в папку «Входящие» приходит новое сообщение, Gmail отправляет уведомление в Cloud Pub/Sub.
- Cloud Pub/Sub отправляет уведомление о новом сообщении в Google Cloud Functions.
- После получения уведомления о новом сообщении экземпляр Cloud Functions подключается к Gmail и получает новое сообщение.
- Если электронное письмо содержит изображение в качестве вложения, экземпляр Cloud Functions вызывает API Cloud Vision для анализа вложения.
- Экземпляр Cloud Functions обновляет выбранную вами таблицу Google Sheets, указывая, кто отправил сообщение и куда следует загрузить вложение.
4. Предоставьте доступ к Gmail.
Прежде чем настраивать облачную функцию для автоматического чтения ваших писем, необходимо авторизовать ее доступ к Gmail. Для этого потребуется зарегистрировать OAuth-клиент в Google и создать связанный с ним идентификатор клиента.
Зарегистрируйте OAuth-клиент
В левом навигационном меню консоли Google Cloud найдите раздел «API и сервисы» . Нажмите «Экран согласия OAuth» .

В поле «Название приложения» введите название, например , GCF + Gmail Codelab . Остальные настройки оставьте без изменений, прокрутите страницу вниз и нажмите «Сохранить» .
Создайте связанный идентификатор клиента.
Перейдите на вкладку «Учетные данные» . Нажмите «Создать учетные данные» и выберите «Идентификатор клиента OAuth» . Выберите тип веб-приложения , дайте ему имя (здесь можно снова использовать GCF + Gmail Codelab ) и нажмите «Создать». Пока оставьте поля «Ограничения» пустыми.
Запишите идентификатор клиента и секретный ключ клиента, полученные во всплывающем окне. Вы можете щелкнуть имя клиента на странице, чтобы снова просмотреть эти значения:

Выполните процедуру авторизации.
В приведенном примере кода файл auth/index.js указывает на две облачные функции, auth_init и auth_callback , которые работают вместе для выполнения процесса авторизации, используя идентификатор клиента и секретный ключ клиента, которые вы только что создали.
Чтобы просмотреть код, откройте auth/index.js в редакторе кода Cloud Shell.
В процессе авторизации возвращаются два типа токенов: токены доступа и токены обновления .
- Токены доступа — это кратковременные подтверждения личности, предоставляющие любому, кто ими владеет, ограниченный доступ к вашим данным;
auth_callbackсохраняет их в Cloud Datastore. - Токены обновления используются для получения новых токенов доступа и имеют значительно больший срок действия.
Как правило, они либо зашифрованы, либо хранятся отдельно от токенов доступа.
Отредактируйте auth/env_vars.yaml в редакторе кода Cloud Shell. Замените YOUR-GOOGLE-CLIENT-ID и YOUR-GOOGLE-CLIENT-SECRET своими значениями. Дополнительную информацию см. в предыдущем шаге. Пока оставьте значения YOUR-GOOGLE-CLIENT-CALLBACK-URL и YOUR-PUBSUB-TOPIC без изменений.

После редактирования файла 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 SDK разрешение на установку бета-версий команд.
Далее перейдите в консоль Google Cloud и в левом навигационном меню нажмите «Cloud Functions» . В списке функций Cloud Functions выберите auth_callback и перейдите на вкладку «Trigger» .


Скопируйте URL-адрес со страницы. Вернитесь на страницу Cloud Functions, щелкните auth_init в списке Cloud Functions. На вкладке «Общие» нажмите «Изменить» . Щелкните «Переменные среды, сеть, тайм-ауты и многое другое » и замените значение 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 для подтверждения.
Удалите часть /auth_callback из URL и добавьте остальную часть как авторизованный источник JavaScript . Например, если ваш URL выглядит так:
https://us-central1-my-project.cloudfunctions.net/auth_callback
В качестве источника следует добавить следующее:
https://us-central1-my-project.cloudfunctions.net/

Нажмите Enter для подтверждения и нажмите «Сохранить» , чтобы применить изменения.
5. Настройте push-уведомления в Gmail.
Если процесс авторизации пройдет успешно, auth_callback автоматически вызовет API Gmail для настройки push-уведомлений.
Для получения push-уведомлений от 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 ; наконец, нажмите «Сохранить» , чтобы применить изменения.
Обновите параметр auth_callback облачной функции, указав, какую тему Pub/Sub использовать. Щелкните «Облачные функции» в левом навигационном меню и выберите auth_callback в списке облачных функций. На вкладке «Общие» щелкните «Изменить» . Щелкните «Дополнительно» и замените значение PUBSUB_TOPIC на имя только что созданной темы Pub/Sub. Нажмите «Сохранить» , чтобы применить изменения.
Теперь вы готовы авторизовать и настроить push-уведомления Gmail. Подождите, пока изменения вступят в силу, затем вернитесь на страницу Cloud Functions , выберите auth_init в списке Cloud Functions и перейдите на вкладку «Триггер» . Щелкните по URL-адресу, и вы будете перенаправлены на страницу входа через Google :

Войдите в систему , используя свою учетную запись Gmail . Любое новое сообщение, поступающее в папку «Входящие», будет отправляться в виде push-уведомления. После входа в систему вы увидите страницу, показанную ниже:

Нажмите «Разрешить» , чтобы авторизовать доступ. auth_callback завершит процесс авторизации, сохранит токены доступа и настроит для вас push-уведомления Gmail. После завершения процесса в вашем браузере должно появиться сообщение Successfully set up Gmail push notifications .
В этом практическом занятии используется пакет @google-cloud/express-oauth2-handlers для автоматизации процесса авторизации. Для получения дополнительной информации см. его репозиторий на GitHub .
6. Обработка входящих сообщений
Как мы уже упоминали ранее, любой подписчик созданной вами темы Pub/Sub будет получать уведомления о поступлении новых сообщений в ваш почтовый ящик. pubsub/index.js указана облачная функция watchGmailMessages , которая после активации в качестве подписчика темы будет читать новые сообщения, классифицировать прикрепленные изображения и экспортировать эти категории в таблицу Google Sheets.
Чтобы просмотреть код, откройте pubsub/index.js в редакторе кода Cloud Shell.
Получение сообщений
Push-уведомление Gmail содержит адрес электронной почты, к которому оно привязано, и идентификатор истории. Для простоты в этом практическом задании вы просто запросите у API Gmail последнее сообщение, полученное при отправке push-уведомления; для лучшего результата используйте идентификатор истории для поиска сообщений .
// 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 вызовет API Cloud Vision для аннотирования изображения. В этом практическом задании вы попросите API Cloud Vision классифицировать изображение и вернуть ряд тегов; например, если предоставлено изображение голубого неба, API Cloud Vision может вернуть теги blue , sky и nature .
watchGmailMessages использует библиотеку Cloud Vision API для Node.js для вызова 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 Sheets. В ней содержится имя отправителя, название вложения и теги прикрепленных изображений (если таковые имеются).
Сначала создайте таблицу Google Sheets. Откройте Google Sheets и выберите « Пустой шаблон» в разделе «Создать новую электронную таблицу» . Скопируйте идентификатор вашей таблицы. Например, если адрес в вашем браузере выглядит так:
https://docs.google.com/spreadsheets/d/abcdefghij01234567890/edit#gid=0
Идентификатор вашей электронной таблицы — abcdefghij01234567890 . В редакторе кода Cloud Shell обновите файл gcf-gmail-codelab/pubsub/env_vars.yaml , заменив YOUR-GOOGLE-SHEET-ID на ваше собственное значение.
watchGmailMessages подключается к API Google Sheets для добавления информации:
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 в левом навигационном меню, выберите auth_init в списке Cloud Functions и найдите раздел «Переменные среды» .
Разверните код
Выполните указанную ниже команду для развертывания облачной функции:
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 в приведенной выше команде на имя вашей темы. Развертывание облачной функции может занять несколько секунд.
7. Попробуйте.
Поздравляем, вы закончили! Отправьте себе электронное письмо с прикрепленным изображением. Через несколько секунд вы увидите, как созданная вами таблица Google Sheets автоматически обновится, добавив предоставленную вами информацию.