Skip to main content

Overview

Fluxer provides comprehensive support for rich media content including file attachments, embedded content, automatic link previews (unfurling), and rich embed objects for creating visually appealing messages.

File Attachments

Upload and share images, videos, documents, and more

Rich Embeds

Structured content with titles, descriptions, and media

Link Previews

Automatic unfurling of websites, social media, and more

Attachment References

Reference uploaded files in embeds with attachment:// URLs

File Attachments

Attachments allow users to share files of various types.

Uploading Attachments

1

Upload to Storage

// First, upload the file to get an upload ID
const formData = new FormData();
formData.append('file', fileBlob, 'image.png');

const uploadResponse = await fetch('/api/upload', {
  method: 'POST',
  headers: { 'Authorization': `Bearer ${token}` },
  body: formData
});

const { upload_filename } = await uploadResponse.json();
2

Send Message with Attachment

const message = await messageSendService.sendMessage({
  user,
  channelId,
  data: {
    content: 'Check out this image!',
    attachments: [
      {
        upload_filename, // From upload step
        filename: 'image.png',
        description: 'A beautiful sunset',
        is_spoiler: false
      }
    ]
  },
  requestCache
});

Attachment Types

Fluxer handles different file types with specialized rendering:
// Supported: PNG, JPEG, GIF, WEBP
{
  filename: 'photo.jpg',
  content_type: 'image/jpeg',
  width: 1920,
  height: 1080,
  size: 245680,
  url: 'https://cdn.fluxer.com/attachments/...',
  proxy_url: 'https://media.fluxer.com/attachments/...'
}
Images are automatically resized and optimized for display. Original files are preserved.

Attachment Limits

Max File Size
number
Default: 8 MB per file (configurable via limits)
Max Attachments
number
Default: 10 files per message
Total Message Size
number
All attachments + content must be under total size limit

Spoiler Attachments

// Mark attachment as spoiler (blurred until clicked)
const message = await messageSendService.sendMessage({
  user,
  channelId,
  data: {
    content: 'Major spoilers ahead!',
    attachments: [
      {
        upload_filename,
        filename: 'SPOILER_ending.png', // Prefix with SPOILER_
        is_spoiler: true
      }
    ]
  },
  requestCache
});

Rich Embeds

Embeds are structured content blocks with titles, descriptions, colors, images, and fields.

Creating Embeds

const message = await messageSendService.sendMessage({
  user,
  channelId,
  data: {
    content: 'Check this out:',
    embeds: [
      {
        title: 'Announcement',
        description: 'We have some exciting news to share!',
        color: 0x5865F2, // Blurple
        timestamp: new Date().toISOString()
      }
    ]
  },
  requestCache
});

Embed Structure

title
string
Main title (max 256 characters)
description
string
Main content (max 4096 characters, supports markdown)
url
string
URL that title links to
color
integer
Color code of the embed’s left border (hex as decimal)
timestamp
string
ISO 8601 timestamp displayed in footer
author
object
Author information displayed at top
  • name: Author name (256 chars)
  • url: URL author name links to
  • icon_url: Small icon next to author name
thumbnail
object
Small image displayed in top-right
  • url: Image URL
  • width: Image width (optional)
  • height: Image height (optional)
image
object
Large image displayed in embed body
  • url: Image URL or attachment://filename
  • width: Image width (optional)
  • height: Image height (optional)
Footer text and icon
  • text: Footer text (2048 chars)
  • icon_url: Small footer icon
fields
array
Array of field objects (max 25)
  • name: Field name (256 chars)
  • value: Field value (1024 chars)
  • inline: Whether field displays inline (boolean)

Embed Limits

Total characters across all embed fields must not exceed 6000 characters.
  • Title: 256 characters
  • Description: 4096 characters
  • Fields: 25 maximum
  • Field name: 256 characters
  • Field value: 1024 characters
  • Footer text: 2048 characters
  • Author name: 256 characters
  • Total: 6000 characters

Attachment References in Embeds

You can reference uploaded attachments in embed images using attachment:// URLs:
const message = await messageSendService.sendMessage({
  user,
  channelId,
  data: {
    content: 'Profile card',
    attachments: [
      {
        upload_filename,
        filename: 'profile-banner.png'
      }
    ],
    embeds: [
      {
        title: 'User Profile',
        description: 'Welcome to my profile!',
        image: {
          url: 'attachment://profile-banner.png' // References attachment
        },
        thumbnail: {
          url: 'attachment://profile-banner.png' // Can reuse same attachment
        }
      }
    ]
  },
  requestCache
});
The attachment:// URLs are automatically resolved to CDN URLs before the message is dispatched to clients.

Validation

// System validates attachment references
messageEmbedAttachmentResolver.validateAttachmentReferences({
  embeds: data.embeds,
  attachments: data.attachments
});

// Throws error if:
// - Embed references attachment:// but no attachments provided
// - Embed references attachment that doesn't exist
// - Attachment filename doesn't match reference
Fluxer automatically generates previews for URLs in messages.

Supported Platforms

Social Media

Twitter/X, Bluesky, Instagram, TikTok

Media

YouTube, Vimeo, Spotify, SoundCloud

Development

GitHub, GitLab, Stack Overflow

General

Any website with OpenGraph or oEmbed

How It Works

1

URL Detection

Client or server detects URLs in message content
2

Unfurl Request

Server fetches URL metadata (OpenGraph, oEmbed, etc.)
3

Embed Generation

Server generates embed object from metadata
4

Dispatch

Embed is added to message and dispatched to clients

Example Unfurled Content

// User sends message with URL
const message = await messageSendService.sendMessage({
  user,
  channelId,
  data: {
    content: 'Check out this article: https://example.com/cool-article'
  },
  requestCache
});

// Server automatically adds unfurled embed:
// {
//   type: 'link',
//   url: 'https://example.com/cool-article',
//   title: 'Cool Article Title',
//   description: 'This article is about...',
//   thumbnail: {
//     url: 'https://example.com/og-image.jpg'
//   },
//   provider: {
//     name: 'Example.com',
//     url: 'https://example.com'
//   }
// }

Suppressing Embeds

Users can prevent link unfurling:
// Suppress embeds with angle brackets
const message = await messageSendService.sendMessage({
  user,
  channelId,
  data: {
    content: 'No preview: <https://example.com/article>'
  },
  requestCache
});

// Or suppress via flags
const message = await messageSendService.sendMessage({
  user,
  channelId,
  data: {
    content: 'https://example.com/article',
    flags: MessageFlags.SUPPRESS_EMBEDS
  },
  requestCache
});

Message Editing with Media

You can modify attachments and embeds when editing messages:
// Add new attachment to existing message
const edited = await messageEditService.editMessage({
  user,
  channelId,
  messageId,
  data: {
    attachments: [
      ...existingAttachments,
      {
        upload_filename: newUploadId,
        filename: 'additional-image.png'
      }
    ]
  },
  requestCache
});
When editing, if you include attachment:// references in embeds, ensure the referenced attachments still exist or are being added.

Permissions

ATTACH_FILES
Permission
required
Required to upload attachments to messages
Required to send messages with embeds or link previews
USE_EXTERNAL_EMOJIS
Permission
Required to use custom emojis in embed descriptions

Best Practices

1

Optimize Media Files

Compress images and videos before uploading to reduce bandwidth and improve load times.
2

Use Attachment References

Prefer attachment:// URLs in embeds to avoid uploading the same file multiple times.
3

Provide Alt Text

Use the description field on attachments for accessibility.
4

Mind Embed Limits

Keep total characters under 6000 across all embed fields.
5

Test Link Previews

Verify your website has proper OpenGraph tags for nice unfurling.
6

Handle Upload Failures

Implement retry logic for failed uploads with exponential backoff.

Troubleshooting

  • Check file size limits
  • Verify file type is supported
  • Ensure you have ATTACH_FILES permission
  • Check network connectivity
  • Verify you have EMBED_LINKS permission
  • Check total character count under 6000
  • Ensure all URLs are valid and accessible
  • Validate embed structure matches schema
  • Verify attachment filename matches exactly
  • Ensure attachment is included in same request
  • Check that attachment:// prefix is correct
  • Validate attachment hasn’t been deleted

Messaging

Learn about sending messages

Custom Expressions

Add custom emojis and stickers

Communities

Understand channel permissions

API Reference

Complete API documentation

Build docs developers (and LLMs) love