Media utilities provide functions for handling media uploads, downloads, encryption, and thumbnail generation.
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
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.Starting byte offset for partial downloads.
Ending byte offset for partial downloads.
Additional fetch options (headers, dispatcher, etc.).
ctx
DownloadMediaMessageContext
Optional context for automatic media reupload on 404/410 errors.Function to request media reupload from sender.
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 of media: 'image', 'video', 'audio', 'document', or 'sticker'.
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
The image to process. Can be a Buffer, stream, or URL object.
Optional dimensions for the output image.Width in pixels (default: 640).
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.
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.MIME type (auto-detected if not provided).
Whether audio should be treated as voice note.
Whether video should be treated as video note.
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 to encrypt (Buffer, stream, or URL).
Type of media being encrypted.
Encryption options.saveOriginalFileIfRequired
Whether to save original file for thumbnail generation.
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
mediaType
'video' | 'image'
required
Type of media to generate thumbnail for.
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`)
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.
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.
Extracts the SHA256 hash of a media message in base64 format.
function mediaMessageSHA256B64(
message: WAMessageContent
): string | undefined
Parameters
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)
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).
Type of media the key is for.
Returns
Object containing derived encryption keys:
Initialization vector (16 bytes).
AES cipher 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)
Determines the file extension for a media message based on its MIME type.
function extensionForMediaMessage(
message: WAMessageContent
): string
Parameters
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
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
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