@@ -62,6 +62,8 @@ import {
6262 type ScheduledContentSnapshot ,
6363} from '../automation/index.js'
6464import type { CitationConfig , MessageContext } from '../events/context.js'
65+ import { createDownloadFn } from '../events/decoders/_media-download.js'
66+ import type { MediaDownloadResult , MediaKind } from '../events/types.js'
6567import {
6668 formatConnectionStatus ,
6769 suppressLibsignalNoise ,
@@ -873,6 +875,30 @@ export class Client extends TypedEventEmitter<ClientEventMap> {
873875 }
874876 }
875877
878+ /**
879+ * Download media bytes for a message stored in the message store (by key).
880+ * Tries both `fromMe` variants. `null` when the message is unknown or carries no media.
881+ */
882+ async downloadMedia ( key : WAMessageKey ) : Promise < MediaDownloadResult | null > {
883+ const kinds : MediaKind [ ] = [ 'image' , 'video' , 'audio' , 'document' , 'sticker' ]
884+ const fields : Record < MediaKind , string > = {
885+ image : 'imageMessage' ,
886+ video : 'videoMessage' ,
887+ audio : 'audioMessage' ,
888+ document : 'documentMessage' ,
889+ sticker : 'stickerMessage' ,
890+ }
891+ for ( const fromMe of [ key . fromMe === true , key . fromMe !== true ] ) {
892+ const stored = await this . store . getMessage ( { ...key , fromMe } ) . catch ( ( ) => undefined )
893+ const content = stored ?. message as Record < string , unknown > | undefined
894+ if ( stored == null || content == null ) continue
895+ const kind = kinds . find ( ( k ) => content [ fields [ k ] ] != null )
896+ if ( kind === undefined ) return null
897+ return createDownloadFn ( stored , kind , this . logger ) ( )
898+ }
899+ return null
900+ }
901+
876902 private async lookupQuoted ( id : string , remoteJid : string ) : Promise < WAMessage | null > {
877903 for ( const fromMe of [ false , true ] ) {
878904 try {
0 commit comments