sendgrid multipart/alternative image from base64 - sendgrid

I can't get Sendgrid (using node.js) to send an email with a embedded base64 image in the html. I think I'm quite close...
var base64img='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQgAAAFXCAYAAABeLtDdAAAgAElEQVR4Xu19CXhURdb2ISsJgSQ';//shortened version
sendgrid.send({
to : 'address1#gmail.com',
from : 'address2#gmail.com',
subject : 'email with image from base64 data',
headers:{
'Content-Type':
'multipart/alternative; boundary="imagebase64"'+
'--imagebase64'+
'Content-Type: image/png; name="base64.png"'+
'Content-Disposition: inline; filename="base64.png"'+
'Content-Transfer-Encoding: base64'+
'Content-ID: <0123456789>'+
'Content-Location: base64.png'+
base64img+
'--imagebase64'
},
html : '<img src="cid:0123456789"/>'
});
Can someone help, as I'm failing to find an example close on sendgrid docs or google

FIXED!
var base64img='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQgAAAFXCAYAAABeLtDdAAAgAElEQVR4Xu19CXhURdb2ISsJgSQ';//shortened version
var data=base64img.replace(/^data:image\/\w+;base64,/,"");
var buffer=new Buffer(data,'base64');
fs.writeFile('/home/engine/public_html/img/base64img.png',buffer,function(err){
fs.readFile('public_html/img/base64img.png',function(err,data){
sendgrid.send({
to : 'address11#gmail.com',
from : 'address2#gmail.com',
subject : 'email with image from base64 data',
files : [{filename:'base64.png',content:data,cid:'1234567890'}],
html : '<img src="cid:1234567890"/>'
},
function(success,message){
if(!success){console.log(message);}
else{
console.log('sent');
fs.unlink('public_html/img/base64img.png');
}
});});});

Related

File not uploading in server ionic3

I have a scenario where I am uploading a image file from my local drive (type jpeg or png) to an API endpoint using ionic. Here is my code below :
fileupload.html -->
//---------------------------------------------------
<ion-item>
<ion-input type="file" accept="image/*" (change)="changeListener($event)"> </ion-input>
</ion-item>
fileupload.ts -->
changeListener($event):void{
this.file=$event.target.files[0];
console.log(this.file);
console.log("upload...");
let regData={"file":this.file};
console.log("REGDATAA"+JSON.stringify(regData));
this.jira.postAttachment("PM-3",regData).subscribe(dataa=>{
console.log(dataa);
});
}
provider.ts -->
public postAttachment(key,data):Observable<any>{
console.log(JSON.stringify(data))
return this.http.post(this.api+'/issue/'+key+'/attachments',JSON.stringify(data),{
headers: new HttpHeaders()
.append('Authorization', `Basic ${this.auth.getAuthString()}`)
.append('Content-Type','multipart/form-data';boundary="-------xe3rtyhrfds")
.append("X-Atlassian-Token", "no-check")
.append("User-Agent", "xx")
});
}
every time I send the file it doesn't take the path and sends an empty response, here is the error below.
//----------------------------------------------------
[object File]: {lastModifiedDate: [date] Fri Sep 21 2018 17:42:46 GMT+0530 (India Standard Time), name: "download.jpg", size: 5056, type: "image/jpeg", webkitRelativePath: ""}
upload...
ion-dev.js (157,11)
REGDATAA{"file":{}}
ion-dev.js (157,11)
{"file":{}}
ion-dev.js (157,11)
ERROR [object Object]
I have resolved CORS issue and there is no problem with the same.
When I send the same response using postman it succeeds here is what I send in Postman.
Form-data
key - "file" (type file) value - "/path/to/my/file"
Headers
Content-type - application/json
x-attlassian token - no-check
Can somebody advice what is going wrong here.
Use FormData to upload file.
fileupload.ts
changeListener(event) {
const fd = new FormData();
this.file = event.target.files[0];
fd.append('file', this.file, this.file.name);
this.jira.postAttachment("PM-3",fd)
.subscribe(data => {
console.log(data);
});
}
provider.ts
postAttachment(key, fd): Observable<any> {
const httpOptions = {
headers: new HttpHeaders(
{ 'Content-Type': 'multipart/form-data' },
{ 'Authorization': `Basic ${this.auth.getAuthString()}` })
};
return this.http.post(this.api+'/issue/'+key+'/attachments', fd, httpOptions);
}
Your have to change the content type from application/json to multipart/form-data. You are sending an image, not a json-file.
Best way is to encode your image to base64 and send it. Everything depends about what your server needs.
or you can try this.
const body = file;
const headers = new Headers({'Content-Type': 'image/jpg'});
return this.http.post(this.api+'/issue/'+key+'/attachments, body, {headers: headers}). ...
For an issue on AngularJS what ended up working is (might a similar aproach help you too) :
make a hidden input de type file
set it's value in the changeListener function
make the file send from there afterwards
The reason being some built in propertie of the file input let's its value be recognised as File/Blob instead of the path many "complex" components use.
Also send it as multipart file as mentioned before.

Send mail with attachment using mailjet in GAS

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.

Sending data in 'Request Payload' using amplifyjs

I have a javascript object to be sent to server as follow :
var input = {a: 'aaa', b: 'bbb', c: 'ccc'};
And I want to send 'a' property in url like this
http://localhost/rest/customer/aaa
That's fine with url substitution feature in amplifyjs as follow :
amplify.request.define('update-customer', 'ajax', {
url : 'rest/customer/{a}',
dataType: 'json',
type : 'PUT'
contentType : 'application/json; charset=utf-8;
});
amplify.request('update-customer', { a : input.a, data : input });
The point I am struggling with is that I would like to send b and c property as a form data in json format as a 'Request Payload', however it is failed becauseof the form data is sent as follow :
Request Payload :
data : {b : 'bbb', c : 'ccc'}
So what I want to achieve is to remove 'data' key in 'Request Payload' as follow :
Request Payload :
{b : 'bbb', c : 'ccc'}
I tested this in REST Client program and was successed.
To wrap up my question, How to send data attached in Request Body without key name using amplifyjs?
Thanks in advance.
Try with:
amplify.request.define('update-customer', 'ajax', {
url: 'rest/customer/{a},
dataType: 'json',
type: 'PUT',
contentType: 'application/json; charset=utf-8',
data: {
b : '{b}',
c : '{c}'
}
});
amplify.request('update-customer', { a : input.a, data : input });
This solution has a problem if input.b or input.c are null. Check this post for further details

Posting (by streaming?) with mikeal request

I'm trying to post a photo using mikeal request library, but the post comes emp
request = require('request')
fs = require("fs")
fs.createReadStream('zebra.jpg').pipe(request.post('http://localhost:2000'))
(on localhost:2000 I've got a simple echo for now)
Now, this works but I want to pass additional parameters using standard POST format.
What I'm actually trying to do is to post an image to Facebook via API, which means I'd like to include a title and possibly some more fields.
If streaming is not the right approach (although I see many benefits such as getting away without temporary files and buffers), what would be the right one?
Thanks for ideas.
UPD:
I've got this far:
fs.createReadStream('zebra.jpg').pipe(graph.post('418533674856800/photos',
{message:"I'm a new API photo!", name:"API Photo",privacy:{value:"EVERYONE"}},
function(err, res) {
console.log(res);
}));
but it returns
dest.on('drain', ondrain);
^
TypeError: Object #<Graph> has no method 'on'
at [object Object].pipe (stream.js:52:8)
at Request._callback (c:\My Stuff\Creatiff\PRAGmatiki\Web-node.js\postaspage.js:66:36)
at Request.callback (c:\My Stuff\Creatiff\PRAGmatiki\Web-node.js\node_modules\request\main.js:119:22)
at Request.<anonymous> (native)
at Request.emit (events.js:70:17)
at Request.<anonymous> (c:\My Stuff\Creatiff\PRAGmatiki\Web-node.js\node_modules\request\main.js:521:16)
at Request.emit (events.js:67:17)
at IncomingMessage.<anonymous> (c:\My Stuff\Creatiff\PRAGmatiki\Web-node.js\node_modules\request\main.js:483:14)
at IncomingMessage.emit (events.js:88:20)
at HTTPParser.parserOnMessageComplete [as onMessageComplete] (http.js:130:23)
Is this happening because I'm streaming? Any help please!
var path = require('path'),
mime = require('mime');
request({
url: 'http://localhost:2000',
headers: {
'content-type' : 'multipart/form-data'
},
method: 'POST',
multipart: [{
'Content-Disposition' : 'form-data; name="inputname"; filename="' + path.basename('zebra.jpg') + '"',
'Content-Type' : mime.lookup('zebra.jpg'),
body: fs.readFileSync('zebra.jpg')
},{
'Content-Disposition' : 'form-data; name="input[array]"; filename="' + path.basename('zebra1.jpg') + '"',
'Content-Type' : mime.lookup('zebra1.jpg'),
body: fs.readFileSync('zebra1.jpg')
},{
'Content-Disposition' : 'form-data; name="input[array]"; filename="' + path.basename('zebra2.jpg') + '"',
'Content-Type' : mime.lookup('zebra2.jpg'),
body: fs.readFileSync('zebra2.jpg')
},{
'Content-Disposition' : 'form-data; name="text"',
body: "text input"
}]
},
function(err, res, body){
});
I don't know what graph is (doesn't appear in mikeael's documentation), but it doesn't implement the Stream interface so can't be used with pipe().
To send multiple parts in a POST you need to use a request of type multipart/form-data. The latest version of mikeal/request has experimental support for this (with examples). Other modules also support it (needle for example, though stream support was a little lacking last time I looked).

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 })
})
})