Tools Blog Learn Quizzes Smile API Log In / Sign Up
Tools Blog Learn Quizzes Smile API Log In / Sign Up
« Return to the tutorials list
We have updated our privacy policy to let you know that we use cookies to personalise content and ads. We also use cookies to analyse our traffic and we share information about your use of our site and application with our advertising and analytics partners. By using this website or our application you agree to our use of cookies. Learn more about the way this website uses cookies or remove this message.

Send emails with attachments using JavaScript

October 16, 2016 Difficulty: 15 / 50 Tweet
mail-with-javascript

Update: October 16th, 2016

My Mandrill API Key stopped working a few months ago, when they became a paid service @MailChimp (source). I have updated the code below and you should be able to use the demo now.

Even so, if Mandrill ever dies again, you can use any other service with the same logic described in this tutorial. The JavaScript logic remains exactly the same.

Update: December 22nd, 2015

Reading file data as dataUrl ... using filereader.readAsDataURL(file) causes broken attachments. I updated the code to use arrayBuffer and then convert that to base64 and all my tests with various file types worked. I updated the code below and the gist.

Original article from November 2015

A few days ago a client asked me if I could send out emails with attachments using client side code only. At first I laughed, asking myself why would anyone want to do that, but then I thought: "Who cares! Whatever the client wants!". In the end I did find out that this was caused because of the hosting environment that he used which didn't allow any type of server-side code to be executed (Sooooo weird!).

Anyway, because I am a Mandrill subscriber myself I decided to use their API to meet this unusual request. I needed to be able to add attachments, so the challenge was to read the contents of the uploaded file and send it as an encoded string to the API end-point at Mandrill as mentioned in their documentation. I achieved this through the FileReader API. Once I had that, I just assembled the request pay-load and sent it to Mandrill who in turn did all the hard work.

Below is the JavaScript code and I've also assembled a demo that outputs the response from Mandrill. I also uploaded a gist for convenience.

Don't bother using the same API key, it doesn't actually send out any emails.

    
        <script>
            var MandrillApi = {};
            MandrillApi.key = 'VoyzlheXND-Imx1UoGqtqw';
            MandrillApi.theform = $('#demo');

            MandrillApi.arrayBufferToProperBase64 = function(buffer) {
                var binary = '';
                var bytes = new Uint8Array( buffer );
                var len = bytes.byteLength;
                for (var i = 0; i < len; i++) {
                    binary += String.fromCharCode( bytes[ i ] );
                }
                return window.btoa( binary );
            };

            MandrillApi.processFile = function() {
                'use strict';
                var theform = this.theform;
                console.log(theform.find('input[type=file]'));
                var thefile = theform.find('input[type=file]')[0].files[0];
                var reader = new FileReader();
                var thefiledata;
                var self = this;
                thefiledata = reader.readAsArrayBuffer(thefile);

                reader.onloadend = function () {
                    /*PUSH FILE CONTENTS TO THE CALLBACK THAT SENDS THE MESSAGE*/
                    MandrillApi.sendEmail(self.arrayBufferToProperBase64(reader.result));
                };
            };

            MandrillApi.sendEmail = function(fileData) {
                'use strict';
                var theApiData = {};
                var thefile = this.theform.find('input[type=file]')[0].files[0];
                var thefiledata = fileData;

                theApiData.key = this.key;
                theApiData.message = {
                    "html": $("#html").val(), //add your html here
                    "text": "", //add your text here
                    "subject": "This is a demo email", //add your subject here
                    "from_email": "info@codepunker.com", //add your from field here
                    "from_name": "CodePunker", //add your from name here
                    "to": [
                        {
                            "email": "anotheremail@codepunker.com", //add your to email addr here
                            "name": "",
                            "type": "to" //bcc or cc
                        }
                    ],
                    "attachments": [
                        {
                            "type": thefile.type, //file type
                            "name": thefile.name, //file name
                            "content": thefiledata //file contents
                        }
                    ],
                };
                //now send the request
                $.ajax({
                    url: "https://mandrillapp.com/api/1.0/messages/send.json",
                    type: 'POST',
                    data: theApiData,
                    async: false,
                }).done(function (data) {
                    var r = JSON.stringify(data);
                    $("#output").val(JSON.stringify(r), null, '\t');
                });
            };

            //init
            MandrillApi.theform.submit(function(e){
                e.preventDefault();
                MandrillApi.processFile();
            });
        </script>
    
comments powered by Disqus

Better Docs For A Better Web - Mozilla Developer Network

Alerts

2017-01-17 - The php_wddx_push_element function in ext/wddx/wddx.c in PHP before 5.6.29 and 7.x before 7.0.14 allows remote attackers to cause a denial of service (out-of-bounds read and memory corruption) or possibly have unspecified other impact via an empty boolean element in a wddxPacket XML document. Read more ...
2017-01-17 - The get_icu_value_internal function in ext/intl/locale/locale_methods.c in PHP before 5.5.36, 5.6.x before 5.6.22, and 7.x before 7.0.7 does not ensure the presence of a '\0' character, which allows remote attackers to cause a denial of service (out-of-bounds read) or possibly have unspecified other impact via a crafted locale_get_primary_language call. Read more ...

See All Entries...