feat: Add MessageMedia.fromUrl method (#769)

This commit is contained in:
Wictor Nogueira
2021-07-31 10:36:11 -03:00
committed by GitHub
parent 9c2592e164
commit cd774bef17
3 changed files with 63 additions and 0 deletions

10
index.d.ts vendored
View File

@@ -1,5 +1,6 @@
import { EventEmitter } from 'events'
import { RequestInit } from 'node-fetch'
import puppeteer = require('puppeteer')
declare namespace WAWebJS {
@@ -664,6 +665,12 @@ declare namespace WAWebJS {
stickerCategories?: string[]
}
export interface MediaFromURLOptions {
client?: Client
unsafeMime?: boolean
reqOptions?: RequestInit
}
/** Media attached to a message */
export class MessageMedia {
/** MIME type of the attachment */
@@ -682,6 +689,9 @@ declare namespace WAWebJS {
/** Creates a MessageMedia instance from a local file path */
static fromFilePath: (filePath: string) => MessageMedia
/** Creates a MessageMedia instance from a URL */
static fromUrl: (url: string, options?: MediaFromURLOptions) => Promise<MessageMedia>
}
export type MessageContent = string | MessageMedia | Location | Contact | Contact[]

View File

@@ -37,6 +37,7 @@
"sharp": "^0.28.3"
},
"devDependencies": {
"@types/node-fetch": "^2.5.11",
"chai": "^4.3.4",
"dotenv": "^10.0.0",
"eslint": "^7.27.0",

View File

@@ -3,6 +3,8 @@
const fs = require('fs');
const path = require('path');
const mime = require('mime');
const fetch = require('node-fetch');
const { URL } = require('url');
/**
* Media attached to a message
@@ -43,6 +45,56 @@ class MessageMedia {
return new MessageMedia(mimetype, b64data, filename);
}
/**
* Creates a MessageMedia instance from a URL
* @param {string} url
* @param {Object} [options]
* @param {number} [options.unsafeMime=false]
* @param {object} [options.client]
* @param {object} [options.reqOptions]
* @param {number} [options.reqOptions.size=0]
* @returns {Promise<MessageMedia>}
*/
static async fromUrl(url, options = {}) {
let mimetype;
if (!options.unsafeMime) {
const pUrl = new URL(url);
mimetype = mime.getType(pUrl.pathname);
if (!mimetype)
throw new Error('Unable to determine MIME type');
}
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');
let data = '';
if (response.buffer) {
data = (await response.buffer()).toString('base64');
} else {
const bArray = new Uint8Array(await response.arrayBuffer());
bArray.forEach((b) => {
data += String.fromCharCode(b);
});
data = btoa(data);
}
return { data, mime };
}
const res = options.client
? (await options.client.pupPage.evaluate(fetchData, url, options.reqOptions))
: (await fetchData(url, options.reqOptions));
if (!mimetype)
mimetype = res.mime;
return new MessageMedia(mimetype, res.data, null);
}
}
module.exports = MessageMedia;