Attaching images to emails in Ionic 2 using Mailgun

I’m having trouble sending emails with image attachments in my Ionic 2 app using Mailgun. The email sending part works fine but the attachments aren’t going through. I’ve tried looking at forums and the API docs but I’m stuck.

Here’s my code for sending the email:

sendEmailWithPictures(imageArray: string[]) {
  const headers = new Headers();
  headers.append('Authorization', `Basic ${this.mailgunKey}`);
  headers.append('Content-Type', 'application/x-www-form-urlencoded');

  const body = `from=${this.fromAddress}&to=${this.toAddress}&subject=${this.emailSubject}&text=${this.emailBody}&attachment=${imageArray[0]}`;

  this.http.post(`https://api.mailgun.net/v3/${this.mailgunDomain}/messages`, body, { headers })
    .subscribe(
      response => console.log('Email sent:', response),
      error => console.error('Email error:', error)
    );
}

The imageArray contains base64 strings of the pictures. These display correctly in the app so I think that part is okay. Any ideas on what I’m doing wrong with the attachment? Thanks for your help!

I’ve encountered a similar issue when working with Mailgun attachments. The problem likely stems from how you’re handling the attachment in the request body. For Mailgun, you need to send attachments as multipart/form-data, not as x-www-form-urlencoded.

Try modifying your code to use FormData instead. Here’s a rough example:

let formData = new FormData();
formData.append('from', this.fromAddress);
formData.append('to', this.toAddress);
formData.append('subject', this.emailSubject);
formData.append('text', this.emailBody);

imageArray.forEach((base64String, index) => {
  let blob = this.base64ToBlob(base64String);
  formData.append('attachment', blob, `image${index}.jpg`);
});

this.http.post(`https://api.mailgun.net/v3/${this.mailgunDomain}/messages`, formData, { headers })
  .subscribe(/* ... */);

You’ll need to implement the base64ToBlob function. This approach should correctly send the attachments. Hope this helps!

I’ve dealt with this exact issue in a recent project. The key is using FormData, as others mentioned, but there’s a crucial step missing: converting base64 to a Blob.

Here’s what worked for me:

sendEmailWithPictures(imageArray: string[]) {
  const formData = new FormData();
  formData.append('from', this.fromAddress);
  formData.append('to', this.toAddress);
  formData.append('subject', this.emailSubject);
  formData.append('text', this.emailBody);

  imageArray.forEach((base64, index) => {
    const imageBlob = this.base64ToBlob(base64.split(',')[1], 'image/jpeg');
    formData.append('attachment', imageBlob, `image${index}.jpg`);
  });

  const headers = new Headers();
  headers.append('Authorization', `Basic ${this.mailgunKey}`);

  this.http.post(`https://api.mailgun.net/v3/${this.mailgunDomain}/messages`, formData, { headers })
    .subscribe(
      response => console.log('Email sent:', response),
      error => console.error('Email error:', error)
    );
}

base64ToBlob(base64: string, type: string = 'image/jpeg'): Blob {
  const byteCharacters = atob(base64);
  const byteArrays = [];

  for (let offset = 0; offset < byteCharacters.length; offset += 512) {
    const slice = byteCharacters.slice(offset, offset + 512);
    const byteNumbers = new Array(slice.length);
    for (let i = 0; i < slice.length; i++) {
      byteNumbers[i] = slice.charCodeAt(i);
    }
    const byteArray = new Uint8Array(byteNumbers);
    byteArrays.push(byteArray);
  }

  return new Blob(byteArrays, { type });
}

This approach should solve your attachment issues. Let me know if you need any clarification!

hey mate, had the same headache with mailgun attachments. try using formdata instead of a string for the body. something like:

let formData = new FormData();
formData.append('from', fromAddress);
formData.append('to', toAddress);
// ... other fields ...
imageArray.forEach(img => formData.append('attachment', img));

ten send that formData in ur post request. should do the trick!