googleapis version: Unsure about the exact version, but I m referencing https://developers.google.com/gmail/api/guides/I want to send emails via the Gmail. send API endpoint WITH ATTACHMENT but I am unable to do so.
Note: I am able to send emails without attachment.
The following is my method which is not working that I have advanced from the method provided by Google on
https://developers.google.com/gmail/api/quickstart/nodejs
module.exports.sendMailAttach = function (to, subject, message, pdfPath, callback) {
const fs = require('fs');
const readline = require('readline');
const {google} = require('googleapis');
const path = require('path');
// If modifying these scopes, delete token.json.
var SCOPES = [
'https://mail.google.com/',
'https://www.googleapis.com/auth/gmail.modify',
'https://www.googleapis.com/auth/gmail.compose',
'https://www.googleapis.com/auth/gmail.send'
];
const TOKEN_PATH = '/home/................../config/token.json';
// Load client secrets from a local file.
fs.readFile('/home/................../config/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), sendMail);
});
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);
});
}
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 makeBody(to, from, subject, message, pdfPath) {
const attach = `${Buffer.from(fs.readFileSync(pdfPath)).toString('base64')}`;
const utf8Subject = `=?utf-8?B?${Buffer.from(subject).toString('base64')}?=`;
const messageParts = [
`From: ${from}`,
`To: ${to}`,
'MIME-Version: 1.0',
`Subject: ${utf8Subject}`,
"Content-Type: application/pdf; name="+path.basename(pdfPath),
"Content-Transfer-Encoding: 7bit",
"Content-Disposition: attachment; filename="+path.basename(pdfPath)
];
// "Content-Transfer-Encoding: base64",
const mailMessage = messageParts.join('\n');
const encodedMessage = Buffer.from(mailMessage)
.toString('base64')
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=+$/, '');
return encodedMessage;
}
function sendMail(auth) {
var raw = makeBody(to, 'me', subject, message, pdfPath);
const gmail = google.gmail({version: 'v1', auth});
gmail.users.messages.send({
auth: auth,
userId: 'me',
uploadType: 'multipart',
resource: {
raw: raw
}
}, (err, res) => {
if (err) return console.log('The API returned an error: ' + err);
console.log(`Mail sent to ${to} res.status ${res.status}, res.statusText ${res.statusText} res.data ${res.data}`)
callback(err, res);
});
}
};
sendMailAttach('[email protected]','Email with Attachment',"testBody",/home/..../Downloads/ADD LOCATION API.PDF, function(error, response){
console.log("response",response);
})
I'm using the following structure to send a message with an attachment:
const messageParts = [
'From: ' + from,
'To: ' + recipients,
`Subject: ${subject}`,
'MIME-Version: 1.0',
'Content-Type: multipart/mixed; boundary="' + mixedB + '"',
'',
'--' + mixedB,
'Content-Type: multipart/related; boundary="' + relatedB + '"',
'',
'--' + relatedB,
'Content-Type: multipart/alternative; boundary="' + alternativeB + '"',
'',
'--' + alternativeB,
'Content-Type: text/html; charset=utf-8',
'',
content, // html content.
'',
'--' + alternativeB + '--',
'',
'--' + relatedB + '--',
'',
'--' + mixedB,
'Content-Type: application/pdf;name="' + config.attachmentFilename + '.pdf"',
'Content-Transfer-Encoding: base64',
'Content-Disposition: attachment;filename="' + config.attachmentFilename + '.pdf"',
'',
config.attachment.slice(config.attachment.indexOf(',') + 1), // base64 data of the file.
'',
'--' + mixedB + '--'
]
This web page help me a lot to learn about structuring the content of an email: https://www.qcode.co.uk/post/70
I just wanted to share this snippet because most issues when send an email with an attachment are because of wrong structuring.
Thanks for the awesome answer!
Most helpful comment
I'm using the following structure to send a message with an attachment:
This web page help me a lot to learn about structuring the content of an email: https://www.qcode.co.uk/post/70
I just wanted to share this snippet because most issues when send an email with an attachment are because of wrong structuring.