Attachment in Mailgun

Hello, I’m struggling to add an image as attachment. I looked around on stackoverflow, this forum and the mailgun API documentation but i just can’t figure it out. This is what I’m trying right now.

 sendAtt(pictures: any[]){
     var requestHeaders = new Headers();
        requestHeaders.append("Authorization", "Basic " + this.apiKey);
        requestHeaders.append("Content-Type", "application/x-www-form-urlencoded");
        this.http.request(new Request({
                method: RequestMethod.Post,
                url: "" + this.mailgunUrl + "/messages",
                body: "from="+this.sender+"&to=" + this.recipient + "&subject=" + this.subject + "&text=" + this.message +"&attachment="+pictures[0] ,
                headers: requestHeaders,
            .subscribe(success => {
                console.log("SUCCESS -> " + JSON.stringify(success));
            }, error => {
                console.log("ERROR -> " + JSON.stringify(error));

The email is actually getting sent but without the image. The array contains the base64images and it’s the same array I use to show them in the application (where it does work).

I have no experience, but looked at the API docs for a second: -> attachment:

attachment => File attachment. You can post multiple attachment values.
Important: You must use multipart/form-data encoding when sending attachments.

But there also seems to be ready made JS packages for Mailgun:
Might be easier to use one of these…

Do I have to swap “application/x-www-form-urlencoded” with “multipart/form-data”?

Probably. A library would handle that for you.

Do they work for Typescript as well because I can’t get it done.

No idea. If you can’t use them, you can at least look inside and see how they do it.

Struggling with this right now too. None of the NPM modules work with ES6+Typescript, and changing to multipart/form-data is more complicated than simply changing the Content-Type header.

Got it to work - can confirm that we DO need to use multipart/form-data, but it’s not intuitive. Here’s a sample:

options = new RequestOptions({
    headers: new Headers({
        "Authorization": `Basic ${this.mailgunBase64Key}`

const formData = new FormData();
formData.append('from', this.recipient);
formData.append('to', this.recipient);
formData.append('subject', this.subject);
formData.append('html', html);
formData.append('attachment', attachment, 'report.txt');, formData, this.options))
.map(result => result.json())
    result => console.log('success!', result),
    error => console.error('fail', error)

The part that caught me off-guard is not actually specifying the Content-Type header… I guess this is implied when using a FormData() body? Took me nearly all day to figure that out :tired_face:. The POST does send as that however, pay attention to that Network devtools tab.

How you “build” your attachment is another issue entirely. I’ve been trying to get a .zip to send with no luck (Gmail keeps blocking them!) but I do have text files working - here’s how I get those:

.map(result => new Blob([result.text()], { type: 'text/plain' }) );

Looks like we’re both using Observables, hopefully this makes enough sense, I extracted it from a larger class.

1 Like