Skip to main content
Media utilities provide functions for handling media uploads, downloads, encryption, and thumbnail generation.

downloadMediaMessage

Downloads media from a WhatsApp message with automatic decryption.
async function downloadMediaMessage<Type extends 'buffer' | 'stream'>(
  message: WAMessage,
  type: Type,
  options: MediaDownloadOptions,
  ctx?: DownloadMediaMessageContext
): Promise<Type extends 'buffer' ? Buffer : Transform>

Parameters

message
WAMessage
required
The message containing the media to download.
type
'buffer' | 'stream'
required
Whether to return the media as a Buffer or a readable stream.
options
MediaDownloadOptions
required
Download configuration options.
startByte
number
Starting byte offset for partial downloads.
endByte
number
Ending byte offset for partial downloads.
options
RequestInit
Additional fetch options (headers, dispatcher, etc.).
ctx
DownloadMediaMessageContext
Optional context for automatic media reupload on 404/410 errors.
reuploadRequest
function
Function to request media reupload from sender.
logger
ILogger
Logger for download events.

Returns

A Promise resolving to either a Buffer or Transform stream depending on the type parameter.

Usage example

import { downloadMediaMessage } from '@whiskeysockets/baileys'
import { writeFile } from 'fs/promises'

// Download as buffer
const buffer = await downloadMediaMessage(
  message,
  'buffer',
  {}
)
await writeFile('downloaded-image.jpg', buffer)

// Download as stream for large files
const stream = await downloadMediaMessage(
  message,
  'stream',
  {}
)

stream.pipe(createWriteStream('video.mp4'))
When downloading large media files (videos, documents), prefer using 'stream' type to avoid loading the entire file into memory.

downloadContentFromMessage

Downloads and decrypts media content from a downloadable message.
async function downloadContentFromMessage(
  message: DownloadableMessage,
  type: MediaType,
  opts?: MediaDownloadOptions
): Promise<Transform>

Parameters

message
DownloadableMessage
required
Object containing mediaKey, directPath, or url for the media.
type
MediaType
required
Type of media: 'image', 'video', 'audio', 'document', or 'sticker'.
opts
MediaDownloadOptions
Optional download options (range, headers, etc.).

Returns

A Promise resolving to a Transform stream of decrypted media data.

Usage example

import { downloadContentFromMessage } from '@whiskeysockets/baileys'

const msg = message.message.imageMessage

const stream = await downloadContentFromMessage(
  msg,
  'image'
)

// Convert stream to buffer
const chunks = []
for await (const chunk of stream) {
  chunks.push(chunk)
}
const buffer = Buffer.concat(chunks)

generateProfilePicture

Generates a properly formatted profile picture from media input.
async function generateProfilePicture(
  mediaUpload: WAMediaUpload,
  dimensions?: { width: number; height: number }
): Promise<{ img: Buffer }>

Parameters

mediaUpload
WAMediaUpload
required
The image to process. Can be a Buffer, stream, or URL object.
dimensions
object
Optional dimensions for the output image.
width
number
Width in pixels (default: 640).
height
number
Height in pixels (default: 640).

Returns

A Promise resolving to an object containing the processed image buffer.

Usage example

import { generateProfilePicture } from '@whiskeysockets/baileys'
import { readFile } from 'fs/promises'

const imageBuffer = await readFile('avatar.jpg')

const { img } = await generateProfilePicture(imageBuffer, {
  width: 640,
  height: 640
})

// Use the generated image
await sock.updateProfilePicture(sock.user.id, img)
Requires either sharp or jimp image processing library to be installed. Sharp is preferred for better performance.

prepareWAMessageMedia

Prepares media for sending in a WhatsApp message by encrypting and uploading it.
async function prepareWAMessageMedia(
  message: AnyMediaMessageContent,
  options: MessageContentGenerationOptions
): Promise<WAMessageContent>

Parameters

message
AnyMediaMessageContent
required
Media message content to prepare.
image
WAMediaUpload
Image to send.
video
WAMediaUpload
Video to send.
audio
WAMediaUpload
Audio to send.
document
WAMediaUpload
Document to send.
sticker
WAMediaUpload
Sticker to send.
caption
string
Media caption text.
fileName
string
Filename for documents.
mimetype
string
MIME type (auto-detected if not provided).
ptt
boolean
Whether audio should be treated as voice note.
ptv
boolean
Whether video should be treated as video note.
gifPlayback
boolean
Whether video should play as GIF.
options
MessageContentGenerationOptions
required
Options including upload function and logger.

Returns

A Promise resolving to formatted message content ready to send.

Usage example

import { prepareWAMessageMedia, generateWAMessageFromContent } from '@whiskeysockets/baileys'
import { readFile } from 'fs/promises'

const imageBuffer = await readFile('photo.jpg')

const prepared = await prepareWAMessageMedia(
  {
    image: imageBuffer,
    caption: 'Check out this photo!'
  },
  {
    upload: sock.waUploadToServer,
    logger: myLogger
  }
)

const message = generateWAMessageFromContent(
  recipientJid,
  prepared,
  { userJid: sock.user.id }
)

await sock.relayMessage(recipientJid, message.message, {
  messageId: message.key.id
})

encryptedStream

Encrypts a media stream using AES-256-CBC for WhatsApp media upload.
async function encryptedStream(
  media: WAMediaUpload,
  mediaType: MediaType,
  options?: EncryptedStreamOptions
): Promise<{
  mediaKey: Buffer
  encFilePath: string
  originalFilePath?: string
  mac: Buffer
  fileEncSha256: Buffer
  fileSha256: Buffer
  fileLength: number
}>

Parameters

media
WAMediaUpload
required
Media to encrypt (Buffer, stream, or URL).
mediaType
MediaType
required
Type of media being encrypted.
options
EncryptedStreamOptions
Encryption options.
saveOriginalFileIfRequired
boolean
Whether to save original file for thumbnail generation.
logger
ILogger
Logger instance.
opts
RequestInit
Fetch options for remote URLs.

Returns

Object containing encryption keys, file paths, and checksums.

Usage example

import { encryptedStream } from '@whiskeysockets/baileys'

const result = await encryptedStream(
  imageBuffer,
  'image',
  { logger: myLogger }
)

console.log('Encrypted file:', result.encFilePath)
console.log('Media key:', result.mediaKey.toString('base64'))

generateThumbnail

Generates a thumbnail for image or video media.
async function generateThumbnail(
  file: string,
  mediaType: 'video' | 'image',
  options: { logger?: ILogger }
): Promise<{
  thumbnail?: string
  originalImageDimensions?: { width: number; height: number }
}>

Parameters

file
string
required
Path to the media file.
mediaType
'video' | 'image'
required
Type of media to generate thumbnail for.
options
object
Options including logger.

Returns

Object containing base64-encoded thumbnail and original dimensions.

Usage example

import { generateThumbnail } from '@whiskeysockets/baileys'

const { thumbnail, originalImageDimensions } = await generateThumbnail(
  '/tmp/video.mp4',
  'video',
  { logger: myLogger }
)

console.log('Thumbnail:', thumbnail)
console.log('Original dimensions:', originalImageDimensions)
For video thumbnails, requires ffmpeg to be installed on the system.

getAudioDuration

Extracts the duration of an audio file in seconds.
async function getAudioDuration(
  buffer: Buffer | string | Readable
): Promise<number | undefined>

Parameters

buffer
Buffer | string | Readable
required
Audio data as Buffer, file path, or readable stream.

Returns

A Promise resolving to the audio duration in seconds, or undefined if unable to determine.

Usage example

import { getAudioDuration } from '@whiskeysockets/baileys'

const duration = await getAudioDuration('./voice-note.ogg')
console.log(`Audio is ${duration} seconds long`)

getAudioWaveform

Generates a waveform visualization for audio files (used in voice notes).
async function getAudioWaveform(
  buffer: Buffer | string | Readable,
  logger?: ILogger
): Promise<Uint8Array | undefined>

Parameters

buffer
Buffer | string | Readable
required
Audio data to analyze.
logger
ILogger
Optional logger for debugging.

Returns

A Promise resolving to a Uint8Array of 64 samples representing the waveform.

Usage example

import { getAudioWaveform } from '@whiskeysockets/baileys'

const waveform = await getAudioWaveform(audioBuffer, logger)
console.log('Waveform samples:', waveform.length) // 64
Requires the audio-decode package to be installed for waveform generation.

mediaMessageSHA256B64

Extracts the SHA256 hash of a media message in base64 format.
function mediaMessageSHA256B64(
  message: WAMessageContent
): string | undefined

Parameters

message
WAMessageContent
required
The message containing media.

Returns

Base64-encoded SHA256 hash of the media file, or undefined if not available.

Usage example

import { mediaMessageSHA256B64 } from '@whiskeysockets/baileys'

const hash = mediaMessageSHA256B64(message.message)
console.log('Media hash:', hash)

getMediaKeys

Derives encryption keys from a media key using HKDF.
async function getMediaKeys(
  buffer: Uint8Array | string | null | undefined,
  mediaType: MediaType
): Promise<MediaDecryptionKeyInfo>

Parameters

buffer
Uint8Array | string | null | undefined
required
The media key (can be base64 string or buffer).
mediaType
MediaType
required
Type of media the key is for.

Returns

Object containing derived encryption keys:
MediaDecryptionKeyInfo
object
iv
Buffer
Initialization vector (16 bytes).
cipherKey
Buffer
AES cipher key (32 bytes).
macKey
Buffer
HMAC key (32 bytes).

Usage example

import { getMediaKeys } from '@whiskeysockets/baileys'

const keys = await getMediaKeys(
  message.message.imageMessage.mediaKey,
  'image'
)

console.log('IV:', keys.iv)
console.log('Cipher key:', keys.cipherKey)

extensionForMediaMessage

Determines the file extension for a media message based on its MIME type.
function extensionForMediaMessage(
  message: WAMessageContent
): string

Parameters

message
WAMessageContent
required
The media message.

Returns

File extension string (e.g., 'jpg', 'mp4', 'pdf').

Usage example

import { extensionForMediaMessage, downloadMediaMessage } from '@whiskeysockets/baileys'
import { writeFile } from 'fs/promises'

const buffer = await downloadMediaMessage(message, 'buffer', {})
const ext = extensionForMediaMessage(message.message)

await writeFile(`media.${ext}`, buffer)

toBuffer

Converts a readable stream to a Buffer.
async function toBuffer(stream: Readable): Promise<Buffer>

Parameters

stream
Readable
required
The stream to convert.

Returns

A Promise resolving to a Buffer containing all stream data.

Usage example

import { toBuffer } from '@whiskeysockets/baileys'
import { createReadStream } from 'fs'

const stream = createReadStream('file.txt')
const buffer = await toBuffer(stream)

console.log('File contents:', buffer.toString())

toReadable

Converts a Buffer to a readable stream.
function toReadable(buffer: Buffer): Readable

Parameters

buffer
Buffer
required
The buffer to convert.

Returns

A Readable stream.

Usage example

import { toReadable } from '@whiskeysockets/baileys'

const buffer = Buffer.from('Hello World')
const stream = toReadable(buffer)

stream.pipe(process.stdout)
  • WAMediaUpload - Union type for media input (Buffer, stream, or URL)
  • MediaType - 'image' | 'video' | 'audio' | 'document' | 'sticker'
  • MediaDownloadOptions - Options for media downloads
  • DownloadableMessage - Message interface with download properties
  • MediaDecryptionKeyInfo - Encryption keys for media

Build docs developers (and LLMs) love