MailWithAttachment: Send Files Quickly from Your App
Sending files by email directly from your application saves users time and smooths workflows. This guide shows a concise, practical approach to implementing a MailWithAttachment feature: how it works, security considerations, and example code in three common languages so you can add file-sending capability quickly.
How it works (overview)
- Process: Your app composes an email message, attaches one or more files, and sends it via an SMTP server or an email-sending API (e.g., SendGrid, Mailgun).
- Components: message body, recipients, subject, attachments (binary or streamed), authentication for the mail service, and optional metadata (content type, filename).
- Flow: validate file → prepare attachment metadata → attach to message (proper encoding) → authenticate to mail server/API → send → handle response/errors.
Security & reliability checklist
- Validate file types and sizes to prevent abuse and unexpected load.
- Scan for malware if users upload files (integrate antivirus or use cloud scanning).
- Use authenticated SMTP or a trusted API with TLS (SMTPS or STARTTLS).
- Limit attachment size (both app-side and enforced server-side).
- Stream large files instead of loading into memory when possible.
- Log actions and errors (avoid logging raw file data).
- Provide user feedback on success/failure and progress for large uploads.
Key implementation notes
- Attachments must be encoded (usually Base64) for SMTP MIME messages. APIs often accept raw binary via multipart/form-data or direct file uploads.
- Set correct MIME types (Content-Type) and include filename in headers (Content-Disposition).
- For multiple attachments, build a multipart/mixed MIME message and include a multipart/alternative section for HTML/plain text body if needed.
- For performance, upload files to object storage (S3, Azure Blob) and include signed download links in email if attachments exceed safe email sizes.
Example: C# (.NET) — SMTP with MailKit
csharp
using MailKit.Net.Smtp; using MimeKit; using System.IO; public void SendWithAttachment(string smtpHost, int smtpPort, string user, string pass, string from, string to, string subject, string bodyHtml, string filePath) { var message = new MimeMessage(); message.From.Add(MailboxAddress.Parse(from)); message.To.Add(MailboxAddress.Parse(to)); message.Subject = subject; var builder = new BodyBuilder { HtmlBody = bodyHtml, TextBody = “See attached.” }; if (File.Exists(filePath)) { builder.Attachments.Add(filePath); } message.Body = builder.ToMessageBody(); using var client = new SmtpClient(); client.Connect(smtpHost, smtpPort, MailKit.Security.SecureSocketOptions.StartTls); client.Authenticate(user, pass); client.Send(message); client.Disconnect(true); }
Example: Python — SMTP with smtplib and email
python
import smtplib from email.message import EmailMessage import mimetypes def send_with_attachment(smtp_host, smtp_port, user, password, sender, recipient, subject, html_body, file_path): msg = EmailMessage() msg[‘From’] = sender msg[‘To’] = recipient msg[‘Subject’] = subject msg.set_content(“See attached file.”) msg.add_alternative(html_body, subtype=‘html’) ctype, encoding = mimetypes.guess_type(file_path) maintype, subtype = (ctype or ‘application/octet-stream’).split(’/’, 1) with open(file_path, ‘rb’) as f: msg.add_attachment(f.read(), maintype=maintype, subtype=subtype, filename=file_path.split(’/’)[-1]) with smtplib.SMTP(smtp_host, smtp_port) as s: s.starttls() s.login(user, password) s.sendmessage(msg)
Example: Node.js — Using Nodemailer
javascript
const nodemailer = require(‘nodemailer’); async function sendWithAttachment(smtpHost, smtpPort, user, pass, from, to, subject, html, filePath) { let transporter = nodemailer.createTransport({ host: smtpHost, port: smtpPort, secure: false, auth: { user, pass } }); let info = await transporter.sendMail({ from, to, subject, html, attachments: [{ path: filePath }] }); return info; }
Handling large files
- If file sizes exceed typical email limits (10–25 MB), upload to cloud storage and include a secure, time-limited download link in the email.
- Use resumable uploads for reliability. Provide a clear UI for progress and cancellations.
Error handling & retries
- Retry transient errors (network, temporary SMTP failures) with exponential backoff.
- Surface permanent errors (authentication, invalid recipient) to the user immediately.
- Track delivery status where possible (webhooks or SMTP DSNs).
UX considerations
- Show upload progress and estimated time for large files.
- Let users remove or rename attachments before sending.
- Warn users about attachment size limits and acceptable file types.
Quick checklist to ship
- Validate uploads (type, size).
- Scan or delegate scanning of files.
- Attach with correct MIME and filename.
- Use TLS and authenticated mail/API service.
- Stream large files or provide download links.
- Implement retries and clear error messages.
Implementing MailWithAttachment can be straightforward using existing libraries and APIs; follow the checklist above for security and reliability, and use the code samples to get started quickly.
Leave a Reply