Функция Lamda не может получать электронные письма Google по идентификатору - PullRequest
0 голосов
/ 24 апреля 2019

В локальном, с помощью простого приложения nodejs, я могу получать электронные письма по идентификатору, но в лямбда-функциях amazon (также с nodejs) это не так (сообщение об ошибке: невозможно прочитать данные свойств undefined.

Я пробовал это: https://developers.google.com/gmail/api/quickstart/nodejs Хорошо работает.

Что я сделал до сих пор в index.js: (учетные данные и файлы токенов json находятся в нужном месте, они скопированы с моего компьютера, сгенерированы приложением nodejs из примера Google)

/* eslint-disable  func-names */
/* eslint-disable  no-console */

const Alexa = require('ask-sdk-core');
const fs = require('fs');
const readline = require('readline');
const google = require('googleapis');
// If modifying these scopes, delete token.json.
const SCOPES = ['https://www.googleapis.com/auth/gmail.readonly'];
// The file token.json stores the user's access and refresh tokens, and is
// created automatically when the authorization flow completes for the first
// time.
const TOKEN_PATH = 'token.json';
// Load client secrets from a local file.
let speechText = 'Welcome to the Alexa Skills Kit, you can say hello!';

const LaunchRequestHandler = {
  canHandle(handlerInput) {
    return handlerInput.requestEnvelope.request.type === 'LaunchRequest';
  },
  async handle(handlerInput) {
    await fs.readFile('credentials.json', async (err, content) => {
      if (err) return console.log('Error loading client secret file:', err);
      // Authorize a client with credentials, then call the Gmail API.
      await authorize(JSON.parse(content), getMessage);
    });
    /**
     * Create an OAuth2 client with the given credentials, and then execute the
     * given callback function.
     * @param {Object} credentials The authorization client credentials.
     * @param {function} callback The callback to call with the authorized client.
     */
    function authorize(credentials, callback) {
      const {client_secret, client_id, redirect_uris} = credentials.installed;
      const oAuth2Client = new google.google.auth.OAuth2(
          client_id, client_secret, redirect_uris[0]);

      // Check if we have previously stored a token.
      fs.readFile(TOKEN_PATH, (err, token) => {
        if (err) return getNewToken(oAuth2Client, callback);
        oAuth2Client.setCredentials(JSON.parse(token));
        callback(oAuth2Client);
      });
    }

    /**
     * Get and store new token after prompting for user authorization, and then
     * execute the given callback with the authorized OAuth2 client.
     * @param {google.auth.OAuth2} oAuth2Client The OAuth2 client to get token for.
     * @param {getEventsCallback} callback The callback for the authorized client.
     */
    function getNewToken(oAuth2Client, callback) {
      const authUrl = oAuth2Client.generateAuthUrl({
        access_type: 'offline',
        scope: SCOPES,
      });
      console.log('Authorize this app by visiting this url:', authUrl);
      const rl = readline.createInterface({
        input: process.stdin,
        output: process.stdout,
      });
      rl.question('Enter the code from that page here: ', (code) => {
        rl.close();
        oAuth2Client.getToken(code, (err, token) => {
          if (err) return console.error('Error retrieving access token', err);
          oAuth2Client.setCredentials(token);
          // Store the token to disk for later program executions
          fs.writeFile(TOKEN_PATH, JSON.stringify(token), (err) => {
            if (err) return console.error(err);
            console.log('Token stored to', TOKEN_PATH);
          });
          callback(oAuth2Client);
        });
      });
    }

    /**
     * Lists the labels in the user's account.
     *
     * @param {google.auth.OAuth2} auth An authorized OAuth2 client.
     */
    async function getMessage(auth) {
      speechText = await resolveMessage();
      console.log(`Speechtext in async function: ${speechText}`);
      function resolveMessage() {
        return new Promise((resolve, reject) => {
          const gmail = google.google.gmail({version: 'v1', auth});
          gmail.users.messages.list({
            userId: 'me',
          }, async (err, res) => {
            console.log(`Error: ${err}`);
            if(err) {
              reject(err);
              return;
            }
            let message = res.data.messages[0];
            console.log(`Messages: ${res.data.messages}`);
            console.log(`Id: ${message.id}`);

//
// THIS IS UNDEFINED:
//


            let messageBody = await gmail.users.messages.get({id: message.id, userId: 'me'});
            console.log(messageBody.data.snippet);
            resolve(messageBody.data.snippet);
          });
        })
      }
    }

    return handlerInput.responseBuilder
      .speak(speechText)
      .reprompt(speechText)
      .withSimpleCard('Hello World', speechText)
      .getResponse();
  },
};

const ErrorHandler = {
  canHandle() {
    return true;
  },
  handle(handlerInput, error) {
    console.log(`Error handled: ${error.message}`);

    return handlerInput.responseBuilder
      .speak('Sorry, I can\'t understand the command. Please say again.')
      .reprompt('Sorry, I can\'t understand the command. Please say again.')
      .getResponse();
  },
};

const skillBuilder = Alexa.SkillBuilders.custom();

exports.handler = skillBuilder
  .addRequestHandlers(
    LaunchRequestHandler,
  )
  .addErrorHandlers(ErrorHandler)
  .lambda();

Так что я могу получить идентификаторы, но не текст сообщения, по идентификатору электронной почты. Это прекрасно, когда я запускаю на своем компьютере одно приложение nodejs. Пробовал на linux mint и windows 10 тоже, оба работают хорошо - но не на AWS.

Есть идеи, что может вызвать это?

...