Skip to main content
Media utility functions handle all aspects of media messages including downloading, encryption, thumbnail generation, and media upload preparation.

downloadMediaMessage

Downloads media from a WhatsApp message.
export const downloadMediaMessage = async <Type extends 'buffer' | 'stream'>(
  message: WAMessage,
  type: Type,
  options: MediaDownloadOptions,
  ctx?: DownloadMediaMessageContext
): Promise<Type extends 'buffer' ? Buffer : Transform>
message
WAMessage
required
The message containing media to download
type
'buffer' | 'stream'
required
Whether to return a Buffer or a Stream
options
MediaDownloadOptions
required
Download options including byte range
ctx
DownloadMediaMessageContext
Context with reupload request handler and logger

MediaDownloadOptions

options.startByte
number
Start byte for partial download
options.endByte
number
End byte for partial download
options.options
RequestInit
Fetch options for the download request
return
Buffer | Transform
Downloaded media as Buffer (type=‘buffer’) or Stream (type=‘stream’)
Example:
import { downloadMediaMessage } from '@whiskeysockets/baileys'
import fs from 'fs'

// Download as buffer
const buffer = await downloadMediaMessage(
  message,
  'buffer',
  { }
)
fs.writeFileSync('image.jpg', buffer)

// Download as stream
const stream = await downloadMediaMessage(
  message,
  'stream',
  { }
)
stream.pipe(fs.createWriteStream('video.mp4'))

// Partial download
const partialBuffer = await downloadMediaMessage(
  message,
  'buffer',
  {
    startByte: 0,
    endByte: 1024 // Download first 1KB
  }
)

// With reupload context
const bufferWithRetry = await downloadMediaMessage(
  message,
  'buffer',
  { },
  {
    reuploadRequest: async (msg) => {
      // Request media re-upload from sender
      return await sock.reuploadRequest(msg)
    },
    logger: myLogger
  }
)
When to use:
  • To download images, videos, audio, documents from messages
  • For saving media to disk
  • When processing media files (thumbnails, transcoding, etc.)
  • Automatically handles media decryption

downloadContentFromMessage

Downloads and decrypts media content from a downloadable message.
export const downloadContentFromMessage = async (
  { mediaKey, directPath, url }: DownloadableMessage,
  type: MediaType,
  opts?: MediaDownloadOptions
): Promise<Transform>
message
DownloadableMessage
required
Object containing mediaKey, directPath, and/or url
type
MediaType
required
Type of media: ‘image’, ‘video’, ‘audio’, ‘document’, ‘sticker’, etc.
opts
MediaDownloadOptions
Download options
return
Transform
Decrypted media stream
Example:
import { downloadContentFromMessage } from '@whiskeysockets/baileys'

const msg = message.message.imageMessage
const stream = await downloadContentFromMessage(
  {
    mediaKey: msg.mediaKey,
    directPath: msg.directPath,
    url: msg.url
  },
  'image'
)

const buffers = []
for await (const chunk of stream) {
  buffers.push(chunk)
}
const buffer = Buffer.concat(buffers)
When to use:
  • For lower-level media downloading
  • When you have the media message properties directly
  • For streaming large files

encryptedStream

Encrypts media for upload to WhatsApp servers.
export const encryptedStream = async (
  media: WAMediaUpload,
  mediaType: MediaType,
  options?: EncryptedStreamOptions
): Promise<{
  mediaKey: Buffer
  encFilePath: string
  originalFilePath?: string
  mac: Buffer
  fileEncSha256: Buffer
  fileSha256: Buffer
  fileLength: number
}>
media
WAMediaUpload
required
Media to encrypt (Buffer, Stream, or URL object)
mediaType
MediaType
required
Type of media being encrypted
options
EncryptedStreamOptions
Encryption options

EncryptedStreamOptions

options.saveOriginalFileIfRequired
boolean
default:false
Whether to save the original unencrypted file
options.logger
ILogger
Logger instance
options.opts
RequestInit
Fetch options if media is a URL
return
object
Object containing encryption keys, file paths, hashes, and file length
Example:
import { encryptedStream } from '@whiskeysockets/baileys'
import fs from 'fs'

// Encrypt from buffer
const buffer = fs.readFileSync('image.jpg')
const encrypted = await encryptedStream(
  buffer,
  'image',
  { logger: myLogger }
)

console.log(encrypted.mediaKey) // Encryption key
console.log(encrypted.encFilePath) // Path to encrypted file
console.log(encrypted.fileSha256) // SHA256 of original
console.log(encrypted.fileEncSha256) // SHA256 of encrypted

// Encrypt from URL
const encryptedFromUrl = await encryptedStream(
  { url: 'https://example.com/image.jpg' },
  'image'
)

// Encrypt from stream
const stream = fs.createReadStream('video.mp4')
const encryptedStream = await encryptedStream(
  { stream },
  'video',
  { saveOriginalFileIfRequired: true }
)

console.log(encryptedStream.originalFilePath) // Saved original file
When to use:
  • Before uploading media to WhatsApp
  • Automatically called by sendMessage with media
  • For manual media upload workflows

generateThumbnail

Generates a JPEG thumbnail for images or videos.
export async function generateThumbnail(
  file: string,
  mediaType: 'video' | 'image',
  options: { logger?: ILogger }
): Promise<{
  thumbnail?: string
  originalImageDimensions?: { width: number; height: number }
}>
file
string
required
Path to the media file
mediaType
'video' | 'image'
required
Type of media
options
object
required
Options with optional logger
return
object
Object with base64 thumbnail and original dimensions (for images)
Example:
import { generateThumbnail } from '@whiskeysockets/baileys'

// Generate image thumbnail
const { thumbnail, originalImageDimensions } = await generateThumbnail(
  '/path/to/image.jpg',
  'image',
  { logger: myLogger }
)

console.log(thumbnail) // Base64 encoded JPEG thumbnail
console.log(originalImageDimensions) // { width: 1920, height: 1080 }

// Generate video thumbnail
const { thumbnail: videoThumb } = await generateThumbnail(
  '/path/to/video.mp4',
  'video',
  { logger: myLogger }
)

console.log(videoThumb) // Base64 thumbnail from video frame
When to use:
  • Automatically used when sending images/videos
  • For generating preview thumbnails
  • Requires ffmpeg for video thumbnails
  • Requires sharp or jimp for image thumbnails

getAudioDuration

Gets the duration of an audio file in seconds.
export async function getAudioDuration(
  buffer: Buffer | string | Readable
): Promise<number | undefined>
buffer
Buffer | string | Readable
required
Audio file as Buffer, file path string, or Readable stream
return
number | undefined
Audio duration in seconds
Example:
import { getAudioDuration } from '@whiskeysockets/baileys'
import fs from 'fs'

// From buffer
const buffer = fs.readFileSync('audio.mp3')
const duration = await getAudioDuration(buffer)
console.log(`Duration: ${duration} seconds`)

// From file path
const duration2 = await getAudioDuration('/path/to/audio.mp3')

// From stream
const stream = fs.createReadStream('audio.ogg')
const duration3 = await getAudioDuration(stream)
When to use:
  • Automatically used when sending audio messages
  • For displaying audio duration in UI
  • Requires music-metadata package

getRawMediaUploadData

Prepares raw media data for upload (used for newsletters).
export const getRawMediaUploadData = async (
  media: WAMediaUpload,
  mediaType: MediaType,
  logger?: ILogger
): Promise<{
  filePath: string
  fileSha256: Buffer
  fileLength: number
}>
media
WAMediaUpload
required
Media to prepare (Buffer, Stream, or URL)
mediaType
MediaType
required
Type of media
logger
ILogger
Logger instance
return
object
Object with file path, SHA256 hash, and file length
Example:
import { getRawMediaUploadData } from '@whiskeysockets/baileys'
import fs from 'fs'

const buffer = fs.readFileSync('image.jpg')
const uploadData = await getRawMediaUploadData(
  buffer,
  'image',
  logger
)

console.log(uploadData.filePath) // Temp file path
console.log(uploadData.fileSha256) // SHA256 hash
console.log(uploadData.fileLength) // File size in bytes

// Use for newsletter upload
const { mediaUrl, directPath } = await sock.newsletterUpload(
  uploadData.filePath,
  {
    fileEncSha256B64: uploadData.fileSha256.toString('base64'),
    mediaType: 'image'
  }
)
When to use:
  • When uploading media to newsletters
  • For unencrypted media uploads
  • Automatically used internally for newsletter messages

generateProfilePicture

Generates a profile picture by resizing and cropping an image.
export const generateProfilePicture = async (
  mediaUpload: WAMediaUpload,
  dimensions?: { width: number; height: number }
): Promise<{ img: Buffer }>
mediaUpload
WAMediaUpload
required
Image to process (Buffer, Stream, or URL)
dimensions
{ width: number; height: number }
Target dimensions (default: 640x640)
return
{ img: Buffer }
Processed profile picture as JPEG buffer
Example:
import { generateProfilePicture } from '@whiskeysockets/baileys'
import fs from 'fs'

const buffer = fs.readFileSync('photo.jpg')
const { img } = await generateProfilePicture(buffer)

// Update profile picture
await sock.updateProfilePicture(sock.user.id, img)

// Custom dimensions
const { img: smallImg } = await generateProfilePicture(
  buffer,
  { width: 320, height: 320 }
)
When to use:
  • When updating profile pictures
  • Automatically resizes and crops to square
  • Requires sharp or jimp library

Build docs developers (and LLMs) love