diff --git a/src/puppet-puppeteer.ts b/src/puppet-puppeteer.ts index 23212e7..845d40e 100644 --- a/src/puppet-puppeteer.ts +++ b/src/puppet-puppeteer.ts @@ -1427,51 +1427,74 @@ export class PuppetPuppeteer extends Puppet { log.verbose('PuppetPuppeteer', 'uploadMedia() webwx_data_ticket: %s', webwxDataTicket) log.verbose('PuppetPuppeteer', 'uploadMedia() pass_ticket: %s', passTicket) - const formData = { - filename: { - options: { - contentType, - filename, - size, - }, - value: buffer, - }, - id, - lastModifiedDate: Date().toString(), - mediatype, - name: filename, - pass_ticket: passTicket || '', - size, - type: contentType, - uploadmediarequest: JSON.stringify(uploadMediaRequest), - webwx_data_ticket: webwxDataTicket, + /** + * If FILE.SIZE > 1M, file buffer need to split for upload. + * Split strategy: + * BASE_LENGTH: 512 * 1024 + * chunks: split number + * chunk: the index of chunks + */ + const BASE_LENGTH = 512 * 1024 + const chunks = Math.ceil(buffer.length / BASE_LENGTH) + + const bufferData = [] + for (let i = 0; i < chunks; i++) { + let tempBuffer = buffer.slice(i * BASE_LENGTH, (i + 1) * BASE_LENGTH) + bufferData.push(tempBuffer) } - let mediaId: string - try { - mediaId = await new Promise((resolve, reject) => { - try { - request.post({ - formData, - headers, - url: uploadMediaUrl + '?f=json', - }, (err, _, body) => { - if (err) { - reject(err) - } else { - let obj = body - if (typeof body !== 'object') { - obj = JSON.parse(body) + + async function getMediaId (buffer: Buffer, index: number) : Promise { + const formData = { + chunk: index, + chunks, + filename: { + options: { + contentType, + filename, + size, + }, + value: buffer, + }, + id, + lastModifiedDate: Date().toString(), + mediatype, + name: filename, + pass_ticket: passTicket || '', + size, + type: contentType, + uploadmediarequest: JSON.stringify(uploadMediaRequest), + webwx_data_ticket: webwxDataTicket, + } + try { + return await new Promise((resolve, reject) => { + try { + request.post({ + formData, + headers, + url: uploadMediaUrl + '?f=json', + }, (err, _, body) => { + if (err) { + reject(err) + } else { + let obj = body + if (typeof body !== 'object') { + obj = JSON.parse(body) + } + resolve(obj.MediaId || '') } - resolve(obj.MediaId || '') - } - }) - } catch (e) { - reject(e) - } - }) - } catch (e) { - log.error('PuppetPuppeteer', 'uploadMedia() uploadMedia exception: %s', e.message) - throw new Error('uploadMedia err: ' + e.message) + }) + } catch (e) { + reject(e) + } + }) + } catch (e) { + log.error('PuppetPuppeteer', 'uploadMedia() uploadMedia exception: %s', e.message) + throw new Error('uploadMedia err: ' + e.message) + } + } + let mediaId = '' + for (let i = 0; i < bufferData.length; i++) { + mediaId = await getMediaId(bufferData[i], i) } if (!mediaId) { log.error('PuppetPuppeteer', 'uploadMedia(): upload fail') diff --git a/src/web-schemas.ts b/src/web-schemas.ts index 3ca48b3..21f6c95 100644 --- a/src/web-schemas.ts +++ b/src/web-schemas.ts @@ -275,10 +275,10 @@ export interface WebRecomendInfo { } export const enum WebMediaType { - Image = 1, - Video = 2, - Audio = 3, - Attachment = 4, + Image = 'pic', + Video = 'video', + Attachment = 'doc', + // Audio = 3, useless now } export interface WebRoomRawMember {