Sending email with attachment from JS

Enonic version: 6.6.0
OS: Windows 8.1 Pro

I have a form with a field for an attachment. The values are parsed with JS and sent to a service that sends a mail using /lib/xp/mail.

Is there a way I can add an attachment without storing the file on the server? I convert the file to base64 before it is sent to the service. When I try to add it using ioLib.newStream nothing is added to the mail. If I just add some text I get it as content in the mail body.

Yes, it is possible to receive a file uploaded in a form as an attachment on a service, and add it to the email, without saving it anywhere.
There is no need to base64 encode, and I think it’s easier without that step.

Make sure you set the "multipart/form-data" encoding in the html form to submit (or ajax request):

<form action="#" data-th-action="${postUrl}" method="post" enctype="multipart/form-data">
   <input name="file1" type="file"/>
</form>

The controller code would be something like this:

var portal = require('/lib/xp/portal');
var mail = require('/lib/xp/mail');

exports.post = function (req) {
    var file1 = portal.getMultipartItem('file1');
    var attachments = [];
    if (file1 && file1.size > 0) {
        attachments.push({
            fileName: file1.fileName,
            mimeType: file1.mimeType,
            data: portal.getMultipartStream('file1')
        });
    }

    var sendResult = mail.send({
        subject: 'test',
        from: 'from@test',
        to: 'to@test',
        attachments: attachments
    });

    return {
        body: {sent: sendResult},
        contentType: 'application/json'
    };
};

If you need to do the base64 encoding and it fails, can you post your code here?

1 Like

I’m trying to do this completely from JS. I can get the file as base64 and send it to the server, but the mail client only takes a stream. Is there a way for me to get the base64 data into a stream to get it as a valid attachment? If i use ioLib.newStream() with the base64 encoded string it’s just appended to the body of the mail like this:

------=_Part_0_31106759.1512734741702 Content-Type: text/plain; charset=UTF-8 Content-
Transfer-Encoding: 7bit 
regular body here 
Mail from local machine ------=_Part_0_31106759.1512734741702 Content-Type: 
application/octet-stream; name=attachment Content-Transfer-Encoding: quoted-printable 
Content-Disposition: attachment; filename=attachment
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAX8AAABVCAYAAAChBOSDAAAAAXNSR= 
0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAHnPSURBVHhe7V0H= 
YFVF1j7pCQkJvSOgKCrgj4XeOyKI2BsW7Cv2ui4qNuwd666urhV7W0RAEURELIu9oaJIrwmQnvB= /3zkz974XXhqW1fUNjklumTtz5szpcyah....

You can convert base64 string to stream using the text-encoding library:

var encodingLib = require('/lib/text-encoding');

var decodedStream = encodingLib.base64Decode(base64Text);