Отвечать с помощью объекта JSON из конечной точки Express, используя Gmail API - PullRequest
0 голосов
/ 07 июня 2018

Я пытаюсь вернуть значение объекта данных из функции listLabels в моем коде ниже.Я хотел бы, чтобы к нему обращались из конечной точки Express, например (localhost: 3001).

Мне удалось сохранить объект в консоли, и я смог самостоятельно отправлять электронные письма.Любая помощь в возврате значения при доступе к конечной точке Express будет принята с благодарностью.

const express = require('express')
const app = express()
const fs = require('fs')
const readline = require('readline')
const {google} = require('googleapis')


app.get('/', function(req, res) {
    res.setHeader('Content-Type', 'application/json')
    let data = getLabels()
    console.log('data: ' + data)
    res.json(data)
})

app.get('/hello', function (req, res) {
    res.send('hello there')
})

app.listen(3001, () => console.log('server up on 3001'))

const SCOPES = ['https://mail.google.com/',
                'https://www.googleapis.com/auth/gmail.modify',
                'https://www.googleapis.com/auth/gmail.compose',
                'https://www.googleapis.com/auth/gmail.send'
                ];

const TOKEN_PATH = 'credentials.json';

function getLabels() {
    fs.readFile('client_secret.json', (err, content) => {
      if (err) return console.log('Error loading client secret file:', err);
      authorize(JSON.parse(content), listLabels);
    });
}

function authorize(credentials, callback) {
  const {client_secret, client_id, redirect_uris} = credentials.installed;
  const oAuth2Client = new 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);
  });
}


function getNewToken(oAuth2Client, callback) {
  const authUrl = oAuth2Client.generateAuthUrl({
    access_type: 'offline',
    scope: SCOPES,
  });
  console.log('Authorize this app by visiting this url:', authUrl);
  fs.writeFile('getCredentials.txt', authUrl, (err) => {
    if (err) throw err;
    console.log('getCredentials.txt saved!')
  })
  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 callback(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);
    });
  });
}

function listLabels(auth) {
  const gmail = google.gmail({version: 'v1', auth});
  console.log('here')
  gmail.users.messages.list({
    userId: 'me',
    maxResults: 10
  }, (err, {data}) => {
      if (err) return console.log('The API returned an error: ' + err);
      console.log('data in listlabels ' + JSON.stringify(data))
      //return data
      let dataForExpress 
      messages.forEach(function (message, index) {
        gmail.users.messages.get({
          userId: 'me',
          id: data.messages[index].id,
          format: 'raw'
        }, (err, {data}) => {
          if (err) return console.log('Error: ' + err)
          console.log(data)
          dataForExpress.push(data)
        });
    })
      return dataForExpress
  })     
}

1 Ответ

0 голосов
/ 07 июня 2018

Ожидаемые данные возвращаются асинхронно, поэтому вам нужно будет обрабатывать их асинхронно, используя callbacks или async await.

Вот пример использования обратных вызовов.

const express = require('express')
const app = express()
const fs = require('fs')
const readline = require('readline')
const {google} = require('googleapis')


app.get('/', function(req, res) {
    res.setHeader('Content-Type', 'application/json')
    // let data = getLabels()
    getLabels((labels) => {
        console.log(labels)
        res.json(labels)
    })
    //console.log('data: ' + data)
    //res.json(data)
})

app.get('/hello', function (req, res) {
    res.send('hello there')
})

app.listen(3001, () => console.log('server up on 3001'))

const SCOPES = ['https://mail.google.com/',
                'https://www.googleapis.com/auth/gmail.modify',
                'https://www.googleapis.com/auth/gmail.compose',
                'https://www.googleapis.com/auth/gmail.send'
                ];

const TOKEN_PATH = 'credentials.json';

function getLabels(callback) {
    fs.readFile('client_secret.json', (err, content) => {
      if (err) return console.log('Error loading client secret file:', err);
      // so here, instead of passing it listLabels directly, we will pass it just a regular callback, and call listlabels inside that callback. This way we can choose what to do with listlabels return value. 
      authorize(JSON.parse(content), (auth) => {
          listLabels(auth, (listOfLabels) => {
              console.log(listOfLabels) // we should have the list here
              callback(listOfLabels)
          }) //match the original arguments
      });
    });
}

function authorize(credentials, callback) {
  const {client_secret, client_id, redirect_uris} = credentials.installed;
  const oAuth2Client = new 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);
  });
}


function getNewToken(oAuth2Client, callback) {
  const authUrl = oAuth2Client.generateAuthUrl({
    access_type: 'offline',
    scope: SCOPES,
  });
  console.log('Authorize this app by visiting this url:', authUrl);
  fs.writeFile('getCredentials.txt', authUrl, (err) => {
    if (err) throw err;
    console.log('getCredentials.txt saved!')
  })
  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 callback(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);
    });
  });
}

function listLabels(auth, callback) {
  const gmail = google.gmail({version: 'v1', auth});
  console.log('here')

  gmail.users.messages.list({
    userId: 'me',
    maxResults: 10
  }, (err, {data}) => {
      if (err) return console.log('The API returned an error: ' + err);
      console.log('data in listlabels ' + JSON.stringify(data))
      //return data
      let dataForExpress 
      let messages = data.messages
      messages.forEach(function (message, index) {
        console.log("Inside foreach, message and index :", message, index)
        gmail.users.messages.get({
          userId: 'me',
          id: message.id,
          format: 'raw'
        }, (err, {data}) => {
          if (err) return console.log('Error: ' + err)
          console.log(data)
          dataForExpress.push(data)
          if dataForExpress.length == messages.length { // we done
              callback(dataForExpress)
          }
        });
    })
  })     
}
...