如何使用 GMAIL API 从 Google Apps 脚本发送电子邮件?

Nik*_*lay 1 google-apps-script gmail-api

我正在尝试使用 Google Apps 脚本中的 Gmail API 自动从我的帐户发送电子邮件。

这是我的代码:

function email_checker() {
  var yourEmailAddress = "###@gmail.com";
  var myEmailAddress = "support@###.com";
  var subject = "testing mail";
  var forScope = GmailApp.getInboxUnreadCount();
  var htmlBody = '<html><body>' + '<h1>HI</h1>' + '</body></html>';

  var message = 'From: Me <' + myEmailAddress + '>\r\n' +
    'To: Me <' + myEmailAddress + '>\r\n' +
    'Subject: ' + subject + '\r\n' +
    'Content-Type: text/html; charset=utf-8\r\n' +
    'Content-Transfer-Encoding: quoted-printable\r\n\r\n' +
    htmlBody;

  var draftBody = Utilities.base64Encode(message);
  draftBody = draftBody.replace(/\//g, '_').replace(/\+/g, '-');

  var params = {
    method: "post",
    contentType: "application/json",
    headers: {
      "Authorization": "Bearer " + ScriptApp.getOAuthToken()
    },
    muteHttpExceptions: true,
    payload: JSON.stringify({
      "message": {
        "raw": draftBody
      }
    })
  };

  var resp = UrlFetchApp.fetch("https://gmail.googleapis.com/upload/gmail/v1/users/me/messages/send", params);
  Logger.log(resp.getContentText());
}
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:不支持媒体类型“application/json”。

谁能告诉我我做错了什么?

谢谢。

Tan*_*ike 5

我相信您的目标和目前的情况如下。

  • 您想要使用 Gmail API 和 UrlFetchApp 发送电子邮件。
  • 您已经完成了发送电子邮件的设置。
    • Gmail API 已启用。
    • 可以包括发送电子邮件的范围。

修改要点:

  • 从您的端点发现使用了媒体上传请求。
  • 在这种情况下,
    • 请求正文需要使用 来创建multipart/alternative
    • 网络安全不需要使用 Base64 编码。
    • 需要内容类型才能使用message/rfc822
    • 创建的请求体可以直接使用payload

当以上几点反映到您的脚本中时,它会变成如下所示。

修改后的脚本:

function email_checker() {
  var yourEmailAddress = "###@gmail.com";
  var myEmailAddress = "support@###.com";
  var subject = "testing mail";
  var forScope = GmailApp.getInboxUnreadCount();
  var htmlBody = '<html><body>' + '<h1>HI</h1>' + '</body></html>';

  var message = 'MIME-Version: 1.0\r\n' +
    'From: Me <' + myEmailAddress + '>\r\n' +
    'To: Me <' + myEmailAddress + '>\r\n' +
    'Subject: ' + subject + '\r\n' +
    'Content-type: multipart/alternative; boundary=boundaryboundary\r\n\r\n' +
    '--boundaryboundary\r\n' +
    'Content-type: text/html; charset=UTF-8\r\n' +
    'Content-Transfer-Encoding: quoted-printable\r\n\r\n' +
    htmlBody + "\r\n\r\n" +
    '--boundaryboundary--';

  var params = {
    method: "post",
    contentType: "message/rfc822",
    headers: {
      "Authorization": "Bearer " + ScriptApp.getOAuthToken()
    },
    muteHttpExceptions: true,
    payload: message
  };

  var resp = UrlFetchApp.fetch("https://gmail.googleapis.com/upload/gmail/v1/users/me/messages/send", params);
  Logger.log(resp.getContentText());
}
Run Code Online (Sandbox Code Playgroud)

笔记:

  • 如果您想使用 的端点POST https://gmail.googleapis.com/gmail/v1/users/{userId}/messages/send,请按如下方式修改您的脚本。

    •   var params = {
          method: "post",
          contentType: "application/json",
          headers: {
            "Authorization": "Bearer " + ScriptApp.getOAuthToken()
          },
          muteHttpExceptions: true,
          payload: JSON.stringify({
            "message": {
              "raw": draftBody
            }
          })
        };
      
        var resp = UrlFetchApp.fetch("https://gmail.googleapis.com/upload/gmail/v1/users/me/messages/send", params);
        Logger.log(resp.getContentText());
      
      Run Code Online (Sandbox Code Playgroud)
    •   var params = {
          method: "post",
          contentType: "application/json",
          headers: {
            "Authorization": "Bearer " + ScriptApp.getOAuthToken()
          },
          muteHttpExceptions: true,
          payload: JSON.stringify({"raw": draftBody})
        };
      
        var resp = UrlFetchApp.fetch("https://gmail.googleapis.com/gmail/v1/users/me/messages/send", params);
        Logger.log(resp.getContentText());
      
      Run Code Online (Sandbox Code Playgroud)
    • 在这种情况下,var draftBody = Utilities.base64Encode(message); draftBody = draftBody.replace(/\//g, '_').replace(/\+/g, '-');也可以修改为var draftBody = Utilities.base64EncodeWebSafe(message);

参考: