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: [email protected]
from: [email protected]
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: [email protected]
from: [email protected]
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"
',
'MIME-Version: 1.0
',
'to: [email protected]
',
'from: [email protected]
',
'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"
',
jpegData, '
',
'--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.