【问题标题】:GMail API using POST request, error code: 400, recipient address required使用 POST 请求的 GMail API,错误代码:400,需要收件人地址
【发布时间】:2019-10-30 20:01:13
【问题描述】:

我正在尝试使用 POST 请求通过 GMail API 在 NodeJS v8.10 中仅使用 Node 标准模块发送电子邮件。 示例代码如下。

我收到一个错误:

{
 "error": {
  "errors": [
   {
    "domain": "global",
    "reason": "invalidArgument",
    "message": "Recipient address required"
   }
  ],
  "code": 400,
  "message": "Recipient address required"
 }
}

它说需要收件人地址,但根据我的想法,(我可能错了),我的 base64url 转换是正确的,因为我在 Google API Explorer 中检查了它,但我的问题在于传递数据,我正在正确地做在指南中告诉,即在体内带有“原始”键,但它仍然不起作用,这就是我的问题所在。也许我遗漏了什么,也许我不知道正确的结构。

是的,有很多关于此的帖子,但没有一个提供解决方案。 我参考了https://developers.google.com/gmail/api/v1/reference/users/messages/send上的指南 但给定的示例是使用客户端库。

我尝试了所有方法,将带有 base64url 编码数据的“原始”数据传递到请求的写入函数中,将其作为数据参数传递到选项中,通过选项中的正文参数传递,我能想到的一切。

我错过了什么吗?我哪里错了?

我是 nodejs 的新手,所以请解释一下,如果可能的话,一个解决方案的示例结构将是最受欢迎的。

Base64url 产生的工作正常,我猜。我复制了转换产生的字符串并在https://developers.google.com/gmail/api/v1/reference/users/messages/send?apix=true尝试了它 它工作正常并向我发送邮件,但它不适用于我的代码。

var email = (
          "Content-Type: text/plain; charset=\"UTF-8\"\n" +
          "Content-length: 5000\n" +
          "MIME-Version: 1.0\n" +
          "Content-Transfer-Encoding: message/rfc2822\n" +
          "to: something@something.com\n" +
          "from: \"Some Name\" <something@gmail.com>\n" +
          "subject: Hello world\n\n" +

          "The actual message text goes here"
            );

async function sendMail(token,resp) {

    return new Promise((resolve,reject) => {

      var base64EncodedEmail = Buffer.from(email).toString('base64'); 
      var base64urlEncodedEmail = base64EncodedEmail.replace(/\+/g, '-').replace(/\//g, '_');

      var params = {
        userId: 'me',
        resource: {
          'raw': base64urlEncodedEmail
        }
      };

      var body2 = {
          "raw": base64urlEncodedEmail,
        }

      var options = {
        hostname: 'www.googleapis.com',
        path:'/upload/gmail/v1/users/me/messages/send',
        headers: {
          'Authorization':'Bearer '+token,
          'Content-Type':'message/rfc822',
        },
        body: {
          "raw": base64urlEncodedEmail,
          'resource': {
            'raw': base64urlEncodedEmail,
          }
        },
        data: JSON.stringify({
          'raw': base64urlEncodedEmail,
          'resource': {
            'raw': base64urlEncodedEmail,
          }
        }),
        message: {
          'raw': base64urlEncodedEmail,
        },
        payload: {
          "raw": base64urlEncodedEmail, //this is me trying everything I can think of
        },
        // body: raw,
        // }
        userId: 'me',
        // resource: {
        //   'raw': base64urlEncodedEmail
        // },
        method: 'POST',
      };

    var id='';
    console.log(base64urlEncodedEmail);
    const req = https.request(options, (res) => {

        var body = '';

        res.on('data', (d) => {
            body += d;
        });
        res.on('end', () => {
            var parsed = body;
            console.log(parsed);
        })
      });

      req.on('error', (e) => {
        console.error(e);
      });
      req.write(JSON.stringify(body2));
      req.end();
  });
};

感谢您的时间和回答。

【问题讨论】:

标签: node.js email gmail-api


【解决方案1】:

我找到了解决办法。

它到处都说将 rfc822 格式的字符串转换为 Base64url 以发送并将其附加到 POST 正文中的“原始”属性,但我不知道发生了什么变化,你不需要再这样做了。

首先,标题中的 Content-Type 应该是

'Content-Type':'message/rfc822'

现在,由于我们将内容类型指定为message/rfc822,我们不需要再将我们要发送的数据转换为base64url格式,我猜(不确定原因,因为我有很少这方面的知识。) 仅将“To:something@any.com”作为正文传递。

这里是为遇到同样问题的人完成它的完整代码。

function makeBody(to, from, subject, message) {
    let str = [
        "to: ", to, "\n",
        "from: ", from, "\n",
        "subject: ", subject, "\n\n",
        message,
    ].join('');
    return str;
}


async function getIdAsync(token,resp) {

    return new Promise((resolve,reject) => {

      let raw = makeBody("something@gmail.com", "something@gmail.com", "Subject Here", "blah blah blah");

      var options = {
        hostname: 'www.googleapis.com',
        path:'/upload/gmail/v1/users/me/messages/send',
        headers: {
          'Authorization':'Bearer '+token,
          'Content-Type':'message/rfc822'
        },
        method: 'POST',
      };

    const req = https.request(options, (res) => {

        var body = '';

        res.on('data', (d) => {
            body += d;
        });
        res.on('end', () => {
            var parsed = body;
            console.log(parsed);
        })
      });

      req.on('error', (e) => {
        console.error(e);
      });
      req.write(raw);
      req.end();
  });
};

快乐编码:)

【讨论】:

    猜你喜欢
    • 2019-09-21
    • 2018-08-14
    • 2020-07-07
    • 1970-01-01
    • 1970-01-01
    • 2020-08-23
    • 2021-10-23
    • 2021-11-03
    • 2015-06-27
    相关资源
    最近更新 更多