Overview
The Advanced iMessage Kit SDK supports sending and receiving various types of attachments including images, videos, documents, stickers, and audio messages.
Sending Attachments
Prepare the file
Ensure the file exists on your filesystem. import fs from "fs" ;
import path from "path" ;
const filePath = path . join ( __dirname , "test-image.png" );
if ( ! fs . existsSync ( filePath )) {
console . error ( "File not found!" );
process . exit ( 1 );
}
Send the attachment
Use the attachments.sendAttachment() method. const message = await sdk . attachments . sendAttachment ({
chatGuid: "iMessage;-;+1234567890" ,
filePath: filePath
});
console . log ( `Sent: ${ message . guid } ` );
Check the response
Verify the attachment was sent successfully. if ( message . attachments && message . attachments . length > 0 ) {
const attachment = message . attachments [ 0 ];
console . log ( `Filename: ${ attachment . transferName } ` );
console . log ( `MIME type: ${ attachment . mimeType } ` );
console . log ( `Size: ${ ( attachment . totalBytes / 1024 ). toFixed ( 2 ) } KB` );
}
Complete Attachment Example
import fs from "fs" ;
import path from "path" ;
import { AdvancedIMessageKit } from "@photon-ai/advanced-imessage-kit" ;
const sdk = new AdvancedIMessageKit ({
serverUrl: "http://localhost:1234" ,
apiKey: "your-api-key"
});
const CHAT_GUID = "iMessage;-;+1234567890" ;
const filePath = path . join ( __dirname , "test-image.png" );
sdk . on ( "ready" , async () => {
if ( ! fs . existsSync ( filePath )) {
console . error ( `File not found: ${ filePath } ` );
await sdk . close ();
process . exit ( 1 );
}
const fileName = path . basename ( filePath );
const fileSize = ( fs . statSync ( filePath ). size / 1024 ). toFixed ( 2 );
console . log ( `Sending ${ fileName } ( ${ fileSize } KB)` );
try {
const message = await sdk . attachments . sendAttachment ({
chatGuid: CHAT_GUID ,
filePath: filePath
});
console . log ( `Sent: ${ message . guid } ` );
if ( message . attachments && message . attachments . length > 0 ) {
const att = message . attachments [ 0 ];
console . log ( ` ${ att . transferName } ( ${ att . mimeType || "unknown" } )` );
}
} catch ( error ) {
console . error ( "Failed to send attachment:" , error . message );
}
await sdk . close ();
process . exit ( 0 );
});
await sdk . connect ();
Audio Messages
Send audio files as voice messages with the audio message flag.
import path from "path" ;
const audioPath = path . join ( __dirname , "voice-memo.mp3" );
const message = await sdk . attachments . sendAttachment ({
chatGuid: "iMessage;-;+1234567890" ,
filePath: audioPath ,
isAudioMessage: true // Renders as audio message in iMessage
});
console . log ( `Audio message sent: ${ message . guid } ` );
console . log ( `Created: ${ new Date ( message . dateCreated ). toLocaleString () } ` );
Setting isAudioMessage: true automatically enables Private API method for proper audio message rendering in iMessage.
Stickers
Send stickers as standalone messages or attached to existing messages.
Standalone Sticker
Reply Sticker
Send a sticker as its own message (like sending an image). import path from "path" ;
const stickerPath = path . join ( __dirname , "sticker.png" );
const message = await sdk . attachments . sendSticker ({
chatGuid: "iMessage;-;+1234567890" ,
filePath: stickerPath
});
console . log ( `Sticker sent: ${ message . guid } ` );
console . log ( `Attachments: ${ message . attachments ?. length || 0 } ` );
if ( message . attachments ?.[ 0 ]) {
const att = message . attachments [ 0 ];
console . log ( `MIME type: ${ att . mimeType } ` );
console . log ( `Is sticker: ${ att . isSticker } ` );
}
Attach a sticker to an existing message (like a reaction). import path from "path" ;
const stickerPath = path . join ( __dirname , "sticker.png" );
const targetMessageGuid = "message-guid-to-attach-to" ;
const message = await sdk . attachments . sendSticker ({
chatGuid: "iMessage;-;+1234567890" ,
filePath: stickerPath ,
selectedMessageGuid: targetMessageGuid ,
stickerX: 0.5 , // X position (0-1)
stickerY: 0.5 , // Y position (0-1)
stickerScale: 0.75 , // Scale factor
stickerRotation: 0 , // Rotation in degrees
stickerWidth: 300 // Width in pixels
});
console . log ( `Sticker attached to message: ${ targetMessageGuid } ` );
Stickers require Private API to be enabled on your server. They will not work with standard API.
Attachment Replies
Send attachments as replies to specific messages.
import path from "path" ;
// Original message GUID
const originalMessageGuid = "guid-of-message-to-reply-to" ;
const imagePath = path . join ( __dirname , "reply-image.jpg" );
const reply = await sdk . attachments . sendAttachment ({
chatGuid: "iMessage;-;+1234567890" ,
filePath: imagePath ,
selectedMessageGuid: originalMessageGuid
});
console . log ( `Reply with attachment sent: ${ reply . guid } ` );
console . log ( `Replying to: ${ originalMessageGuid } ` );
Receiving Attachments
Download and process incoming attachments.
Find messages with attachments
Query messages and filter for those with attachments. const messages = await sdk . messages . getMessages ({
chatGuid: "iMessage;-;+1234567890" ,
limit: 50 ,
with: [ "attachment" ]
});
const withAttachments = messages . filter (
m => m . attachments && m . attachments . length > 0
);
console . log ( `Found ${ withAttachments . length } messages with attachments` );
Get attachment details
Retrieve metadata for a specific attachment. const firstMsg = withAttachments [ 0 ];
const attachment = firstMsg ?. attachments ?.[ 0 ];
if ( attachment ) {
console . log ( `Attachment: ${ attachment . transferName } ` );
console . log ( `Type: ${ attachment . mimeType || "unknown" } ` );
console . log ( `Size: ${ ( attachment . totalBytes / 1024 ). toFixed ( 2 ) } KB` );
console . log ( `GUID: ${ attachment . guid } ` );
}
Download the attachment
Download the file to your local filesystem. import fs from "fs" ;
import path from "path" ;
const buffer = await sdk . attachments . downloadAttachment ( attachment . guid , {
original: true // Get original quality
});
const outputPath = path . join ( "/tmp" , attachment . transferName );
fs . writeFileSync ( outputPath , buffer );
console . log ( `Saved to: ${ outputPath } ` );
Complete Download Example
import fs from "fs" ;
import path from "path" ;
const CHAT_GUID = "iMessage;-;+1234567890" ;
const OUTPUT_DIR = "/tmp" ;
sdk . on ( "ready" , async () => {
try {
// Get recent messages with attachments
const messages = await sdk . messages . getMessages ({
chatGuid: CHAT_GUID ,
limit: 50 ,
with: [ "attachment" ]
});
const messagesWithAttachments = messages . filter (
m => m . attachments && m . attachments . length > 0
);
if ( messagesWithAttachments . length === 0 ) {
console . log ( "No messages with attachments found" );
await sdk . close ();
process . exit ( 0 );
}
console . log ( `Found ${ messagesWithAttachments . length } messages with attachments \n ` );
// Download the first attachment
const firstMsg = messagesWithAttachments [ 0 ];
const attachment = firstMsg ?. attachments ?.[ 0 ];
if ( ! attachment ) {
console . log ( "No attachment found" );
await sdk . close ();
process . exit ( 0 );
}
console . log ( `Attachment: ${ attachment . transferName } ` );
console . log ( `Type: ${ attachment . mimeType || "unknown" } ` );
console . log ( `Size: ${ ( attachment . totalBytes / 1024 ). toFixed ( 2 ) } KB` );
console . log ( `GUID: ${ attachment . guid } \n ` );
// Get attachment info
const info = await sdk . attachments . getAttachment ( attachment . guid );
console . log ( `Info retrieved: ${ info . transferName } ` );
// Download attachment
console . log ( "Downloading..." );
const buffer = await sdk . attachments . downloadAttachment ( attachment . guid , {
original: true
});
const outputPath = path . join ( OUTPUT_DIR , attachment . transferName );
fs . writeFileSync ( outputPath , buffer );
console . log ( `Saved to: ${ outputPath } ` );
// Get blurhash if it's an image
if ( attachment . mimeType ?. startsWith ( "image/" )) {
try {
const blurhash = await sdk . attachments . getAttachmentBlurhash ( attachment . guid );
console . log ( `Blurhash: ${ blurhash } ` );
} catch {
console . log ( "Blurhash not available" );
}
}
// Check for Live Photo
if ( attachment . hasLivePhoto ) {
console . log ( " \n Downloading Live Photo video..." );
const liveBuffer = await sdk . attachments . downloadAttachmentLive ( attachment . guid );
const livePath = path . join ( OUTPUT_DIR , ` ${ path . parse ( attachment . transferName ). name } _live.mov` );
fs . writeFileSync ( livePath , liveBuffer );
console . log ( `Live Photo saved to: ${ livePath } ` );
}
// Get total attachment count
const totalCount = await sdk . attachments . getAttachmentCount ();
console . log ( ` \n Total attachments in database: ${ totalCount } ` );
} catch ( error ) {
console . error ( "Failed to download attachment:" , error );
}
await sdk . close ();
process . exit ( 0 );
});
await sdk . connect ();
Download Options
Customize how attachments are downloaded.
Original Quality
Custom Dimensions
Force Redownload
const buffer = await sdk . attachments . downloadAttachment ( attachmentGuid , {
original: true
});
// Resize image to specific dimensions
const buffer = await sdk . attachments . downloadAttachment ( attachmentGuid , {
width: 800 ,
height: 600 ,
quality: 85 // JPEG quality (0-100)
});
// Force redownload even if cached
const buffer = await sdk . attachments . downloadAttachment ( attachmentGuid , {
force: true
});
Live Photos
Download the video component of Live Photos.
import fs from "fs" ;
import path from "path" ;
const attachment = message . attachments ?.[ 0 ];
if ( attachment ?. hasLivePhoto ) {
console . log ( "This is a Live Photo!" );
// Download the image
const imageBuffer = await sdk . attachments . downloadAttachment ( attachment . guid , {
original: true
});
fs . writeFileSync ( "live-photo.jpg" , imageBuffer );
// Download the video
const videoBuffer = await sdk . attachments . downloadAttachmentLive ( attachment . guid );
fs . writeFileSync ( "live-photo.mov" , videoBuffer );
console . log ( "Live Photo downloaded (image + video)" );
}
Blurhash
Generate blurhash strings for image placeholders.
const attachment = message . attachments ?.[ 0 ];
if ( attachment ?. mimeType ?. startsWith ( "image/" )) {
try {
const blurhash = await sdk . attachments . getAttachmentBlurhash ( attachment . guid );
console . log ( `Blurhash: ${ blurhash } ` );
// Use blurhash for placeholder while loading full image
} catch ( error ) {
console . log ( "Blurhash not available for this image" );
}
}
Blurhash is a compact representation of an image placeholder. It’s useful for showing a preview while the full image loads.
Attachment Count
Get the total number of attachments in your database.
const totalAttachments = await sdk . attachments . getAttachmentCount ();
console . log ( `Total attachments: ${ totalAttachments } ` );
Listening for New Attachments
Receive attachments in real-time as they arrive.
import fs from "fs" ;
import path from "path" ;
sdk . on ( "new-message" , async ( message ) => {
// Check if message has attachments
if ( ! message . attachments || message . attachments . length === 0 ) {
return ;
}
console . log ( ` \n New message with ${ message . attachments . length } attachment(s)` );
for ( const attachment of message . attachments ) {
console . log ( ` - ${ attachment . transferName } ( ${ attachment . mimeType } )` );
try {
// Auto-download image attachments
if ( attachment . mimeType ?. startsWith ( "image/" )) {
const buffer = await sdk . attachments . downloadAttachment ( attachment . guid , {
original: true
});
const savePath = path . join ( "/tmp/downloads" , attachment . transferName );
fs . writeFileSync ( savePath , buffer );
console . log ( ` Saved to: ${ savePath } ` );
}
} catch ( error ) {
console . error ( ` Failed to download: ${ error . message } ` );
}
}
});
Custom Filenames
Specify custom filenames when sending attachments.
import path from "path" ;
const filePath = path . join ( __dirname , "image.jpg" );
const message = await sdk . attachments . sendAttachment ({
chatGuid: "iMessage;-;+1234567890" ,
filePath: filePath ,
fileName: "vacation-photo.jpg" // Custom filename
});
console . log ( `Sent as: ${ message . attachments ?.[ 0 ]?. transferName } ` );
Supported File Types
The SDK supports all file types that iMessage supports:
Images : JPG, PNG, GIF, HEIC, HEIF
Videos : MOV, MP4, M4V
Audio : MP3, M4A, WAV, AAC
Documents : PDF, DOC, DOCX, XLS, XLSX, PPT, PPTX
Archives : ZIP, RAR
Other : Any file type iMessage can handle
Large files may take longer to upload. Consider showing upload progress to users in production applications.
Error Handling
Handle common attachment errors gracefully.
try {
const message = await sdk . attachments . sendAttachment ({
chatGuid: CHAT_GUID ,
filePath: filePath
});
console . log ( "Attachment sent successfully" );
} catch ( error ) {
if ( error . code === "ENOENT" ) {
console . error ( "File not found" );
} else if ( error . response ?. status === 413 ) {
console . error ( "File too large" );
} else if ( error . response ?. status === 415 ) {
console . error ( "Unsupported file type" );
} else {
console . error ( "Failed to send attachment:" , error . message );
}
}
Next Steps
Sending Messages Learn more about message sending features
Best Practices Optimize your attachment handling