node.js - 使用 Gmail API 从 Express 端点响应 JSON 对象

标签 node.js express gmail-api

我正在尝试从下面的代码中的函数 listLabels 返回数据对象的值。我希望从 Express 端点访问它,例如(本地主机: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
  })     
}

最佳答案

您期望的数据将以异步方式返回,因此您需要使用回调异步等待来异步处理它。

这是一个使用回调的示例。

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)
          }
        });
    })
  })     
}

关于node.js - 使用 Gmail API 从 Express 端点响应 JSON 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50741157/

相关文章:

php - 错误 403 : Error sending test message to Cloud PubSub: User not authorized to perform this action

使用 Postman 发送 Gmail api

node.js - 为什么我的 Nginx 反向代理 node.js+express 服务器重定向到 0.0.0.0?

php - 使用 Gmail API 发送带签名的电子邮件

javascript - 下载使用 SheetJS/XLXS 在 Node 中创建的 excel 文件 [NodeJS] [React]

javascript - 插入行时解析错误

javascript - Node.js 给出错误 : Can't set headers after they are sent

node.js - Stripe 无效请求错误: You can only create new accounts if you've signed up for Connect

javascript - YouTube使用 Node js自动上传

javascript - 事件排序 ExpressJS/Node