Send mail with attachment using mailjet in GAS - email

I am trying to send mail with a PDF attachment using Mailjet from Google Apps Script. I can send regular mail without issue, but not quite sure how to include an attachment.
Mailjet documentation: https://dev.mailjet.com/guides/#sending-with-attached-files
I think my problem is the Base64Content. I don't really understand how to encode the attachment. When I execute the below code, an email is being sent with a PDF attachment, but when I try and open the PDF it displays: "Cannot display PDF (test.pdf is of invalid format)".
var newDoc = DocumentApp.openById(newDocid)
var attachment = newDoc.getAs(MimeType.PDF);
var mailjeturl = "https://api.mailjet.com/v3.1/send";
var mailjetparams = {
"Messages":[{
"From": {"Email": 'myemail#domain.com',"Name": 'Robert'},
"To": [{"Email": 'theiremail#domain.com'}],
"Subject": 'subject',
"HTMLPart": 'this message',
"Attachments": [{"ContentType": "application/pdf",
"Filename": "test.pdf",
"Base64Content": Utilities.base64Encode(attachment)}]
}]
}
var mailjetoptions = {
'method': 'post',
'contentType': 'application/json',
'payload': JSON.stringify(mailjetparams),
'headers': {'Authorization': 'Basic ' + Utilities.base64Encode(MAILJET_KEY)}
};
var response = JSON.parse(UrlFetchApp.fetch(mailjeturl, mailjetoptions))

Try to encode like this:
var pdf = newDoc.getAs('application/pdf').getBytes();
var attach = {fileName:'test.pdf',content:pdf, mimeType:'application/pdf'};
var mailjetparams = {
"Messages":[{
"From": {"Email": 'sender#domain.com',"Name": 'Robert'},
"To": [{"Email": 'reciever#domain.com'}],
"Subject": 'subject',
"HTMLPart": 'this message',
"Attachments": [attach]
}]
}

How about the following modification? I thought that the reason of the error may be Utilities.base64Encode(attachment).
Modification points :
attachment retrieved by newDoc.getAs(MimeType.PDF) is Blob. The Blob cannot be directly converted to base64 using Utilities.base64Encode(). So please convert Blob to byte array, and convert to base64.
When this is reflected to your script. The modification part is as follows.
From :
var attachment = newDoc.getAs(MimeType.PDF);
To :
var attachment = newDoc.getAs(MimeType.PDF).getBytes();
or
var attachment = newDoc.getBlob().getBytes();
When Google Document is retrieved as a Blob, Google converts automatically to PDF. You can also use this.
Reference :
base64Encode()
If I misunderstand your question, I'm sorry.

Related

How can i send the Map Object in multipart request in flutter

Here I am trying to send the Object Map in the multipart request but my request is going as a string, not in JSON format please suggest me to do correct request. Thanks in advance.
I have tried the multipart request but my request should be in correct form..
var getApiUrl = 'http://malik-env-test.ap-south-1.elasticbeanstalk.com/webapi/post/create';
Map userData = {
"creator": {
"creatorId": "298",
"createDate": "2018-12-21 20:44:45.8"
},
"info": "$campusInfo",
"title": "$eventName",
"postCampusId": "5642"
};
Uri uri = Uri.parse(getApiUrl);
http.MultipartRequest request = new http.MultipartRequest('POST', uri);
request.fields['creator'] = userData['creator'];
request.fields['info'] = '$campusInfo';
request.fields['title'] = '$eventName';
request.fields['postCampusId'] = '5642';
request.files.add(await http.MultipartFile.fromPath('image_file1', imagePath, contentType: new MediaType('application', 'x-tar')));
// var body = json.encode(request);
print(request);
http.StreamedResponse response = await request.send();
String jsonData = response.toString();
print(jsonData);ddd
Try:
request.fields['userData'] = json.encode(userData);
You need to find out from the API spec or server owner what field name to use for the json. I've assumed userData.
If you want control over the media type, encoding, etc, add it as a file like this:
request.files.add(
http.MultipartFile.fromBytes(
'the_form_field name',
utf8.encode(json.encode(userData)),
contentType: MediaType(
'application',
'json',
{'charset': 'utf-8'},
),
),
);
I think, the easiest way to add object fields is using brackets like this ;
request.fields['creator[creatorId]'] = '$creatorId';
request.fields['creator[createDate]'] = '$createDate';
request.fields['title'] = '$eventName';
request.fields['postCampusId'] = '5642';
So, for the fields inside another you need to put the object name first then add to fields name inside brackets.
this should work just fine.
var userData = json.encode({
"creator": {
"creatorId": "298",
"createDate": "2018-12-21 20:44:45.8"
},
"info": "$campusInfo",
"title": "$eventName",
"postCampusId": "5642"
});
var client = http.Client();
client
.post('https://'+ url ,
headers: {
'content-type': 'application/json',
},
body: userData )

How to send pdf file as an attachment in sendgrid node.js v3 client

I am using v3 node.js client to send an email. Now , I want to send pdf attachment with the email. I went through the API documentation. But I did not find anywhere how to do it.
I am using the following code to send an email.
const msg = {
to: process.env.EMAIL_ID,
from: process.env.ALERT_EMAIL_ID,
subject: subjectText,
text: info
};
sgMail.send(msg);
Let us assume your PDF is in S3.
Get your file from S3
const pdfFile = await s3
.getObject({
Bucket: PDF_BUCKET_NAME,
Key: `flight-${fileName}.pdf`,
})
.promise();
Once you have the file
const base64data = pdfFile.Body.toString('base64');
const data = {
from: 'text#example.in',
to: user.emailId,
subject: 'Your ticket for flight PNR XYSSA1 from DEL-BLR',
html: `Please find attached your ticket
<br><br>Regards<br>
Team Example`,
attachments: [
{ content: base64data, filename: 'flight-ticket', type: 'application/pdf', disposition: 'attachment' },
],
};
await sgMail.send(data);
In case you have your file in the filesystem, just get the buffer from fs.readFile convert it into base64 like shown above and repeat the steps and you should be good to go.

Send more then one PDF file using Google Apps Script

I used that method to send some files through mail, but I'm having issues to send PDF files, they are not enconding back.
function sendEmail() {
var files = [
"1X0YYxxtnKJtkn9BhoBcSb265acOYOnWJytQeBKEvfqU",
"12r6Owm616Ioqj9EfOgkNqPgXNi88f_chdPRyBcSC2EM"
];
var attachments = [];
for (var f in files) {
var file = DriveApp.getFileById(files[f]);
attachments.push({
"type": file.getMimeType(),
"name": file.getName(),
"content": Utilities.base64Encode(file.getBlob().getAs('application/pdf').getBytes())
});
}
MailApp.sendEmail('mail#gmail.com', 'Attachment example', 'Two files are attached.', {
name: 'Automatic Emailer Script',
attachments: attachments
});
}

Google Apps Script - create draft Gmail email message WITH embedded graphics

I want to create a draft Gmail email message using Google Apps Script, like in the following example taken from Mogsdad's accepted answer to the Create draft mail using Google apps script question:
function createDraft() {
var forScope = GmailApp.getInboxUnreadCount(); // needed for auth scope
var raw =
'Subject: testing Draft\n' +
//'To: test#test.com\n' +
'Content-Type: multipart/alternative; boundary=1234567890123456789012345678\n' +
'testing Draft msg\n' +
'--1234567890123456789012345678--\n';
var draftBody = Utilities.base64Encode(raw);
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://www.googleapis.com/gmail/v1/users/me/drafts", params);
Logger.log(resp.getContentText());
It works great, BUT I want to embedd some image in the message body, without linking to external URL, so it always shows up, it's not blocked by some email clients, including Gmail. How to do that?

Sending mails with attachment via NodeJS

Is there any library for NodeJS for sending mails with attachment?
Yes, it is pretty simple,
I use nodemailer: npm install nodemailer --save
var mailer = require('nodemailer');
mailer.SMTP = {
host: 'host.com',
port:587,
use_authentication: true,
user: 'you#example.com',
pass: 'xxxxxx'
};
Then read a file and send an email :
fs.readFile("./attachment.txt", function (err, data) {
mailer.send_mail({
sender: 'sender#sender.com',
to: 'dest#dest.com',
subject: 'Attachment!',
body: 'mail content...',
attachments: [{'filename': 'attachment.txt', 'content': data}]
}), function(err, success) {
if (err) {
// Handle error
}
}
});
Try with nodemailer, for example try this:
var nodemailer = require('nodemailer');
nodemailer.SMTP = {
host: 'mail.yourmail.com',
port: 25,
use_authentication: true,
user: 'info#youdomain.com',
pass: 'somepasswd'
};
var message = {
sender: "sender#domain.com",
to:'somemail#somedomain.com',
subject: '',
html: '<h1>test</h1>',
attachments: [
{
filename: "somepicture.jpg",
contents: new Buffer(data, 'base64'),
cid: cid
}
]
};
finally, send the message
nodemailer.send_mail(message,
function(err) {
if (!err) {
console.log('Email send ...');
} else console.log(sys.inspect(err));
});
Personally i use Amazon SES rest API or Sendgrid rest API which is the most consistent way to do it.
If you need a low level approach use https://github.com/Marak/node_mailer and set up your own smtp server (or one you have access too)
http://blog.nodejitsu.com/sending-emails-in-node
Have you tried Nodemailer?
Nodemailer supports
Unicode to use any characters
HTML contents as well as plain text alternative
Attachments
Embedded images in HTML
SSL (but not STARTTLS)
You may use nodejs-phpmailer
You can also use AwsSum's Amazon SES library:
https://github.com/appsattic/node-awssum/
In there, there is an operation called SendEmail and SendRawEmail, the latter of which can send attachments via the service.
use mailer package it is very flexible and easy.
Another alternative library to try is emailjs.
I gave some of the suggestions here a try myself but running code complained that send_mail() and sendMail() is undefined (even though I simply copy & pasted code with minor tweaks). I'm using node 0.12.4 and npm 2.10.1. I had no issues with emailjs, that just worked off the shelf for me. And it has nice wrapper around attachments, so you can attach it various ways to your liking and easily, compared to the nodemailer examples here.
Nodemailer for any nodejs mail needs. It's just the best at the moment :D
I haven't used it but nodemailer(npm install nodemailer) looks like what you want.
Send With express-mailer (https://www.npmjs.com/package/express-mailer)
Send PDF -->
var pdf="data:application/pdf;base64,JVBERi0xLjM..etc"
attachments: [ { filename: 'archive.pdf',
contents: new Buffer(pdf.replace(/^data:application\/(pdf);base64,/,''), 'base64')
}
]
Send Image -->
var img = 'data:image/jpeg;base64,/9j/4AAQ...etc'
attachments: [
{
filename: 'myImage.jpg',
contents: new Buffer(img.replace(/^data:image\/(png|gif|jpeg);base64,/,''), 'base64')
}
]
Send txt -->
attachments: [
{
filename: 'Hello.txt',
contents: 'hello world!'
}
]
you can use official api of google for this.
They have provided package for node for this purpose.
google official api
Ive attached part of my code that did the attachment thing for me
function makeBody(subject, message) {
var boundary = "__myapp__";
var nl = "\n";
var attach = new Buffer(fs.readFileSync(__dirname + "/../"+fileName)) .toString("base64");
// console.dir(attach);
var str = [
"MIME-Version: 1.0",
"Content-Transfer-Encoding: 7bit",
"to: " + receiverId,
"subject: " + subject,
"Content-Type: multipart/alternate; boundary=" + boundary + nl,
"--" + boundary,
"Content-Type: text/plain; charset=UTF-8",
"Content-Transfer-Encoding: 7bit" + nl,
message+ nl,
"--" + boundary,
"--" + boundary,
"Content-Type: Application/pdf; name=myPdf.pdf",
'Content-Disposition: attachment; filename=myPdf.pdf',
"Content-Transfer-Encoding: base64" + nl,
attach,
"--" + boundary + "--"
].join("\n");
var encodedMail = new Buffer(str).toString("base64").replace(/\+/g, '-').replace(/\//g, '_');
return encodedMail;
}
P.S thanks to himanshu for his intense research on this
The answer is not updated with the last version of nodemailer#6.x
Here an updated example:
const fs = require('fs')
const path = require('path')
const nodemailer = require('nodemailer')
const transport = nodemailer.createTransport({
host: 'smtp.libero.it',
port: 465,
secure: true,
auth: {
user: 'email#libero.it',
pass: 'HelloWorld'
}
})
fs.readFile(path.join(__dirname, 'test22.csv'), function (err, data) {
transport.sendMail({
from: 'email_from#libero.it',
to: 'email_to#libero.it',
subject: 'Attachment',
text: 'mail content...', // or body: field
attachments: [{ filename: 'attachment.txt', content: data }]
}, function (err, success) {
if (err) {
// Handle error
console.log(err)
return
}
console.log({ success })
})
})