Skip to main content

Overview

GoBlue supports sending various types of attachments alongside your automated messages, including images, documents, links, and rich media content. This capability enhances your messaging by providing visual context, supporting materials, and interactive elements that increase engagement and effectiveness.
Attachment support depends on the recipient’s device and messaging platform. iMessage supports rich attachments, while SMS has more limitations.

Supported Attachment Types

Media Attachments

Images

Formats: JPG, PNG, GIF, HEIC Max Size: 10 MB per image Use Cases: Product photos, screenshots, infographics, QR codes

Videos

Formats: MP4, MOV, M4V Max Size: 100 MB per video Use Cases: Product demos, tutorials, testimonials

Audio

Formats: MP3, M4A, WAV Max Size: 25 MB per audio file Use Cases: Voice messages, audio previews, recordings

Documents

Formats: PDF, DOC, DOCX, XLS, XLSX, PPT, PPTX Max Size: 50 MB per document Use Cases: Proposals, contracts, presentations, reports
GoBlue automatically generates rich previews for web links:

Adding Attachments to Messages

Method 1: URL-Based Attachments

Include attachment URLs in your webhook data:
{
  "firstName": "Sarah",
  "phoneNumber": "+1234567890",
  "serviceType": "web development",
  "attachments": [
    {
      "type": "image",
      "url": "https://yoursite.com/images/portfolio-sample.jpg",
      "caption": "Sample of our recent work"
    },
    {
      "type": "document", 
      "url": "https://yoursite.com/files/service-guide.pdf",
      "filename": "Web Development Service Guide.pdf"
    }
  ]
}
Message Template:
Hi {{firstName}},

Thanks for your interest in {{serviceType}}! 

I've attached a sample of our recent work and our service guide for your review.

Looking forward to discussing your project!

Best regards,
{{agentName}}

{{#attachments}}
📎 {{caption}}
{{/attachments}}

Method 2: Dynamic Attachment Selection

Use form data to determine which attachments to include:
// Example: Industry-specific attachments
const attachmentLibrary = {
  'healthcare': [
    {
      type: 'document',
      url: 'https://yoursite.com/docs/hipaa-compliance.pdf',
      filename: 'HIPAA Compliance Guide.pdf'
    }
  ],
  'e-commerce': [
    {
      type: 'image',
      url: 'https://yoursite.com/images/ecommerce-portfolio.jpg',
      caption: 'E-commerce Projects Portfolio'
    }
  ],
  'saas': [
    {
      type: 'video',
      url: 'https://yoursite.com/videos/saas-demo.mp4',
      caption: 'SaaS Platform Demo'
    }
  ]
};

function selectAttachments(contactData) {
  const industry = contactData.industry || contactData.serviceType;
  return attachmentLibrary[industry] || [];
}

Method 3: iOS Shortcuts Integration

Configure iOS Shortcuts to handle different attachment types:
  • Image Attachments
  • Document Attachments
  • Multiple Attachments
Shortcut Steps:
  1. Get message content from GoBlue
  2. Extract attachment URLs from message data
  3. Download images to Photos app
  4. Send message with images attached
GoBlue Integration:
{
  "messageContent": "Hi John, here's the mockup you requested!",
  "attachments": [
    {
      "type": "image",
      "url": "https://yoursite.com/mockups/johns-project.png"
    }
  ]
}

Attachment Strategies by Use Case

Sales and Lead Generation

Attachment Types: Images, videos, PDFs Template Example:
Hi {{firstName}},

Thanks for your interest in {{serviceType}}! 

I've attached some samples of our work with similar {{industryType}} clients. The {{attachmentDescription}} should give you a good sense of our capabilities.

I'd love to discuss how we could create something similar for {{companyName}}.

Available for a quick call this week?

Best,
{{agentName}}
Dynamic Attachment Selection:
function selectPortfolioSamples(industry, budget) {
  const samples = portfolioLibrary[industry] || [];
  
  // Filter by budget tier
  if (budget < 5000) {
    return samples.filter(s => s.tier === 'basic');
  } else if (budget > 20000) {
    return samples.filter(s => s.tier === 'premium');
  }
  
  return samples.filter(s => s.tier === 'standard');
}
Attachment Types: PDFs, spreadsheets, presentations Template Example:
Hi {{firstName}},

I've prepared a custom proposal for your {{projectType}} project.

The attached document includes:
• Project timeline and milestones
• Detailed pricing breakdown
• Team member profiles
• Similar client case studies

Please review and let me know if you have any questions. I'm available to discuss any aspects of the proposal.

Looking forward to working together!

{{agentName}}
Attachment Types: PDFs, images, videos Implementation:
function selectCaseStudies(contactData) {
  const relevant = caseStudyLibrary.filter(study => 
    study.industry === contactData.industry ||
    study.projectType === contactData.serviceType ||
    study.companySize === contactData.companySize
  );
  
  // Return top 2-3 most relevant
  return relevant
    .sort((a, b) => b.relevanceScore - a.relevanceScore)
    .slice(0, 3);
}

Customer Service and Support

Use Case: Onboarding new customers Template:
Hi {{firstName}},

Welcome to {{productName}}! 

I've attached a quick video tutorial that will help you get started with {{specificFeature}}.

The video is just {{videoDuration}} and covers:
• Initial setup steps
• Key features for your {{useCase}}
• Pro tips for maximum efficiency

Watch when convenient, and feel free to reach out with any questions!

{{supportTeamName}}
Attachment Types: PDFs, screenshots, screen recordings Dynamic Content:
function generateTroubleshootingGuide(issueType, userPlatform) {
  const guide = {
    steps: getTroubleshootingSteps(issueType),
    screenshots: getScreenshots(issueType, userPlatform),
    additionalInfo: getAdditionalResources(issueType)
  };
  
  return generatePDF(guide);
}

E-commerce and Retail

Use Case: Order confirmations, product recommendations Template:
Hi {{firstName}},

Your order #{{orderNumber}} has shipped! 🎉

I've attached photos of your {{productName}} being carefully packaged. Your order includes:

{{#orderItems}}
• {{itemName}} ({{quantity}}x)
{{/orderItems}}

Tracking: {{trackingUrl}}
Expected delivery: {{deliveryDate}}

Thanks for choosing {{companyName}}!
Attachment Types: Images, PDFs Implementation:
function attachSizeGuide(productCategory, customerData) {
  const sizeChart = getSizeChart(productCategory);
  const personalizedGuide = generatePersonalizedGuide(
    sizeChart, 
    customerData.previousOrders
  );
  
  return {
    type: 'image',
    url: personalizedGuide.url,
    caption: `Size guide for ${productCategory}`
  };
}

Advanced Attachment Features

Conditional Attachments

Use webhook data to determine which attachments to include:
{
  "firstName": "John",
  "phoneNumber": "+1234567890",
  "serviceType": "web development",
  "budget": "$10,000+",
  "hasSeenDemo": false,
  "industry": "healthcare",
  "attachmentRules": [
    {
      "condition": "budget > 5000",
      "attachments": ["premium-portfolio.pdf", "enterprise-case-study.pdf"]
    },
    {
      "condition": "hasSeenDemo === false",
      "attachments": ["product-demo-video.mp4"]
    },
    {
      "condition": "industry === 'healthcare'",
      "attachments": ["hipaa-compliance-doc.pdf"]
    }
  ]
}

Personalized Attachments

Generate custom attachments based on recipient data:
class PersonalizedAttachmentGenerator {
  async generateProposal(contactData) {
    const template = await this.getProposalTemplate();
    
    const personalizedData = {
      clientName: `${contactData.firstName} ${contactData.lastName}`,
      companyName: contactData.companyName,
      projectDetails: contactData.projectDescription,
      timeline: contactData.timeline,
      budget: contactData.budget,
      customizations: this.getRecommendations(contactData)
    };
    
    const proposalPDF = await this.generatePDF(template, personalizedData);
    
    return {
      type: 'document',
      url: proposalPDF.url,
      filename: `Proposal_${contactData.companyName}_${Date.now()}.pdf`
    };
  }
  
  async generateQRCode(contactData, campaign) {
    const qrData = {
      url: `${campaign.landingPageUrl}?ref=${contactData.id}`,
      contactId: contactData.id,
      campaignId: campaign.id
    };
    
    const qrImage = await this.generateQR(qrData);
    
    return {
      type: 'image',
      url: qrImage.url,
      caption: 'Scan to access your personalized page'
    };
  }
}

Interactive Attachments

Create attachments that encourage engagement:
  • QR Codes
  • Survey Forms
Use Cases:
  • Event registration
  • Exclusive offers
  • Contact information sharing
  • App downloads
function createQRCode(action, contactId) {
  const qrData = {
    action: action,
    contactId: contactId,
    timestamp: Date.now(),
    trackingUrl: `https://yoursite.com/track/${action}/${contactId}`
  };
  
  return generateQRCode(qrData);
}

Technical Implementation

File Storage and Management

Supported Services: AWS S3, Google Cloud Storage, Azure Blob
class AttachmentManager {
  async uploadFile(file, metadata) {
    const storageKey = `attachments/${metadata.campaignId}/${file.name}`;
    
    const uploadResult = await this.cloudStorage.upload({
      key: storageKey,
      body: file.buffer,
      contentType: file.mimeType,
      metadata: {
        originalName: file.name,
        uploadedBy: metadata.userId,
        campaignId: metadata.campaignId,
        expiresAt: metadata.expiresAt
      }
    });
    
    return {
      url: uploadResult.publicUrl,
      storageKey: storageKey,
      size: file.size,
      contentType: file.mimeType
    };
  }
}
Benefits: Faster downloads, global distribution, bandwidth optimization
function generateCDNUrl(attachmentKey, transformations = {}) {
  const baseUrl = 'https://cdn.yoursite.com';
  const params = new URLSearchParams();
  
  // Image transformations
  if (transformations.width) params.set('w', transformations.width);
  if (transformations.height) params.set('h', transformations.height);
  if (transformations.quality) params.set('q', transformations.quality);
  
  return `${baseUrl}/${attachmentKey}?${params.toString()}`;
}

iOS Shortcuts Integration

Shortcut Structure for Attachments:
1

Retrieve Message Data

Get message content and attachment metadata from GoBlue API
2

Download Attachments

// Download each attachment
for (const attachment of message.attachments) {
  const fileData = await downloadFile(attachment.url);
  attachmentFiles.push({
    data: fileData,
    filename: attachment.filename || extractFilename(attachment.url),
    type: attachment.type
  });
}
3

Prepare Message

Combine text content with attachment files
4

Send via iMessage

Use iOS Shortcuts actions to send message with attachments
5

Update Status

Report delivery status back to GoBlue

Error Handling

const sizeLimits = {
  image: 10 * 1024 * 1024,    // 10 MB
  video: 100 * 1024 * 1024,  // 100 MB
  document: 50 * 1024 * 1024, // 50 MB
  audio: 25 * 1024 * 1024     // 25 MB
};

function validateFileSize(attachment) {
  const limit = sizeLimits[attachment.type];
  if (attachment.size > limit) {
    throw new Error(`File too large: ${attachment.type} limit is ${limit} bytes`);
  }
}
async function downloadWithRetry(url, maxRetries = 3) {
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    try {
      const response = await fetch(url, { timeout: 30000 });
      if (response.ok) {
        return await response.buffer();
      }
    } catch (error) {
      if (attempt === maxRetries) {
        throw new Error(`Failed to download after ${maxRetries} attempts: ${error.message}`);
      }
      
      // Wait before retry
      await new Promise(resolve => setTimeout(resolve, attempt * 1000));
    }
  }
}
function handleAttachmentFailure(message, failedAttachment) {
  // Remove failed attachment
  message.attachments = message.attachments.filter(a => a !== failedAttachment);
  
  // Add fallback text
  message.content += `\n\n📎 Attachment unavailable. View online: ${failedAttachment.fallbackUrl}`;
  
  // Log for manual review
  this.logAttachmentFailure(message.id, failedAttachment);
  
  return message;
}

Analytics and Tracking

Attachment Performance Metrics

Engagement Metrics

  • Download Rate: % of recipients who download attachments
  • View Time: How long recipients view media
  • Click-through Rate: Clicks on links in attachments
  • Sharing Rate: How often attachments are forwarded

Technical Metrics

  • Delivery Success Rate: % of attachments delivered successfully
  • File Size Impact: Effect on message delivery time
  • Format Performance: Which file types perform best
  • Error Rates: Common attachment failures

Tracking Implementation

class AttachmentAnalytics {
  trackAttachmentPerformance(messageId, attachmentId, event) {
    const trackingData = {
      messageId: messageId,
      attachmentId: attachmentId,
      event: event, // 'sent', 'downloaded', 'viewed', 'shared'
      timestamp: new Date().toISOString(),
      userAgent: this.getUserAgent(),
      ipAddress: this.getClientIP()
    };
    
    return this.analytics.track('attachment_event', trackingData);
  }
  
  generateAttachmentReport(campaignId) {
    const attachmentStats = this.getAttachmentStats(campaignId);
    
    return {
      totalAttachments: attachmentStats.total,
      deliveryRate: attachmentStats.delivered / attachmentStats.total,
      downloadRate: attachmentStats.downloaded / attachmentStats.delivered,
      topPerformingTypes: this.getTopPerformingTypes(attachmentStats),
      sizingRecommendations: this.getSizingRecommendations(attachmentStats)
    };
  }
}

Best Practices

Content Guidelines

File Optimization

  • Compress images without losing quality
  • Use appropriate formats (JPEG for photos, PNG for graphics)
  • Keep file sizes reasonable for mobile networks
  • Test downloads on different connection speeds

Accessibility

  • Include alt text for images
  • Provide text descriptions for videos
  • Use descriptive filenames
  • Consider recipients with disabilities

Security

  • Don’t include sensitive information in filenames
  • Use secure, expiring URLs for confidential documents
  • Scan files for malware before sending
  • Implement access controls for attachments

User Experience

  • Preview attachments in your message text
  • Explain why you’re including attachments
  • Provide alternative access methods
  • Keep attachment lists concise

Performance Optimization

// Only download attachments when message is being sent
async function prepareMessageForSending(message) {
  const attachments = await Promise.all(
    message.attachmentUrls.map(url => this.downloadAttachment(url))
  );
  
  return {
    ...message,
    attachments: attachments.filter(a => a !== null) // Remove failed downloads
  };
}
class AttachmentCache {
  constructor() {
    this.cache = new Map();
    this.maxSize = 100 * 1024 * 1024; // 100 MB cache
  }
  
  async getAttachment(url) {
    if (this.cache.has(url)) {
      return this.cache.get(url);
    }
    
    const attachment = await this.downloadAttachment(url);
    
    if (this.getCacheSize() + attachment.size <= this.maxSize) {
      this.cache.set(url, attachment);
    }
    
    return attachment;
  }
}

Next Steps

Test your attachments across different devices and network conditions to ensure a consistent experience for all recipients.