fix: allow media upload retries

This commit is contained in:
canove
2025-05-06 08:06:05 -03:00
parent 8cc8b44724
commit f58a38fde9
4 changed files with 19 additions and 7 deletions

View File

@@ -236,7 +236,7 @@ export type MessageGenerationOptionsFromContent = MiscMessageGenerationOptions &
userJid: string userJid: string
} }
export type WAMediaUploadFunction = (readStream: Readable, opts: { fileEncSha256B64: string, mediaType: MediaType, timeoutMs?: number }) => Promise<{ mediaUrl: string, directPath: string }> export type WAMediaUploadFunction = (encFilePath: string, opts: { fileEncSha256B64: string, mediaType: MediaType, timeoutMs?: number }) => Promise<{ mediaUrl: string, directPath: string }>
export type MediaGenerationOptions = { export type MediaGenerationOptions = {
logger?: ILogger logger?: ILogger

View File

@@ -1,7 +1,11 @@
import { Boom } from '@hapi/boom' import { Boom } from '@hapi/boom'
import { createHash } from 'crypto' import { createHash } from 'crypto'
import { createWriteStream, promises as fs } from 'fs'
import { tmpdir } from 'os'
import { join } from 'path'
import { CatalogCollection, CatalogStatus, OrderDetails, OrderProduct, Product, ProductCreate, ProductUpdate, WAMediaUpload, WAMediaUploadFunction } from '../Types' import { CatalogCollection, CatalogStatus, OrderDetails, OrderProduct, Product, ProductCreate, ProductUpdate, WAMediaUpload, WAMediaUploadFunction } from '../Types'
import { BinaryNode, getBinaryNodeChild, getBinaryNodeChildren, getBinaryNodeChildString } from '../WABinary' import { BinaryNode, getBinaryNodeChild, getBinaryNodeChildren, getBinaryNodeChildString } from '../WABinary'
import { generateMessageIDV2 } from './generics'
import { getStream, getUrlFromDirectPath, toReadable } from './messages-media' import { getStream, getUrlFromDirectPath, toReadable } from './messages-media'
export const parseCatalogNode = (node: BinaryNode) => { export const parseCatalogNode = (node: BinaryNode) => {
@@ -235,22 +239,30 @@ export const uploadingNecessaryImages = async(
const { stream } = await getStream(img) const { stream } = await getStream(img)
const hasher = createHash('sha256') const hasher = createHash('sha256')
const contentBlocks: Buffer[] = []
const filePath = join(tmpdir(), 'img' + generateMessageIDV2())
const encFileWriteStream = createWriteStream(filePath)
for await (const block of stream) { for await (const block of stream) {
hasher.update(block) hasher.update(block)
contentBlocks.push(block) encFileWriteStream.write(block)
} }
const sha = hasher.digest('base64') const sha = hasher.digest('base64')
const { directPath } = await waUploadToServer( const { directPath } = await waUploadToServer(
toReadable(Buffer.concat(contentBlocks)), filePath,
{ {
mediaType: 'product-catalog-image', mediaType: 'product-catalog-image',
fileEncSha256B64: sha, fileEncSha256B64: sha,
timeoutMs timeoutMs
} }
) )
await fs
.unlink(filePath)
.catch(err => console.log('Error deleting temp file ', err))
return { url: getUrlFromDirectPath(directPath) } return { url: getUrlFromDirectPath(directPath) }
} }
) )

View File

@@ -606,7 +606,7 @@ export const getWAUploadToServer = (
{ customUploadHosts, fetchAgent, logger, options }: SocketConfig, { customUploadHosts, fetchAgent, logger, options }: SocketConfig,
refreshMediaConn: (force: boolean) => Promise<MediaConnInfo>, refreshMediaConn: (force: boolean) => Promise<MediaConnInfo>,
): WAMediaUploadFunction => { ): WAMediaUploadFunction => {
return async(stream, { mediaType, fileEncSha256B64, timeoutMs }) => { return async(filePath, { mediaType, fileEncSha256B64, timeoutMs }) => {
// send a query JSON to obtain the url & auth token to upload our media // send a query JSON to obtain the url & auth token to upload our media
let uploadInfo = await refreshMediaConn(false) let uploadInfo = await refreshMediaConn(false)
@@ -626,7 +626,7 @@ export const getWAUploadToServer = (
const body = await axios.post( const body = await axios.post(
url, url,
stream, createReadStream(filePath),
{ {
...options, ...options,
maxRedirects: 0, maxRedirects: 0,

View File

@@ -177,7 +177,7 @@ export const prepareWAMessageMedia = async(
const [{ mediaUrl, directPath }] = await Promise.all([ const [{ mediaUrl, directPath }] = await Promise.all([
(async() => { (async() => {
const result = await options.upload( const result = await options.upload(
createReadStream(encFilePath), encFilePath,
{ fileEncSha256B64, mediaType, timeoutMs: options.mediaUploadTimeoutMs } { fileEncSha256B64, mediaType, timeoutMs: options.mediaUploadTimeoutMs }
) )
logger?.debug({ mediaType, cacheableKey }, 'uploaded media') logger?.debug({ mediaType, cacheableKey }, 'uploaded media')