or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

advanced-delivery.mdattachments-content.mdemail-service.mdindex.mdmessage-construction.mdtemplates-personalization.mdtracking-analytics.md

attachments-content.mddocs/

0

# Attachments and Content

1

2

Attachments and content management provide comprehensive support for file attachments, multiple content types, and rich media in emails. This includes file attachments, inline images, and various content formats.

3

4

## Capabilities

5

6

### File Attachments

7

8

Attach files to emails with support for various file types and configurations.

9

10

```javascript { .api }

11

// Attachment data structure

12

interface AttachmentData {

13

content: string; // Base64-encoded file content (required)

14

filename: string; // File name (required)

15

type?: string; // MIME type (optional, auto-detected if not provided)

16

disposition?: string; // "attachment" or "inline" (default: "attachment")

17

contentId?: string; // Content-ID for inline attachments (for <img> tags)

18

}

19

20

// Add attachments to email

21

const msg = {

22

to: 'recipient@example.com',

23

from: 'sender@example.com',

24

subject: 'Email with Attachments',

25

text: 'Please find attached files.',

26

attachments: [attachmentData]

27

};

28

```

29

30

**Usage Examples:**

31

32

```javascript

33

const fs = require('fs');

34

const path = require('path');

35

36

// Basic file attachment

37

const pdfAttachment = {

38

content: fs.readFileSync('./report.pdf', { encoding: 'base64' }),

39

filename: 'monthly-report.pdf',

40

type: 'application/pdf',

41

disposition: 'attachment'

42

};

43

44

const msg = {

45

to: 'client@example.com',

46

from: 'reports@example.com',

47

subject: 'Monthly Report',

48

text: 'Please find your monthly report attached.',

49

attachments: [pdfAttachment]

50

};

51

52

// Multiple attachments with different types

53

const attachments = [

54

{

55

content: fs.readFileSync('./invoice.pdf', { encoding: 'base64' }),

56

filename: 'invoice-2024-03.pdf',

57

type: 'application/pdf'

58

},

59

{

60

content: fs.readFileSync('./data.csv', { encoding: 'base64' }),

61

filename: 'export-data.csv',

62

type: 'text/csv'

63

},

64

{

65

content: fs.readFileSync('./image.jpg', { encoding: 'base64' }),

66

filename: 'product-photo.jpg',

67

type: 'image/jpeg'

68

}

69

];

70

71

const multiAttachmentMsg = {

72

to: 'customer@example.com',

73

from: 'orders@example.com',

74

subject: 'Order Complete - Invoice and Details',

75

html: '<p>Your order is complete. Please find attached your invoice and order details.</p>',

76

attachments: attachments

77

};

78

```

79

80

### Inline Images

81

82

Embed images directly in HTML emails using Content-ID references.

83

84

```javascript { .api }

85

// Inline image attachment

86

const inlineImage = {

87

content: base64ImageContent,

88

filename: 'image.jpg',

89

type: 'image/jpeg',

90

disposition: 'inline',

91

contentId: 'myimage' // Used in HTML as <img src="cid:myimage">

92

};

93

94

// HTML content referencing inline image

95

const htmlContent = `

96

<html>

97

<body>

98

<h1>Welcome!</h1>

99

<p>Here's our logo:</p>

100

<img src="cid:myimage" alt="Company Logo" width="200">

101

</body>

102

</html>

103

`;

104

```

105

106

**Usage Examples:**

107

108

```javascript

109

const fs = require('fs');

110

111

// Single inline image

112

const logoImage = {

113

content: fs.readFileSync('./logo.png', { encoding: 'base64' }),

114

filename: 'logo.png',

115

type: 'image/png',

116

disposition: 'inline',

117

contentId: 'company-logo'

118

};

119

120

const emailWithLogo = {

121

to: 'customer@example.com',

122

from: 'welcome@example.com',

123

subject: 'Welcome to Our Service',

124

html: `

125

<div style="text-align: center;">

126

<img src="cid:company-logo" alt="Welcome" style="max-width: 300px;">

127

<h1>Welcome to Example Corp!</h1>

128

<p>We're excited to have you on board.</p>

129

</div>

130

`,

131

attachments: [logoImage]

132

};

133

134

// Multiple inline images

135

const headerImage = {

136

content: fs.readFileSync('./header.jpg', { encoding: 'base64' }),

137

filename: 'header.jpg',

138

type: 'image/jpeg',

139

disposition: 'inline',

140

contentId: 'header-image'

141

};

142

143

const productImage = {

144

content: fs.readFileSync('./product.jpg', { encoding: 'base64' }),

145

filename: 'product.jpg',

146

type: 'image/jpeg',

147

disposition: 'inline',

148

contentId: 'product-image'

149

};

150

151

const newsletterMsg = {

152

to: 'subscriber@example.com',

153

from: 'newsletter@example.com',

154

subject: 'March Newsletter - New Products',

155

html: `

156

<html>

157

<body>

158

<img src="cid:header-image" alt="Newsletter Header" style="width: 100%; max-width: 600px;">

159

<h2>Featured Product This Month</h2>

160

<div style="display: flex; align-items: center;">

161

<img src="cid:product-image" alt="Product" style="width: 200px; margin-right: 20px;">

162

<div>

163

<h3>Amazing Product</h3>

164

<p>This month's featured product offers incredible value...</p>

165

</div>

166

</div>

167

</body>

168

</html>

169

`,

170

attachments: [headerImage, productImage]

171

};

172

```

173

174

### Attachment Class

175

176

Use the Attachment class for programmatic attachment creation and management.

177

178

```javascript { .api }

179

const { Attachment } = require('@sendgrid/helpers').classes;

180

181

/**

182

* Create a new attachment instance

183

* @param data - Optional initial attachment data

184

*/

185

const attachment = new Attachment(data);

186

187

// Setter methods

188

attachment.setContent(content); // Set base64 content

189

attachment.setFilename(filename); // Set filename

190

attachment.setType(type); // Set MIME type

191

attachment.setDisposition(disposition); // Set disposition

192

attachment.setContentId(contentId); // Set content ID

193

194

// Data population

195

attachment.fromData(data); // Populate from data object

196

197

// JSON conversion

198

const jsonData = attachment.toJSON(); // Convert to API format

199

```

200

201

**Usage Examples:**

202

203

```javascript

204

const { Attachment } = require('@sendgrid/helpers').classes;

205

const fs = require('fs');

206

207

// Create attachment using class

208

const attachment = new Attachment();

209

attachment.setContent(fs.readFileSync('./document.pdf', { encoding: 'base64' }));

210

attachment.setFilename('important-document.pdf');

211

attachment.setType('application/pdf');

212

attachment.setDisposition('attachment');

213

214

// Create multiple attachments programmatically

215

const files = [

216

{ path: './file1.txt', name: 'document1.txt', type: 'text/plain' },

217

{ path: './file2.jpg', name: 'image1.jpg', type: 'image/jpeg' },

218

{ path: './file3.pdf', name: 'report1.pdf', type: 'application/pdf' }

219

];

220

221

const attachments = files.map(file => {

222

const attachment = new Attachment();

223

attachment.setContent(fs.readFileSync(file.path, { encoding: 'base64' }));

224

attachment.setFilename(file.name);

225

attachment.setType(file.type);

226

return attachment;

227

});

228

229

const msg = {

230

to: 'recipient@example.com',

231

from: 'sender@example.com',

232

subject: 'Multiple Documents',

233

text: 'Please find all requested documents attached.',

234

attachments: attachments

235

};

236

```

237

238

### Content Types and Management

239

240

Manage various content types including text, HTML, and custom formats.

241

242

```javascript { .api }

243

// Content structure

244

interface MailContent {

245

type: string; // MIME type (e.g., "text/plain", "text/html")

246

value: string; // Content body

247

}

248

249

// Using Mail class for content management

250

const mail = new Mail();

251

252

// Content management methods

253

mail.setContent(content); // Set content array

254

mail.addContent(content); // Add single content item

255

mail.addTextContent(text); // Add plain text

256

mail.addHtmlContent(html); // Add HTML content

257

```

258

259

**Usage Examples:**

260

261

```javascript

262

const { Mail } = require('@sendgrid/helpers').classes;

263

264

// Multiple content types

265

const mail = new Mail();

266

mail.setFrom('sender@example.com');

267

mail.addTo('recipient@example.com');

268

mail.setSubject('Multi-format Email');

269

270

// Add text version

271

mail.addTextContent(`

272

Welcome to Our Service!

273

274

Thank you for signing up. Here are your next steps:

275

1. Verify your email address

276

2. Complete your profile

277

3. Start using our features

278

279

Best regards,

280

The Team

281

`);

282

283

// Add HTML version

284

mail.addHtmlContent(`

285

<html>

286

<body style="font-family: Arial, sans-serif;">

287

<h1 style="color: #333;">Welcome to Our Service!</h1>

288

<p>Thank you for signing up. Here are your next steps:</p>

289

<ol>

290

<li>Verify your email address</li>

291

<li>Complete your profile</li>

292

<li>Start using our features</li>

293

</ol>

294

<p style="color: #666;">Best regards,<br>The Team</p>

295

</body>

296

</html>

297

`);

298

299

// Custom content type (e.g., calendar invite)

300

mail.addContent({

301

type: 'text/calendar; method=REQUEST',

302

value: `BEGIN:VCALENDAR

303

VERSION:2.0

304

PRODID:-//Example Corp//CalDAV Client//EN

305

BEGIN:VEVENT

306

UID:meeting-12345@example.com

307

DTSTART:20240315T140000Z

308

DTEND:20240315T150000Z

309

SUMMARY:Team Meeting

310

DESCRIPTION:Weekly team sync meeting

311

ORGANIZER:mailto:organizer@example.com

312

ATTENDEE:mailto:recipient@example.com

313

END:VEVENT

314

END:VCALENDAR`

315

});

316

```

317

318

### File Upload Helpers

319

320

Utility functions for common file operations and encoding.

321

322

```javascript

323

// File encoding utility functions

324

function encodeFileToBase64(filePath) {

325

return fs.readFileSync(filePath, { encoding: 'base64' });

326

}

327

328

function createAttachmentFromFile(filePath, filename, mimeType) {

329

return {

330

content: encodeFileToBase64(filePath),

331

filename: filename || path.basename(filePath),

332

type: mimeType || getMimeType(filePath),

333

disposition: 'attachment'

334

};

335

}

336

337

function createInlineImageFromFile(filePath, contentId, filename) {

338

return {

339

content: encodeFileToBase64(filePath),

340

filename: filename || path.basename(filePath),

341

type: getMimeType(filePath),

342

disposition: 'inline',

343

contentId: contentId

344

};

345

}

346

347

// MIME type detection

348

function getMimeType(filePath) {

349

const ext = path.extname(filePath).toLowerCase();

350

const mimeTypes = {

351

'.pdf': 'application/pdf',

352

'.doc': 'application/msword',

353

'.docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',

354

'.xls': 'application/vnd.ms-excel',

355

'.xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',

356

'.jpg': 'image/jpeg',

357

'.jpeg': 'image/jpeg',

358

'.png': 'image/png',

359

'.gif': 'image/gif',

360

'.txt': 'text/plain',

361

'.csv': 'text/csv',

362

'.json': 'application/json',

363

'.zip': 'application/zip'

364

};

365

return mimeTypes[ext] || 'application/octet-stream';

366

}

367

```

368

369

**Usage Examples:**

370

371

```javascript

372

const fs = require('fs');

373

const path = require('path');

374

375

// Helper function usage

376

const documentAttachment = createAttachmentFromFile('./reports/monthly.pdf', 'March-Report.pdf');

377

const logoInline = createInlineImageFromFile('./assets/logo.png', 'company-logo');

378

379

const msg = {

380

to: 'client@example.com',

381

from: 'reports@example.com',

382

subject: 'Monthly Report with Branding',

383

html: `

384

<div>

385

<img src="cid:company-logo" alt="Logo" style="max-width: 200px;">

386

<h1>Monthly Report</h1>

387

<p>Please find your detailed monthly report attached.</p>

388

</div>

389

`,

390

attachments: [documentAttachment, logoInline]

391

};

392

393

// Batch file processing

394

const attachmentDirectory = './attachments';

395

const files = fs.readdirSync(attachmentDirectory);

396

397

const attachments = files

398

.filter(file => !file.startsWith('.')) // Skip hidden files

399

.map(file => createAttachmentFromFile(

400

path.join(attachmentDirectory, file),

401

file

402

));

403

404

const batchMsg = {

405

to: 'recipient@example.com',

406

from: 'sender@example.com',

407

subject: `Batch Documents - ${attachments.length} files`,

408

text: `Please find ${attachments.length} documents attached.`,

409

attachments: attachments

410

};

411

```

412

413

## Best Practices

414

415

### File Size and Performance

416

417

1. **Optimize file sizes**: Compress images and documents before attaching

418

2. **Base64 encoding overhead**: Remember that base64 encoding increases file size by ~33%

419

3. **Email size limits**: Keep total email size under 25MB (including all attachments)

420

4. **Consider alternatives**: For large files, consider linking to cloud storage instead

421

422

### Security Considerations

423

424

1. **Validate file types**: Only allow expected file extensions

425

2. **Scan for malware**: Consider virus scanning for user-uploaded attachments

426

3. **Content-ID security**: Use unique, non-guessable content IDs for inline images

427

4. **File name sanitization**: Sanitize file names to prevent directory traversal

428

429

### Deliverability Impact

430

431

1. **Attachment reputation**: Some file types (like .exe) may trigger spam filters

432

2. **Image optimization**: Optimize inline images for email clients

433

3. **Alternative text**: Always provide alt text for images

434

4. **Fallback content**: Provide text alternatives for rich content

435

436

### Error Handling

437

438

```javascript

439

sgMail.send(msgWithAttachments)

440

.catch(error => {

441

if (error.response && error.response.body) {

442

const { errors } = error.response.body;

443

444

errors.forEach(err => {

445

if (err.field === 'attachments') {

446

console.error('Attachment error:', err.message);

447

// Common issues: file too large, invalid base64, unsupported type

448

} else if (err.field === 'content') {

449

console.error('Content error:', err.message);

450

// Common issues: missing required content, invalid HTML

451

}

452

});

453

}

454

});

455

```