diff --git a/index.d.ts b/index.d.ts index 2421ab3..c3c4d6c 100644 --- a/index.d.ts +++ b/index.d.ts @@ -692,6 +692,7 @@ declare namespace WAWebJS { export interface MediaFromURLOptions { client?: Client + filename?: string unsafeMime?: boolean reqOptions?: RequestInit } diff --git a/src/structures/MessageMedia.js b/src/structures/MessageMedia.js index 4174b06..548015a 100644 --- a/src/structures/MessageMedia.js +++ b/src/structures/MessageMedia.js @@ -5,7 +5,7 @@ const path = require('path'); const mime = require('mime'); const fetch = require('node-fetch'); const { URL } = require('url'); - +const { Client } = require('whatsapp-web.js'); // eslint-disable-line no-unused-vars /** * Media attached to a message * @param {string} mimetype MIME type of the attachment @@ -50,27 +50,25 @@ class MessageMedia { * Creates a MessageMedia instance from a URL * @param {string} url * @param {Object} [options] - * @param {number} [options.unsafeMime=false] - * @param {object} [options.client] + * @param {boolean} [options.unsafeMime=false] + * @param {string} [options.filename] + * @param {Client} [options.client] * @param {object} [options.reqOptions] * @param {number} [options.reqOptions.size=0] * @returns {Promise} */ static async fromUrl(url, options = {}) { - let mimetype; + const pUrl = new URL(url); + let mimetype = mime.getType(pUrl.pathname); - if (!options.unsafeMime) { - const pUrl = new URL(url); - mimetype = mime.getType(pUrl.pathname); - - if (!mimetype) - throw new Error('Unable to determine MIME type'); - } + if (!mimetype && !options.unsafeMime) + throw new Error('Unable to determine MIME type using URL. Set unsafeMime to true to download it anyway.'); async function fetchData (url, options) { const reqOptions = Object.assign({ headers: { accept: 'image/* video/* text/* audio/*' } }, options); const response = await fetch(url, reqOptions); const mime = response.headers.get('Content-Type'); + const name = response.headers.get('Content-Disposition')?.match(/((?<=filename=")(.*)(?="))/); let data = ''; if (response.buffer) { @@ -83,18 +81,21 @@ class MessageMedia { data = btoa(data); } - return { data, mime }; + return { data, mime, name }; } const res = options.client ? (await options.client.pupPage.evaluate(fetchData, url, options.reqOptions)) : (await fetchData(url, options.reqOptions)); + const filename = options.filename ?? + (res.name ? res.name[0] : (pUrl.pathname.split('/').pop() || 'file')); + if (!mimetype) mimetype = res.mime; - return new MessageMedia(mimetype, res.data, null); + return new MessageMedia(mimetype, res.data, filename); } } -module.exports = MessageMedia; \ No newline at end of file +module.exports = MessageMedia;