From d9ae732bfd1bceac5d0c0c777e99ac08798c26e4 Mon Sep 17 00:00:00 2001 From: Manuel Kraus Date: Mon, 29 Aug 2016 20:01:05 +0200 Subject: [PATCH] Add sendFile function (#562) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * sendFile * Add default value to filename * eslint * (╯°□°)╯︵ ┻━┻ --- package.json | 4 +- src/client/ClientDataResolver.js | 39 ++++++++++++++++++++ src/client/rest/APIRequest.js | 8 ++-- src/client/rest/RESTMethods.js | 4 +- src/structures/DMChannel.js | 4 ++ src/structures/GroupDMChannel.js | 4 ++ src/structures/GuildMember.js | 4 ++ src/structures/TextChannel.js | 4 ++ src/structures/User.js | 4 ++ src/structures/interface/TextBasedChannel.js | 21 ++++++++++- 10 files changed, 87 insertions(+), 9 deletions(-) diff --git a/package.json b/package.json index 033892fd0..a9de93b2c 100644 --- a/package.json +++ b/package.json @@ -32,8 +32,8 @@ "opusscript": "^0.0.1" }, "devDependencies": { - "jsdoc-parse": "^1.2.7", - "fs-extra": "^0.30.0" + "fs-extra": "^0.30.0", + "jsdoc-parse": "^1.2.7" }, "optionalDependencies": { "node-opus": "^0.1.13" diff --git a/src/client/ClientDataResolver.js b/src/client/ClientDataResolver.js index b588ff277..040e641e7 100644 --- a/src/client/ClientDataResolver.js +++ b/src/client/ClientDataResolver.js @@ -1,3 +1,7 @@ +const path = require('path'); +const fs = require('fs'); +const request = require('superagent'); + const getStructure = name => require(`../structures/${name}`); const User = getStructure('User'); @@ -163,6 +167,41 @@ class ClientDataResolver { return String(data); } + + /** + * Data that can be resolved to give a Buffer. This can be: + * * A Buffer + * * The path to a local file + * * An URL + * @typedef {String|Buffer} FileResolvable + */ + + /** + * Resolves a FileResolvable to a Buffer + * @param {FileResolvable} fileResolvable the file resolvable to resolve + * @returns {String|Buffer} + */ + resolveFile(resource) { + if ($string(resource)) { + return new Promise((resolve, reject) => { + if (/^https?:\/\//.test(resource)) { + request.get(resource) + .set('Content-Type', 'blob') + .end((err, res) => err ? reject(err) : resolve(res.body)); + } else { + const file = path.resolve(resource); + const stat = fs.statSync(file); + if (!stat.isFile()) { + return reject(new Error(`The file could not be found: ${file}`)); + } + + return resolve(fs.readFileSync(file)); + } + }); + } + + return Promise.resolve(resource); + } } module.exports = ClientDataResolver; diff --git a/src/client/rest/APIRequest.js b/src/client/rest/APIRequest.js index e27e5833c..c56d1ebf1 100644 --- a/src/client/rest/APIRequest.js +++ b/src/client/rest/APIRequest.js @@ -29,12 +29,14 @@ class APIRequest { if (this.auth) { apiRequest.set('authorization', this.getAuth()); } + if (this.file && this.file.file) { + apiRequest.set('Content-Type', 'multipart/form-data'); + apiRequest.attach('file', this.file.file, this.file.name); + } if (this.data) { apiRequest.send(this.data); } - if (this.file) { - apiRequest.attach('file', this.file.file, this.file.name); - } + apiRequest.set('User-Agent', this.rest.userAgentManager.userAgent); return apiRequest; } diff --git a/src/client/rest/RESTMethods.js b/src/client/rest/RESTMethods.js index 25166add0..019491d75 100644 --- a/src/client/rest/RESTMethods.js +++ b/src/client/rest/RESTMethods.js @@ -41,7 +41,7 @@ class RESTMethods { }); } - sendMessage($channel, content, tts, nonce) { + sendMessage($channel, content, tts, nonce, file) { return new Promise((resolve, reject) => { const $this = this; let channel = $channel; @@ -49,7 +49,7 @@ class RESTMethods { function req() { $this.rest.makeRequest('post', Constants.Endpoints.channelMessages(channel.id), true, { content, tts, nonce, - }) + }, file) .then(data => resolve($this.rest.client.actions.MessageCreate.handle(data).m)) .catch(reject); } diff --git a/src/structures/DMChannel.js b/src/structures/DMChannel.js index b591d2c9c..eb56bd25a 100644 --- a/src/structures/DMChannel.js +++ b/src/structures/DMChannel.js @@ -47,6 +47,10 @@ class DMChannel extends Channel { return; } + sendFile() { + return; + } + _cacheMessage() { return; } diff --git a/src/structures/GroupDMChannel.js b/src/structures/GroupDMChannel.js index 9760c0b10..4505b0fcf 100644 --- a/src/structures/GroupDMChannel.js +++ b/src/structures/GroupDMChannel.js @@ -124,6 +124,10 @@ class GroupDMChannel extends Channel { return; } + sendFile() { + return; + } + _cacheMessage() { return; } diff --git a/src/structures/GuildMember.js b/src/structures/GuildMember.js index 5da424e5f..a40e73f96 100644 --- a/src/structures/GuildMember.js +++ b/src/structures/GuildMember.js @@ -222,6 +222,10 @@ class GuildMember { sendTTSMessage() { return; } + + sendFile() { + return; + } } TextBasedChannel.applyToClass(GuildMember); diff --git a/src/structures/TextChannel.js b/src/structures/TextChannel.js index c101f1721..3cb0b94d2 100644 --- a/src/structures/TextChannel.js +++ b/src/structures/TextChannel.js @@ -32,6 +32,10 @@ class TextChannel extends GuildChannel { return; } + sendFile() { + return; + } + _cacheMessage() { return; } diff --git a/src/structures/User.js b/src/structures/User.js index de16f1f8c..4dce49145 100644 --- a/src/structures/User.js +++ b/src/structures/User.js @@ -122,6 +122,10 @@ class User { sendTTSMessage() { return; } + + sendFile() { + return; + } } TextBasedChannel.applyToClass(User); diff --git a/src/structures/interface/TextBasedChannel.js b/src/structures/interface/TextBasedChannel.js index e7267279a..c83817015 100644 --- a/src/structures/interface/TextBasedChannel.js +++ b/src/structures/interface/TextBasedChannel.js @@ -68,7 +68,24 @@ class TextBasedChannel { sendTTSMessage(content, options = {}) { return this.client.rest.methods.sendMessage(this, content, true, options.nonce); } - + /** + * Send a file to this channel + * @param {FileResolvable} attachment The file to send + * @param {String} [fileName="file.jpg"] The name and extension of the file + * @returns {Promise} + */ + sendFile(attachment, fileName = 'file.jpg') { + return new Promise((resolve, reject) => { + this.client.resolver.resolveFile(attachment) + .then(file => { + this.client.rest.methods.sendMessage(this, undefined, false, undefined, { + file, + name: fileName, + }).then(resolve).catch(reject); + }) + .catch(reject); + }); + } /** * The parameters to pass in when requesting previous messages from a channel. `around`, `before` and * `after` are mutually exclusive. All the parameters are optional. @@ -173,7 +190,7 @@ function applyProp(structure, prop) { } exports.applyToClass = (structure, full = false) => { - const props = ['sendMessage', 'sendTTSMessage']; + const props = ['sendMessage', 'sendTTSMessage', 'sendFile']; if (full) { props.push('_cacheMessage'); props.push('getMessages');