mirror of
https://github.com/FranP-code/Baileys.git
synced 2025-10-13 00:32:22 +00:00
feat: add option to reupload in downloadMediaMessage
This commit is contained in:
25
README.md
25
README.md
@@ -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
|
||||||
|
|||||||
@@ -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,33 +588,67 @@ 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(
|
||||||
const mContent = extractMessageContent(message.message)
|
message: WAMessage,
|
||||||
if(!mContent) {
|
type: 'buffer' | 'stream',
|
||||||
throw new Boom('No message present', { statusCode: 400, data: message })
|
options: MediaDownloadOptions,
|
||||||
}
|
ctx?: DownloadMediaMessageContext
|
||||||
|
) => {
|
||||||
const contentType = getContentType(mContent)
|
try {
|
||||||
const mediaType = contentType.replace('Message', '') as MediaType
|
const result = await downloadMsg()
|
||||||
const media = mContent[contentType]
|
return result
|
||||||
if(typeof media !== 'object' || !('url' in media)) {
|
} catch(error) {
|
||||||
throw new Boom(`"${contentType}" message is not a media message`)
|
if(ctx) {
|
||||||
}
|
if(axios.isAxiosError(error)) {
|
||||||
|
// check if the message requires a reupload
|
||||||
const stream = await downloadContentFromMessage(media, mediaType, options)
|
if(REUPLOAD_REQUIRED_STATUS.includes(error.response?.status)) {
|
||||||
if(type === 'buffer') {
|
ctx.logger.info({ key: message.key }, 'sending reupload media request...')
|
||||||
let buffer = Buffer.from([])
|
// request reupload
|
||||||
for await (const chunk of stream) {
|
message = await ctx.reuploadRequest(message)
|
||||||
buffer = Buffer.concat([buffer, chunk])
|
const result = await downloadMsg()
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return buffer
|
throw error
|
||||||
}
|
}
|
||||||
|
|
||||||
return stream
|
async function downloadMsg() {
|
||||||
|
const mContent = extractMessageContent(message.message)
|
||||||
|
if(!mContent) {
|
||||||
|
throw new Boom('No message present', { statusCode: 400, data: message })
|
||||||
|
}
|
||||||
|
|
||||||
|
const contentType = getContentType(mContent)
|
||||||
|
const mediaType = contentType.replace('Message', '') as MediaType
|
||||||
|
const media = mContent[contentType]
|
||||||
|
if(typeof media !== 'object' || !('url' in media)) {
|
||||||
|
throw new Boom(`"${contentType}" message is not a media message`)
|
||||||
|
}
|
||||||
|
|
||||||
|
const stream = await downloadContentFromMessage(media, mediaType, options)
|
||||||
|
if(type === 'buffer') {
|
||||||
|
let buffer = Buffer.from([])
|
||||||
|
for await (const chunk of stream) {
|
||||||
|
buffer = Buffer.concat([buffer, chunk])
|
||||||
|
}
|
||||||
|
|
||||||
|
return buffer
|
||||||
|
}
|
||||||
|
|
||||||
|
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 */
|
||||||
|
|||||||
Reference in New Issue
Block a user