diff --git a/src/Socket/chats.ts b/src/Socket/chats.ts index 7ed3e5e..295cfcc 100644 --- a/src/Socket/chats.ts +++ b/src/Socket/chats.ts @@ -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: { diff --git a/src/Types/Message.ts b/src/Types/Message.ts index fb768f2..5445cdb 100644 --- a/src/Types/Message.ts +++ b/src/Types/Message.ts @@ -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 diff --git a/src/Utils/messages-media.ts b/src/Utils/messages-media.ts index 05f3253..a32342a 100644 --- a/src/Utils/messages-media.ts +++ b/src/Utils/messages-media.ts @@ -51,13 +51,25 @@ const extractVideoThumb = async ( }) }) as Promise -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' } }