feat: new media download way
This commit is contained in:
parent
b5217d208c
commit
5869d86177
4 changed files with 173 additions and 2 deletions
|
|
@ -1,6 +1,7 @@
|
||||||
const { MessageMedia, Location, Poll } = require('whatsapp-web.js')
|
const { MessageMedia, Location, Poll } = require('whatsapp-web.js')
|
||||||
|
const { Readable } = require('stream')
|
||||||
const { sessions } = require('../sessions')
|
const { sessions } = require('../sessions')
|
||||||
const { sendErrorResponse } = require('../utils')
|
const { sendErrorResponse, decodeBase64 } = require('../utils')
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get message by its ID from a given chat using the provided client.
|
* Get message by its ID from a given chat using the provided client.
|
||||||
|
|
@ -116,6 +117,7 @@ const downloadMedia = async (req, res) => {
|
||||||
const client = sessions.get(req.params.sessionId)
|
const client = sessions.get(req.params.sessionId)
|
||||||
const message = await _getMessageById(client, messageId, chatId)
|
const message = await _getMessageById(client, messageId, chatId)
|
||||||
if (!message) { throw new Error('Message not found') }
|
if (!message) { throw new Error('Message not found') }
|
||||||
|
if (!message.hasMedia) { throw new Error('Message media not found') }
|
||||||
const messageMedia = await message.downloadMedia()
|
const messageMedia = await message.downloadMedia()
|
||||||
res.json({ success: true, messageMedia })
|
res.json({ success: true, messageMedia })
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
@ -123,6 +125,54 @@ const downloadMedia = async (req, res) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Downloads media from a message and sends it as binary data.
|
||||||
|
* @async
|
||||||
|
* @function
|
||||||
|
* @param {Object} req - The request object.
|
||||||
|
* @param {Object} res - The response object.
|
||||||
|
* @param {string} req.params.sessionId - The session ID.
|
||||||
|
* @param {string} req.body.messageId - The message ID.
|
||||||
|
* @param {string} req.body.chatId - The chat ID.
|
||||||
|
* @returns {Promise<void>} - A Promise that resolves with no value when the function completes.
|
||||||
|
*/
|
||||||
|
const downloadMediaAsData = async (req, res) => {
|
||||||
|
/*
|
||||||
|
#swagger.summary = 'Download attached message media as binary data'
|
||||||
|
*/
|
||||||
|
try {
|
||||||
|
const { messageId, chatId } = req.body
|
||||||
|
const client = sessions.get(req.params.sessionId)
|
||||||
|
const message = await _getMessageById(client, messageId, chatId)
|
||||||
|
if (!message) { throw new Error('Message not found') }
|
||||||
|
if (!message.hasMedia) { throw new Error('Message media not found') }
|
||||||
|
const { data, mimetype, filename, filesize } = await message.downloadMedia()
|
||||||
|
/* #swagger.responses[200] = {
|
||||||
|
description: 'Binary data.'
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
res.writeHead(200, {
|
||||||
|
...(mimetype && { 'Content-Type': mimetype }),
|
||||||
|
...(filesize && { 'Content-Length': filesize }),
|
||||||
|
...(filename && { 'Content-Disposition': `attachment; filename=${encodeURIComponent(filename)}` })
|
||||||
|
})
|
||||||
|
const readableStream = new Readable({
|
||||||
|
read () {
|
||||||
|
for (const chunk of decodeBase64(data)) {
|
||||||
|
this.push(chunk)
|
||||||
|
}
|
||||||
|
this.push(null)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
readableStream.on('end', () => {
|
||||||
|
res.end()
|
||||||
|
})
|
||||||
|
readableStream.pipe(res)
|
||||||
|
} catch (error) {
|
||||||
|
sendErrorResponse(res, 500, error.message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Forwards a message to a destination chat.
|
* Forwards a message to a destination chat.
|
||||||
* @async
|
* @async
|
||||||
|
|
@ -684,6 +734,7 @@ module.exports = {
|
||||||
getClassInfo,
|
getClassInfo,
|
||||||
deleteMessage,
|
deleteMessage,
|
||||||
downloadMedia,
|
downloadMedia,
|
||||||
|
downloadMediaAsData,
|
||||||
forward,
|
forward,
|
||||||
getInfo,
|
getInfo,
|
||||||
getMentions,
|
getMentions,
|
||||||
|
|
|
||||||
|
|
@ -170,6 +170,7 @@ routes.use('/message', messageRouter)
|
||||||
messageRouter.post('/getClassInfo/:sessionId', [middleware.sessionNameValidation, middleware.sessionValidation], messageController.getClassInfo)
|
messageRouter.post('/getClassInfo/:sessionId', [middleware.sessionNameValidation, middleware.sessionValidation], messageController.getClassInfo)
|
||||||
messageRouter.post('/delete/:sessionId', [middleware.sessionNameValidation, middleware.sessionValidation], messageController.deleteMessage)
|
messageRouter.post('/delete/:sessionId', [middleware.sessionNameValidation, middleware.sessionValidation], messageController.deleteMessage)
|
||||||
messageRouter.post('/downloadMedia/:sessionId', [middleware.sessionNameValidation, middleware.sessionValidation], messageController.downloadMedia)
|
messageRouter.post('/downloadMedia/:sessionId', [middleware.sessionNameValidation, middleware.sessionValidation], messageController.downloadMedia)
|
||||||
|
messageRouter.post('/downloadMediaAsData/:sessionId', [middleware.sessionNameValidation, middleware.sessionValidation], messageController.downloadMediaAsData)
|
||||||
messageRouter.post('/forward/:sessionId', [middleware.sessionNameValidation, middleware.sessionValidation], messageController.forward)
|
messageRouter.post('/forward/:sessionId', [middleware.sessionNameValidation, middleware.sessionValidation], messageController.forward)
|
||||||
messageRouter.post('/getInfo/:sessionId', [middleware.sessionNameValidation, middleware.sessionValidation], messageController.getInfo)
|
messageRouter.post('/getInfo/:sessionId', [middleware.sessionNameValidation, middleware.sessionValidation], messageController.getInfo)
|
||||||
messageRouter.post('/getMentions/:sessionId', [middleware.sessionNameValidation, middleware.sessionValidation], messageController.getMentions)
|
messageRouter.post('/getMentions/:sessionId', [middleware.sessionNameValidation, middleware.sessionValidation], messageController.getMentions)
|
||||||
|
|
|
||||||
11
src/utils.js
11
src/utils.js
|
|
@ -51,10 +51,19 @@ const sendMessageSeenStatus = async (message) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const decodeBase64 = function * (base64String) {
|
||||||
|
const chunkSize = 1024
|
||||||
|
for (let i = 0; i < base64String.length; i += chunkSize) {
|
||||||
|
const chunk = base64String.slice(i, i + chunkSize)
|
||||||
|
yield Buffer.from(chunk, 'base64')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
triggerWebhook,
|
triggerWebhook,
|
||||||
sendErrorResponse,
|
sendErrorResponse,
|
||||||
waitForNestedObject,
|
waitForNestedObject,
|
||||||
checkIfEventisEnabled,
|
checkIfEventisEnabled,
|
||||||
sendMessageSeenStatus
|
sendMessageSeenStatus,
|
||||||
|
decodeBase64
|
||||||
}
|
}
|
||||||
|
|
|
||||||
110
swagger.json
110
swagger.json
|
|
@ -8664,6 +8664,116 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/message/downloadMediaAsData/{sessionId}": {
|
||||||
|
"post": {
|
||||||
|
"tags": [
|
||||||
|
"Message"
|
||||||
|
],
|
||||||
|
"summary": "Download attached message media as binary data",
|
||||||
|
"description": "",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "sessionId",
|
||||||
|
"in": "path",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"description": "Unique identifier for the session (alphanumeric and - allowed)",
|
||||||
|
"example": "f8377d8d-a589-4242-9ba6-9486a04ef80c"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Binary data."
|
||||||
|
},
|
||||||
|
"403": {
|
||||||
|
"description": "Forbidden.",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/ForbiddenResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"404": {
|
||||||
|
"description": "Not Found.",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/NotFoundResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"422": {
|
||||||
|
"description": "Unprocessable Entity.",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/ErrorResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Server failure.",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/ErrorResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"apiKeyAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"requestBody": {
|
||||||
|
"required": true,
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"chatId": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "The chat id which contains the message",
|
||||||
|
"example": "6281288888888@c.us"
|
||||||
|
},
|
||||||
|
"messageId": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Unique WhatsApp ID for the message",
|
||||||
|
"example": "ABCDEF999999999"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"application/xml": {
|
||||||
|
"schema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"chatId": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "The chat id which contains the message",
|
||||||
|
"example": "6281288888888@c.us"
|
||||||
|
},
|
||||||
|
"messageId": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Unique WhatsApp ID for the message",
|
||||||
|
"example": "ABCDEF999999999"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/message/forward/{sessionId}": {
|
"/message/forward/{sessionId}": {
|
||||||
"post": {
|
"post": {
|
||||||
"tags": [
|
"tags": [
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue