首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在Node.js中使用Gmail API发送带有附件的电子邮件?

如何在Node.js中使用Gmail API发送带有附件的电子邮件?
EN

Stack Overflow用户
提问于 2018-02-28 05:36:00
回答 3查看 6.4K关注 0票数 6

我是Node.js的新手,我正在尝试使用Gmail API创建一个邮箱,除了在电子邮件中上传附件之外,一切都很正常。我找到了Java、Python和C#的例子,但是我找不到任何关于node的文档。任何建议都将不胜感激。

下面是我的代码:

代码语言:javascript
运行
复制
function makeBody(to, from, subject, message) {
    var str = ["Content-Type: multipart/mixed; charset=\"UTF-8\"\n",
        "MIME-Version: 1.0\n",
        "Content-Transfer-Encoding: 7bit\n",
        "to: ", to, "\n",
        "from: ", from, "\n",
        "subject: ", subject, "\n\n",
        message,
        file
    ].join('');

    var encodedMail = new Buffer(str).toString("base64").replace(/\+/g, '-').replace(/\//g, '_');

    return encodedMail;
}

function sendMessage(auth) {
    var raw = makeBody(tap, 'me', response.subject, response.content, response.files);
    gmail.users.messages.send({
        auth: auth,
        userId: 'me',
        resource: {
            raw: raw
        }
    }, function (err, response) {
        if (err) {
            console.log('Error  ' + err);
            return;
        }

        if (response) {
            res.sendFile(__dirname + '/boite.html')
        }
    });
}
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-03-01 23:02:21

Creating messages with attachments中有一个关于这方面的说明

创建带有附件的邮件与创建任何其他邮件类似,但将文件作为多部分MIME邮件上载的过程取决于编程语言。

有关NodeJS示例参考,请查看此SO Post

票数 0
EN

Stack Overflow用户

发布于 2018-09-13 17:36:17

这可能有点晚了,不管怎样,我会花点时间,以防以后有人想要一个替代方案。

Moxched方法的主要问题是,他可能需要更仔细地研究MIME规范(这对我来说是一个很大的痛苦),以便更好地理解发送附件所必需的一些事情。

在我看来,为了能够使用gmail API发送附件和许多其他东西,你必须根据MIME规范构建all请求,为此,你需要了解MIME中的事情是如何工作的,包括边界。

Joris方法有效,但最终没有使用nodeJS库来发送电子邮件。他不能将gmail-api-create-message-body包中的答案与gmail API一起使用的原因是,由于某种原因,该库在其MIME消息的顶部生成了以下内容:

代码语言:javascript
运行
复制
'Content-Type: multipart/related; boundary="foo_bar_baz"',
`In-Reply-To: fakeemail@gmail.com`,
`References: `,
`From: fakeemail2@gmail.com`,
`Subject: SUBJECT`,
`MIME-Version: 1.0`,
'',
`--foo_bar_baz`,
`Content-Type: application/json; charset="UTF-8"`,
'',
`{`,
`}`,
'',
`--foo_bar_baz`,
`Content-Type: message/rfc822`,
'',
...

出于某种原因,gmailAPI不喜欢这样...

我的建议是更好地理解MIME规范,一个非常简单的方法是使用一些旧的逆向工程,因为我建议查看nodemailer的gmail-api-create-message-bodymail-composer的回复。

使用nodemailer/lib/mail-composer,您将能够轻松地根据MIME规范生成必要的MIME消息,它包括附件支持和所有其他内容。生成的MIME消息与Gmail API兼容。我留下一个基于NodeJS文档示例的工作示例,该示例发送带有2个附件的电子邮件。

希望这能有所帮助!

代码语言:javascript
运行
复制
const fs = require('fs');
const path = require('path');
const readline = require('readline');
const {google} = require('googleapis');

const MailComposer = require('nodemailer/lib/mail-composer');

// If modifying these scopes, delete token.json.
const SCOPES = [
  'https://mail.google.com',
  'https://www.googleapis.com/auth/gmail.readonly'
];
const TOKEN_PATH = 'token.json';

// Load client secrets from a local file.
fs.readFile('credentials.json', (err, content) => {
  if (err) return console.log('Error loading client secret file:', err);
  // Authorize a client with credentials, then call the Gmail API.
  //authorize(JSON.parse(content), listLabels);

  authorize(JSON.parse(content), sendEmail);

});

/**
 * 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.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);
    });
  });
}

function sendEmail(auth) {

  // ----------nodemailer test----------------------------------------------------

  let mail = new MailComposer(
    {
      to: "FAKE_EMAIL@gmail.com",
      text: "I hope this works",
      html: " <strong> I hope this works </strong>",
      subject: "Test email gmail-nodemailer-composer",
      textEncoding: "base64",
      attachments: [
        {   // encoded string as an attachment
          filename: 'text1.txt',
          content: 'aGVsbG8gd29ybGQh',
          encoding: 'base64'
        },
        {   // encoded string as an attachment
          filename: 'text2.txt',
          content: 'aGVsbG8gd29ybGQh',
          encoding: 'base64'
        },
      ]
    });

  mail.compile().build( (error, msg) => {
    if (error) return console.log('Error compiling email ' + error);

    const encodedMessage = Buffer.from(msg)
      .toString('base64')
      .replace(/\+/g, '-')
      .replace(/\//g, '_')
      .replace(/=+$/, '');

    const gmail = google.gmail({version: 'v1', auth});
    gmail.users.messages.send({
      userId: 'me',
      resource: {
        raw: encodedMessage,
      }
    }, (err, result) => {
      if (err) return console.log('NODEMAILER - The API returned an error: ' + err);

      console.log("NODEMAILER - Sending email reply from server:", result.data);
    });

  })

  // ----------nodemailer test----------------------------------------------------


}

票数 14
EN

Stack Overflow用户

发布于 2018-06-10 21:33:32

被同样的问题卡住了,我设法通过左右抓取东西来构建一个解决方案。

您需要使用的是npm包gmail-api-create-message-body

npm package page

代码语言:javascript
运行
复制
  const body = createBody({
    headers:{
      To:(msg.to.name) + " <" + msg.to.email + ">",
      From:(msg.from.name) + " <" + msg.from.email + ">",
      Subject:msg.subject
    },
    textHtml:msg.body.html,
    textPlain:msg.body.text,
    attachments:msg.files
  })

files是以下格式的数组。这只是一个例子:

代码语言:javascript
运行
复制
    files: [{
      type: "image/jpeg",
      name: "id1.jpg",
      data:base64ImageData
    }, {
      type: "image/jpeg",
      name: "id2.jpg",
      data: base64ImageData
    }]

接下来我需要混合两个API,我想通过Google API来做所有的事情,但是这不起作用,我不想浪费时间去理解为什么(他们的文档+节点的例子是一场灾难)

为了进行调用,我们需要身份验证令牌。这可以使用npm包google-auth-library找到。

代码语言:javascript
运行
复制
await oauth2Client.getAccessToken()

关于如何使用谷歌OAuth2的全部细节,我认为已经超出了这个答案的范围。

接下来,我们需要实际发送邮件。我不可能让它与官方的Gmail api一起工作(不断获得Error: Recipient address required),所以我使用了request-promise,如gmail-api-create-message-body示例中所示

代码语言:javascript
运行
复制
await rp({
  method: 'POST',
  uri: 'https://www.googleapis.com/upload/gmail/v1/users/me/messages/send',
  headers: {
    Authorization: `Bearer ${oauth2Client.credentials.access_token}`,
    'Content-Type': 'multipart/related; boundary="foo_bar_baz"'
  },
  body: body
});

这个al工作得很好。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49018323

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档