Mail attachment wrong media type Gmail API

后端 未结 2 2076
北荒
北荒 2020-11-28 11:39

I\'m trying to send a message with a jpeg file attached through the Gmail API in Javascript client side. The code I\'ve written so far is as follows:

$.ajax(         


        
相关标签:
2条回答
  • 2020-11-28 12:04

    The docs are a little confusing as the upload docs are generic instructions for how uploads work with Google API and the example isn't quite appropriate for gmail. That said, there is a more detailed explanation of how to send messages and attachments with the gmail API that covers it.

    In short, the attachment needs to be encoded in the raw message itself before you send it.

    0 讨论(0)
  • 2020-11-28 12:20

    EDIT

    This first piece of code works for attachments with a combined size of a few mb. If you want to use the allowed limit of 35 mb, check the edit at the end of the answer.


    After Steve pushed me in the right direction (the entire mail has to be in the "raw"-parameter), I simply tried the Python API and looked at the mail generated by that.

    Mail without attachment

    Content-Type: text/plain; charset="UTF-8"
    MIME-Version: 1.0
    Content-Transfer-Encoding: 7bit
    to: receiver@gmail.com
    from: sender@gmail.com
    subject: Subject Text
    
    The actual message text goes here
    

    Mail with attachment

    Content-Type: multipart/mixed; boundary="foo_bar_baz"
    MIME-Version: 1.0
    to: receiver@gmail.com
    from: sender@gmail.com
    subject: Subject Text
    
    --foo_bar_baz
    Content-Type: text/plain; charset="UTF-8"
    MIME-Version: 1.0
    Content-Transfer-Encoding: 7bit
    
    The actual message text goes here
    
    --foo_bar_baz
    Content-Type: image/jpeg
    MIME-Version: 1.0
    Content-Transfer-Encoding: base64
    Content-Disposition: attachment; filename="example.jpg"
    
    {JPEG data}
    
    --foo_bar_baz--
    

    So I just wrote my code around this, and it worked great!

    var reader = new FileReader();
    reader.readAsDataURL(attachment);
    reader.onloadend = function (e) {
      // The relevant base64-encoding comes after "base64,"
      var jpegData = e.target.result.split('base64,')[1];
      var mail = [
        'Content-Type: multipart/mixed; boundary="foo_bar_baz"\r\n',
        'MIME-Version: 1.0\r\n',
        'to: receiver@gmail.com\r\n',
        'from: sender@gmail.com\r\n',
        'subject: Subject Text\r\n\r\n',
    
        '--foo_bar_baz\r\n',
        'Content-Type: text/plain; charset="UTF-8"\r\n',
        'MIME-Version: 1.0\r\n',
        'Content-Transfer-Encoding: 7bit\r\n\r\n',
    
        'The actual message text goes here\r\n\r\n',
    
        '--foo_bar_baz\r\n',
        'Content-Type: image/jpeg\r\n',
        'MIME-Version: 1.0\r\n',
        'Content-Transfer-Encoding: base64\r\n',
        'Content-Disposition: attachment; filename="example.jpg"\r\n\r\n',
    
        jpegData, '\r\n\r\n',
    
        '--foo_bar_baz--'
      ].join('');
    
      // The Gmail API requires url safe Base64 
      // (replace '+' with '-', replace '/' with '_', remove trailing '=')
      mail = btoa(mail).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
    
      $.ajax({
        type: "POST",
        url: "https://www.googleapis.com/gmail/v1/users/me/messages/send",
        headers: {
          'Authorization': 'Bearer ' + accessToken,
          'Content-Type': 'application/json'
        },
        data: JSON.stringify({
          raw: mail
        })
      });
    }
    

    Edit

    The code above works, but a few alterations are needed to use the max limit of 35 mb.

    With a mail built up as the example under the heading Mail with attachment, the altered ajax-request looks as follows:

    $.ajax({
      type: "POST",
      url: "https://www.googleapis.com/gmail/v1/users/me/messages/send?uploadType=multipart",
      headers: {
        'Authorization': 'Bearer ' + accessToken,
        'Content-Type': 'message/rfc822'
      },
      data: mail
    }); 
    

    The Content-Type is now message/rfc822 instead of application/json, the url has gotten a new parameter uploadType=multipart, and most importantly the mail is no longer Base64 encoded, but supplied in the rfc822-format.

    0 讨论(0)
提交回复
热议问题