Add support for stream as media message input (#905)

* Add support for stream as media message input

* refactor: use async/await on readable toBuffer

* refactor: be more explicit about using a readable stream

Co-authored-by: Adhiraj Singh <adhirajsingh1001@gmail.com>
This commit is contained in:
Maurilho Batista
2021-11-26 02:00:15 -03:00
committed by GitHub
parent 6e830c1e1b
commit e810f2dec5
3 changed files with 25 additions and 4 deletions

View File

@@ -100,7 +100,7 @@ export const makeChatsSocket = (config: SocketConfig) => {
}
const updateProfilePicture = async(jid: string, content: WAMediaUpload) => {
const { img } = await generateProfilePicture('url' in content ? content.url.toString() : content)
const { img } = await generateProfilePicture(content)
await query({
tag: 'iq',
attrs: {

View File

@@ -3,6 +3,7 @@ import type { Logger } from "pino"
import type { URL } from "url"
import type NodeCache from "node-cache"
import type { GroupMetadata } from "./GroupMetadata"
import type { Readable } from "stream"
import { proto } from '../../WAProto'
// export the WAMessage Prototypes
@@ -18,7 +19,7 @@ export type WALocationMessage = proto.ILocationMessage
export type WAGenericMediaMessage = proto.IVideoMessage | proto.IImageMessage | proto.IAudioMessage | proto.IDocumentMessage | proto.IStickerMessage
export import WAMessageStubType = proto.WebMessageInfo.WebMessageInfoStubType
export import WAMessageStatus = proto.WebMessageInfo.WebMessageInfoStatus
export type WAMediaUpload = Buffer | { url: URL | string }
export type WAMediaUpload = Buffer | { url: URL | string } | { stream: Readable }
/** Set of message types that are supported by the library */
export type MessageType = keyof proto.Message

View File

@@ -51,13 +51,25 @@ const extractVideoThumb = async (
})
}) as Promise<void>
export const compressImage = async (bufferOrFilePath: Buffer | string) => {
export const compressImage = async (bufferOrFilePath: Readable | Buffer | string) => {
if(bufferOrFilePath instanceof Readable) {
bufferOrFilePath = await toBuffer(bufferOrFilePath)
}
const { read, MIME_JPEG } = await import('jimp')
const jimp = await read(bufferOrFilePath as any)
const result = await jimp.resize(32, 32).getBufferAsync(MIME_JPEG)
return result
}
export const generateProfilePicture = async (bufferOrFilePath: Buffer | string) => {
export const generateProfilePicture = async (mediaUpload: WAMediaUpload) => {
let bufferOrFilePath: Buffer | string
if(Buffer.isBuffer(mediaUpload)) {
bufferOrFilePath = mediaUpload
} else if('url' in mediaUpload) {
bufferOrFilePath = mediaUpload.url.toString()
} else {
bufferOrFilePath = await toBuffer(mediaUpload.stream)
}
const { read, MIME_JPEG } = await import('jimp')
const jimp = await read(bufferOrFilePath as any)
const min = Math.min(jimp.getWidth (), jimp.getHeight ())
@@ -89,8 +101,16 @@ export const toReadable = (buffer: Buffer) => {
readable.push(null)
return readable
}
export const toBuffer = async(stream: Readable) => {
let buff = Buffer.alloc(0)
for await(const chunk of stream) {
buff = Buffer.concat([ buff, chunk ])
}
return buff
}
export const getStream = async (item: WAMediaUpload) => {
if(Buffer.isBuffer(item)) return { stream: toReadable(item), type: 'buffer' }
if('stream' in item) return { stream: item.stream, type: 'readable' }
if(item.url.toString().startsWith('http://') || item.url.toString().startsWith('https://')) {
return { stream: await getGotStream(item.url), type: 'remote' }
}