feat: add option to reupload in downloadMediaMessage

This commit is contained in:
Adhiraj Singh
2022-06-01 13:19:05 +05:30
parent f62898dee7
commit cafc707628
2 changed files with 74 additions and 27 deletions

View File

@@ -569,7 +569,7 @@ The presence expires after about 10 seconds.
If you want to save the media you received If you want to save the media you received
``` ts ``` ts
import { writeFile } from 'fs/promises' import { writeFile } from 'fs/promises'
import { downloadContentFromMessage } from '@adiwajshing/baileys' import { downloadMediaMessage } from '@adiwajshing/baileys'
sock.ev.on('messages.upsert', async ({ messages }) => { sock.ev.on('messages.upsert', async ({ messages }) => {
const m = messages[0] const m = messages[0]
@@ -578,18 +578,29 @@ sock.ev.on('messages.upsert', async ({ messages }) => {
const messageType = Object.keys (m.message)[0]// get what type of message it is -- text, image, video const messageType = Object.keys (m.message)[0]// get what type of message it is -- text, image, video
// if the message is an image // if the message is an image
if (messageType === 'imageMessage') { if (messageType === 'imageMessage') {
// download stream // download the message
const stream = await downloadContentFromMessage(m.message.imageMessage, 'image') const buffer = await downloadMediaMessage(
let buffer = Buffer.from([]) m,
for await(const chunk of stream) { 'buffer',
buffer = Buffer.concat([buffer, chunk]) { },
{
logger,
// pass this so that baileys can request a reupload of media
// that has been deleted
reuploadRequest: sock.updateMediaMessage
} }
)
// save to file // save to file
await writeFile('./my-download.jpeg', buffer) await writeFile('./my-download.jpeg', buffer)
} }
} }
``` ```
**Note:** WhatsApp automatically removes old media from their servers, and so for the device to access said media -- a re-upload is required by another device that has the media. This can be accomplished using:
``` ts
const updatedMediaMsg = await sock.updateMediaMessage(msg)
```
## Deleting Messages ## Deleting Messages
``` ts ``` ts

View File

@@ -1,5 +1,7 @@
import { Boom } from '@hapi/boom' import { Boom } from '@hapi/boom'
import axios from 'axios'
import { promises as fs } from 'fs' import { promises as fs } from 'fs'
import { Logger } from 'pino'
import { proto } from '../../WAProto' import { proto } from '../../WAProto'
import { MEDIA_KEYS, URL_REGEX, WA_DEFAULT_EPHEMERAL } from '../Defaults' import { MEDIA_KEYS, URL_REGEX, WA_DEFAULT_EPHEMERAL } from '../Defaults'
import { import {
@@ -586,10 +588,43 @@ export const aggregateMessageKeysNotFromMe = (keys: proto.IMessageKey[]) => {
return Object.values(keyMap) return Object.values(keyMap)
} }
type DownloadMediaMessageContext = {
reuploadRequest: (msg: WAMessage) => Promise<WAMessage>
logger: Logger
}
const REUPLOAD_REQUIRED_STATUS = [410, 404]
/** /**
* Downloads the given message. Throws an error if it's not a media message * Downloads the given message. Throws an error if it's not a media message
*/ */
export const downloadMediaMessage = async(message: WAMessage, type: 'buffer' | 'stream', options: MediaDownloadOptions) => { export const downloadMediaMessage = async(
message: WAMessage,
type: 'buffer' | 'stream',
options: MediaDownloadOptions,
ctx?: DownloadMediaMessageContext
) => {
try {
const result = await downloadMsg()
return result
} catch(error) {
if(ctx) {
if(axios.isAxiosError(error)) {
// check if the message requires a reupload
if(REUPLOAD_REQUIRED_STATUS.includes(error.response?.status)) {
ctx.logger.info({ key: message.key }, 'sending reupload media request...')
// request reupload
message = await ctx.reuploadRequest(message)
const result = await downloadMsg()
return result
}
}
}
throw error
}
async function downloadMsg() {
const mContent = extractMessageContent(message.message) const mContent = extractMessageContent(message.message)
if(!mContent) { if(!mContent) {
throw new Boom('No message present', { statusCode: 400, data: message }) throw new Boom('No message present', { statusCode: 400, data: message })
@@ -613,6 +648,7 @@ export const downloadMediaMessage = async(message: WAMessage, type: 'buffer' | '
} }
return stream return stream
}
} }
/** Checks whether the given message is a media message; if it is returns the inner content */ /** Checks whether the given message is a media message; if it is returns the inner content */