From d8d7e7dff8ff0545a803fd2538e50ce09568821d Mon Sep 17 00:00:00 2001 From: Adhiraj Date: Wed, 22 Jul 2020 12:29:52 +0530 Subject: [PATCH] DownloadAndSaveMedia --- README.md | 10 ++++++---- src/WAClient/Messages.ts | 17 ++++++++++++++++- src/WAClient/Tests.ts | 4 ++-- src/WAClient/Utils.ts | 25 +++++++++++++------------ 4 files changed, 37 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index d08c608..90c1614 100644 --- a/README.md +++ b/README.md @@ -242,17 +242,19 @@ export enum Presence { } ``` -## Decoding Media -If you want to save & process some images, videos, documents or stickers you received +## Downloading Media +If you want to save the media you received ``` ts -import { MessageType } from '@adiwajshing/baileys' +import { MessageType, extensionForMediaMessage } from '@adiwajshing/baileys' client.setOnUnreadMessage (false, async m => { if (!m.message) return // if there is no text or media message const messageType = Object.keys (m.message)[0]// get what type of message it is -- text, image, video // if the message is not a text message if (messageType !== MessageType.text && messageType !== MessageType.extendedText) { - const savedFilename = await client.decodeMediaMessage(m.message, "filename") // extension applied automatically + const buffer = await client.downloadMediaMessage(m) // to decrypt & use as a buffer + + const savedFilename = await client.downloadAndSaveMediaMessage (m) // to decrypt & save to file console.log(m.key.remoteJid + " sent media, saved at: " + savedFilename) } } diff --git a/src/WAClient/Messages.ts b/src/WAClient/Messages.ts index 9c98db7..ef4ad81 100644 --- a/src/WAClient/Messages.ts +++ b/src/WAClient/Messages.ts @@ -1,5 +1,6 @@ import WhatsAppWebGroups from './Groups' import fetch from 'node-fetch' +import { promises as fs } from 'fs' import { MessageOptions, MessageType, @@ -17,7 +18,7 @@ import { } from './Constants' import { generateMessageID, sha256, hmacSign, aesEncrypWithIV, randomBytes } from '../WAConnection/Utils' import { WAMessageContent, WAMetric, WAFlag, WANode, WAMessage, WAMessageProto } from '../WAConnection/Constants' -import { validateJIDForSending, generateThumbnail, getMediaKeys, decodeMediaMessageBuffer } from './Utils' +import { validateJIDForSending, generateThumbnail, getMediaKeys, decodeMediaMessageBuffer, extensionForMediaMessage } from './Utils' import { proto } from '../../WAMessage/WAMessage' export default class WhatsAppWebMessages extends WhatsAppWebGroups { @@ -350,4 +351,18 @@ export default class WhatsAppWebMessages extends WhatsAppWebGroups { throw error } } + /** + * Securely downloads the media from the message and saves to a file. + * Renews the download url automatically, if necessary. + * @param message the media message you want to decode + * @param filename the name of the file where the media will be saved + * @param attachExtension should the parsed extension be applied automatically to the file + */ + async downloadAndSaveMediaMessage (message: WAMessage, filename: string, attachExtension: boolean=true) { + const buffer = await this.downloadMediaMessage (message) + const extension = extensionForMediaMessage (message.message) + const trueFileName = attachExtension ? (filename + '.' + extension) : filename + await fs.writeFile (trueFileName, buffer) + return trueFileName + } } diff --git a/src/WAClient/Tests.ts b/src/WAClient/Tests.ts index 2ef9276..c9f9bdf 100644 --- a/src/WAClient/Tests.ts +++ b/src/WAClient/Tests.ts @@ -52,8 +52,8 @@ WAClientTest('Messages', (client) => { it('should send a gif', async () => { const content = fs.readFileSync('./Media/ma_gif.mp4') const message = await sendAndRetreiveMessage(client, content, MessageType.video, { mimetype: Mimetype.gif }) - const buffer = await client.downloadMediaMessage(message) - fs.writeFileSync ('./Media/received_vid.mp4', buffer) + + await client.downloadAndSaveMediaMessage(message,'./Media/received_vid') }) it('should send an image', async () => { const content = fs.readFileSync('./Media/meme.jpeg') diff --git a/src/WAClient/Utils.ts b/src/WAClient/Utils.ts index bd6702e..b7d326f 100644 --- a/src/WAClient/Utils.ts +++ b/src/WAClient/Utils.ts @@ -165,18 +165,10 @@ export async function decodeMediaMessageBuffer(message: WAMessageContent) { } throw new Error('Decryption failed, HMAC sign does not match') } -/** - * Decode a media message (video, image, document, audio) & save it to the given file - * @param message the media message you want to decode - * @param filename the name of the file where the media will be saved - * @param attachExtension should the correct extension be applied automatically to the file - */ -export async function decodeMediaMessage(message: WAMessageContent, filename: string, attachExtension: boolean=true) { - const getExtension = (mimetype) => mimetype.split(';')[0].split('/')[1] - - const buffer = await decodeMediaMessageBuffer (message) +export function extensionForMediaMessage(message: WAMessageContent) { + const getExtension = (mimetype: string) => mimetype.split(';')[0].split('/')[1] const type = Object.keys(message)[0] as MessageType - let extension + let extension: string if (type === MessageType.location || type === MessageType.liveLocation) { extension = '.jpeg' } else { @@ -187,7 +179,16 @@ export async function decodeMediaMessage(message: WAMessageContent, filename: st | proto.DocumentMessage extension = getExtension (messageContent.mimetype) } - + return extension +} + +/** + * Decode a media message (video, image, document, audio) & save it to the given file + * @deprecated use `client.downloadAndSaveMediaMessage` + */ +export async function decodeMediaMessage(message: WAMessageContent, filename: string, attachExtension: boolean=true) { + const buffer = await decodeMediaMessageBuffer (message) + const extension = extensionForMediaMessage (message) const trueFileName = attachExtension ? (filename + '.' + extension) : filename fs.writeFileSync(trueFileName, buffer) return trueFileName