diff --git a/docs/docs_client.rst b/docs/docs_client.rst index 13ed9ef55..733cc7451 100644 --- a/docs/docs_client.rst +++ b/docs/docs_client.rst @@ -305,6 +305,7 @@ Gets a list of previously sent messages in a channel. - **options** - An `object` containing either of the following: - **before** - A `Message Resolvable`_ - gets messages before this message. - **after** - A `Message Resolvable`_ - gets messages after this message. + - **around** - A `Message Resolvable`_ - gets the messages around this message. - **callback** - `function` taking the following: - **error** - error if any occurred - **messages** - `array` of Message_ objects sent in channel @@ -318,7 +319,35 @@ Gets a message. This also works for messages that aren't cached but will only wo - **messageID** - The message id to get the message object from. A `String` - **callback** - `function` taking the following: - **error** - error if any occurred - - **message** - The `Message_` + - **message** - The `Message`_ + +pinMessage(message, `callback`) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Pins a message to a channel. + +- **message** - The Message_ to pin. +- **callback** - `function` taking the following: + - **error** - error if any occurred + +unpinMessage(message, `callback`) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Unpins a message to a channel. + +- **message** - The Message_ to unpin. +- **callback** - `function` taking the following: + - **error** - error if any occurred + +getPinnedMessages(channel, `callback`) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Gets a list of all pinned messages in a channel. + +- **channel** - The Channel_ to get pins from +- **callback** - `function` taking the following: + - **error** - error if any occurred + - **messages** - `array` of Message_ objects that are pinned. getBans(server, `callback`) ~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/docs_message.rst b/docs/docs_message.rst index a638b76d4..1a98abd7f 100644 --- a/docs/docs_message.rst +++ b/docs/docs_message.rst @@ -84,6 +84,11 @@ mentions A array of User_ objects that were mentioned in the message. +pinned +~~~~~~ + +`Boolean`, true if the message is pinned to its channel. + Functions --------- diff --git a/lib/Client/Client.js b/lib/Client/Client.js index b2c5d320d..618d8acb1 100644 --- a/lib/Client/Client.js +++ b/lib/Client/Client.js @@ -544,6 +544,94 @@ var Client = (function (_EventEmitter) { return this.internal.getMessage(channel, messageID).then(dataCallback(callback), errorCallback(callback)); }; + /** + * Pins a message to a channel. + * @param {MessageResolvable} message to pin. + * @returns {Promise} resolves null if successful, otherwise rejects with an error. + * @example + * // pin message - callback + * client.pinMessage(msg, (err) => { + * if(!err) { + * console.log("Successfully pinned message") + * } else { + * console.log("Couldn't pin the message: " + err); + * } + * }); + * @example + * // pin message - promise + * client.pinMessage(msg) + * .then(() => { + * console.log("Successfully pinned message"); + * }) + * .catch(err => console.log("Couldn't pin the message: " + err)); + */ + + Client.prototype.pinMessage = function pinMessage(msg) { + var callback = arguments.length <= 1 || arguments[1] === undefined ? function () /*err*/{} : arguments[1]; + + return this.internal.pinMessage(msg).then(dataCallback(callback), errorCallback(callback)); + }; + + /** + * Unpins a message to a server. + * @param {MessageResolvable} message to unpin. + * @returns {Promise} resolves null if successful, otherwise rejects with an error. + * @example + * // unpin message - callback + * client.unpinMessage(msg, (err) => { + * if(!err) { + * console.log("Successfully unpinned message") + * } else { + * console.log("Couldn't pin the message: " + err); + * } + * }); + * @example + * // unpin message - promise + * client.unpinMessage(msg) + * .then(() => { + * console.log("Successfully unpinned message"); + * }) + * .catch(err => console.log("Couldn't unpin the message: " + err)); + */ + + Client.prototype.unpinMessage = function unpinMessage(msg) { + var callback = arguments.length <= 1 || arguments[1] === undefined ? function () /*err*/{} : arguments[1]; + + return this.internal.unpinMessage(msg).then(dataCallback(callback), errorCallback(callback)); + }; + + /** + * Gets all pinned messages of a channel. + * @param {TextChannelResolvable} where to get the pins from. + * @returns {Promise, Error>} Resolves with an array of messages if successful, otherwise rejects with an error. + * @example + * // log all pinned messages - callback + * client.getPinnedMessages(channel, (err, messages) => { + * if(!err) { + * for(var message of messages) { + * console.log(message.content); + * } + * } else { + * console.log("Couldn't fetch pins: " + err); + * } + * }); + * @example + * // log all pinned messages - promise + * client.getPinnedMessages(channel) + * .then(messages => { + * for(var message of messages) { + * console.log(message.content); + * } + * }) + * .catch(err => console.log("Couldn't fetch pins: " + err)); + */ + + Client.prototype.getPinnedMessages = function getPinnedMessages(channel) { + var callback = arguments.length <= 1 || arguments[1] === undefined ? function () /*err, messages*/{} : arguments[1]; + + return this.internal.getPinnedMessages(channel).then(dataCallback(callback), errorCallback(callback)); + }; + /** * Gets the banned users of a server (if the client has permission to) * @param {ServerResolvable} server server to get banned users of diff --git a/lib/Client/InternalClient.js b/lib/Client/InternalClient.js index 40682c2ac..296068c9a 100644 --- a/lib/Client/InternalClient.js +++ b/lib/Client/InternalClient.js @@ -909,6 +909,12 @@ var InternalClient = (function () { qsObject.after = res.id; } } + if (options.around) { + var res = _this19.resolver.resolveMessage(options.around); + if (res) { + qsObject.around = res.id; + } + } return _this19.apiRequest("get", _Constants.Endpoints.CHANNEL_MESSAGES(channel.id) + "?" + _querystring2["default"].stringify(qsObject), true).then(function (res) { return res.map(function (msg) { @@ -943,16 +949,58 @@ var InternalClient = (function () { }); }; + // def pinMessage + + InternalClient.prototype.pinMessage = function pinMessage(msg) { + var message = this.resolver.resolveMessage(msg); + + if (!message) { + return Promise.reject(new Error("Supplied message did not resolve to a message")); + } + + return this.apiRequest("put", "" + _Constants.Endpoints.CHANNEL_PIN(msg.channel.id, msg.id), true); + }; + + // def unpinMessage + + InternalClient.prototype.unpinMessage = function unpinMessage(msg) { + var message = this.resolver.resolveMessage(msg); + + if (!message) { + return Promise.reject(new Error("Supplied message did not resolve to a message")); + } + + if (!message.pinned) { + return Promise.reject(new Error("Supplied message is not pinned")); + } + + return this.apiRequest("del", "" + _Constants.Endpoints.CHANNEL_PIN(msg.channel.id, msg.id), true); + }; + + // def getPinnedMessages + + InternalClient.prototype.getPinnedMessages = function getPinnedMessages(_channel) { + var _this21 = this; + + return this.resolver.resolveChannel(_channel).then(function (channel) { + return _this21.apiRequest("get", "" + _Constants.Endpoints.CHANNEL_PINS(channel.id), true).then(function (res) { + return res.map(function (msg) { + return channel.messages.add(new _StructuresMessage2["default"](msg, channel, _this21.client)); + }); + }); + }); + }; + // def getBans InternalClient.prototype.getBans = function getBans(server) { - var _this21 = this; + var _this22 = this; server = this.resolver.resolveServer(server); return this.apiRequest("get", _Constants.Endpoints.SERVER_BANS(server.id), true).then(function (res) { return res.map(function (ban) { - return _this21.users.add(new _StructuresUser2["default"](ban.user, _this21.client)); + return _this22.users.add(new _StructuresUser2["default"](ban.user, _this22.client)); }); }); }; @@ -960,7 +1008,7 @@ var InternalClient = (function () { // def createChannel InternalClient.prototype.createChannel = function createChannel(server, name) { - var _this22 = this; + var _this23 = this; var type = arguments.length <= 2 || arguments[2] === undefined ? "text" : arguments[2]; @@ -972,23 +1020,23 @@ var InternalClient = (function () { }).then(function (res) { var channel; if (res.type === "text") { - channel = new _StructuresTextChannel2["default"](res, _this22.client, server); + channel = new _StructuresTextChannel2["default"](res, _this23.client, server); } else { - channel = new _StructuresVoiceChannel2["default"](res, _this22.client, server); + channel = new _StructuresVoiceChannel2["default"](res, _this23.client, server); } - return server.channels.add(_this22.channels.add(channel)); + return server.channels.add(_this23.channels.add(channel)); }); }; // def deleteChannel InternalClient.prototype.deleteChannel = function deleteChannel(_channel) { - var _this23 = this; + var _this24 = this; return this.resolver.resolveChannel(_channel).then(function (channel) { - return _this23.apiRequest("del", _Constants.Endpoints.CHANNEL(channel.id), true).then(function () { + return _this24.apiRequest("del", _Constants.Endpoints.CHANNEL(channel.id), true).then(function () { channel.server.channels.remove(channel); - _this23.channels.remove(channel); + _this24.channels.remove(channel); }); }); }; @@ -1026,7 +1074,7 @@ var InternalClient = (function () { // def moveMember InternalClient.prototype.moveMember = function moveMember(user, channel) { - var _this24 = this; + var _this25 = this; user = this.resolver.resolveUser(user); return this.resolver.resolveChannel(channel).then(function (channel) { @@ -1036,7 +1084,7 @@ var InternalClient = (function () { if (channel.type !== "voice") { throw new Error("Can't moveMember into a non-voice channel"); } else { - return _this24.apiRequest("patch", _Constants.Endpoints.SERVER_MEMBERS(server.id) + "/" + user.id, true, { channel_id: channel.id }).then(function (res) { + return _this25.apiRequest("patch", _Constants.Endpoints.SERVER_MEMBERS(server.id) + "/" + user.id, true, { channel_id: channel.id }).then(function (res) { user.voiceChannel = channel; return res; }); @@ -1101,15 +1149,15 @@ var InternalClient = (function () { // def createRole InternalClient.prototype.createRole = function createRole(server, data) { - var _this25 = this; + var _this26 = this; server = this.resolver.resolveServer(server); return this.apiRequest("post", _Constants.Endpoints.SERVER_ROLES(server.id), true).then(function (res) { - var role = server.roles.add(new _StructuresRole2["default"](res, server, _this25.client)); + var role = server.roles.add(new _StructuresRole2["default"](res, server, _this26.client)); if (data) { - return _this25.updateRole(role, data); + return _this26.updateRole(role, data); } return role; }); @@ -1118,7 +1166,7 @@ var InternalClient = (function () { // def updateRole InternalClient.prototype.updateRole = function updateRole(role, data) { - var _this26 = this; + var _this27 = this; role = this.resolver.resolveRole(role); var server = this.resolver.resolveServer(role.server); @@ -1157,7 +1205,7 @@ var InternalClient = (function () { } return this.apiRequest("patch", _Constants.Endpoints.SERVER_ROLES(server.id) + "/" + role.id, true, newData).then(function (res) { - return server.roles.update(role, new _StructuresRole2["default"](res, server, _this26.client)); + return server.roles.update(role, new _StructuresRole2["default"](res, server, _this27.client)); }); }; @@ -1174,7 +1222,7 @@ var InternalClient = (function () { //def addMemberToRole InternalClient.prototype.addMemberToRole = function addMemberToRole(member, roles) { - var _this27 = this; + var _this28 = this; member = this.resolver.resolveUser(member); @@ -1191,7 +1239,7 @@ var InternalClient = (function () { } } else { roles = roles.map(function (r) { - return _this27.resolver.resolveRole(r); + return _this28.resolver.resolveRole(r); }); } @@ -1254,7 +1302,7 @@ var InternalClient = (function () { //def removeMemberFromRole InternalClient.prototype.removeMemberFromRole = function removeMemberFromRole(member, roles) { - var _this28 = this; + var _this29 = this; member = this.resolver.resolveUser(member); @@ -1271,7 +1319,7 @@ var InternalClient = (function () { } } else { roles = roles.map(function (r) { - return _this28.resolver.resolveRole(r); + return _this29.resolver.resolveRole(r); }); } @@ -1312,7 +1360,7 @@ var InternalClient = (function () { // def createInvite InternalClient.prototype.createInvite = function createInvite(chanServ, options) { - var _this29 = this; + var _this30 = this; return this.resolver.resolveChannel(chanServ).then(function (channel) { if (!options) { @@ -1326,8 +1374,8 @@ var InternalClient = (function () { options.xkcdpass = options.xkcd || false; } - return _this29.apiRequest("post", _Constants.Endpoints.CHANNEL_INVITES(channel.id), true, options).then(function (res) { - return new _StructuresInvite2["default"](res, _this29.channels.get("id", res.channel.id), _this29.client); + return _this30.apiRequest("post", _Constants.Endpoints.CHANNEL_INVITES(channel.id), true, options).then(function (res) { + return new _StructuresInvite2["default"](res, _this30.channels.get("id", res.channel.id), _this30.client); }); }); }; @@ -1345,7 +1393,7 @@ var InternalClient = (function () { //def getInvite InternalClient.prototype.getInvite = function getInvite(invite) { - var _this30 = this; + var _this31 = this; invite = this.resolver.resolveInviteID(invite); if (!invite) { @@ -1353,11 +1401,11 @@ var InternalClient = (function () { } return this.apiRequest("get", _Constants.Endpoints.INVITE(invite), true).then(function (res) { - if (!_this30.channels.has("id", res.channel.id)) { - return new _StructuresInvite2["default"](res, null, _this30.client); + if (!_this31.channels.has("id", res.channel.id)) { + return new _StructuresInvite2["default"](res, null, _this31.client); } - return _this30.apiRequest("post", _Constants.Endpoints.CHANNEL_INVITES(res.channel.id), true, { validate: invite }).then(function (res2) { - return new _StructuresInvite2["default"](res2, _this30.channels.get("id", res.channel.id), _this30.client); + return _this31.apiRequest("post", _Constants.Endpoints.CHANNEL_INVITES(res.channel.id), true, { validate: invite }).then(function (res2) { + return new _StructuresInvite2["default"](res2, _this31.channels.get("id", res.channel.id), _this31.client); }); }); }; @@ -1365,22 +1413,22 @@ var InternalClient = (function () { //def getInvites InternalClient.prototype.getInvites = function getInvites(channel) { - var _this31 = this; + var _this32 = this; if (!(channel instanceof _StructuresChannel2["default"])) { var server = this.resolver.resolveServer(channel); if (server) { return this.apiRequest("get", _Constants.Endpoints.SERVER_INVITES(server.id), true).then(function (res) { return res.map(function (data) { - return new _StructuresInvite2["default"](data, _this31.channels.get("id", data.channel.id), _this31.client); + return new _StructuresInvite2["default"](data, _this32.channels.get("id", data.channel.id), _this32.client); }); }); } } return this.resolver.resolveChannel(channel).then(function (channel) { - return _this31.apiRequest("get", _Constants.Endpoints.CHANNEL_INVITES(channel.id), true).then(function (res) { + return _this32.apiRequest("get", _Constants.Endpoints.CHANNEL_INVITES(channel.id), true).then(function (res) { return res.map(function (data) { - return new _StructuresInvite2["default"](data, _this31.channels.get("id", data.channel.id), _this31.client); + return new _StructuresInvite2["default"](data, _this32.channels.get("id", data.channel.id), _this32.client); }); }); }); @@ -1389,7 +1437,7 @@ var InternalClient = (function () { //def overwritePermissions InternalClient.prototype.overwritePermissions = function overwritePermissions(channel, role, updated) { - var _this32 = this; + var _this33 = this; return this.resolver.resolveChannel(channel).then(function (channel) { if (!channel instanceof _StructuresServerChannel2["default"]) { @@ -1402,7 +1450,7 @@ var InternalClient = (function () { }; if (role instanceof String || typeof role === "string") { - role = _this32.resolver.resolveUser(role) || _this32.resolver.resolveRole(role); + role = _this33.resolver.resolveUser(role) || _this33.resolver.resolveRole(role); } if (role instanceof _StructuresUser2["default"]) { @@ -1435,7 +1483,7 @@ var InternalClient = (function () { } } - return _this32.apiRequest("put", _Constants.Endpoints.CHANNEL_PERMISSIONS(channel.id) + "/" + data.id, true, data); + return _this33.apiRequest("put", _Constants.Endpoints.CHANNEL_PERMISSIONS(channel.id) + "/" + data.id, true, data); }); }; @@ -1475,49 +1523,49 @@ var InternalClient = (function () { //def sendTyping InternalClient.prototype.sendTyping = function sendTyping(channel) { - var _this33 = this; + var _this34 = this; return this.resolver.resolveChannel(channel).then(function (channel) { - return _this33.apiRequest("post", _Constants.Endpoints.CHANNEL(channel.id) + "/typing", true); + return _this34.apiRequest("post", _Constants.Endpoints.CHANNEL(channel.id) + "/typing", true); }); }; //def startTyping InternalClient.prototype.startTyping = function startTyping(channel) { - var _this34 = this; + var _this35 = this; return this.resolver.resolveChannel(channel).then(function (channel) { - if (_this34.intervals.typing[channel.id]) { + if (_this35.intervals.typing[channel.id]) { // typing interval already exists, leave it alone throw new Error("Already typing in that channel"); } - _this34.intervals.typing[channel.id] = setInterval(function () { - return _this34.sendTyping(channel)["catch"](function (error) { - return _this34.emit("error", error); + _this35.intervals.typing[channel.id] = setInterval(function () { + return _this35.sendTyping(channel)["catch"](function (error) { + return _this35.emit("error", error); }); }, 4000); - return _this34.sendTyping(channel); + return _this35.sendTyping(channel); }); }; //def stopTyping InternalClient.prototype.stopTyping = function stopTyping(channel) { - var _this35 = this; + var _this36 = this; return this.resolver.resolveChannel(channel).then(function (channel) { - if (!_this35.intervals.typing[channel.id]) { + if (!_this36.intervals.typing[channel.id]) { // typing interval doesn"t exist throw new Error("Not typing in that channel"); } - clearInterval(_this35.intervals.typing[channel.id]); - _this35.intervals.typing[channel.id] = false; + clearInterval(_this36.intervals.typing[channel.id]); + _this36.intervals.typing[channel.id] = false; }); }; @@ -1608,7 +1656,7 @@ var InternalClient = (function () { //def updateChannel InternalClient.prototype.updateChannel = function updateChannel(channel, data) { - var _this36 = this; + var _this37 = this; return this.resolver.resolveChannel(channel).then(function (channel) { if (!channel) { @@ -1639,7 +1687,7 @@ var InternalClient = (function () { data.bitrate *= 1000; // convert to bits before sending } - return _this36.apiRequest("patch", _Constants.Endpoints.CHANNEL(channel.id), true, data).then(function (res) { + return _this37.apiRequest("patch", _Constants.Endpoints.CHANNEL(channel.id), true, data).then(function (res) { channel.name = data.name; channel.topic = data.topic; channel.position = data.position; @@ -1696,7 +1744,7 @@ var InternalClient = (function () { }; InternalClient.prototype.createWS = function createWS(url) { - var _this37 = this; + var _this38 = this; var self = this; var client = self.client; @@ -1735,14 +1783,14 @@ var InternalClient = (function () { this.websocket.onclose = function (code) { self.websocket = null; self.state = _ConnectionState2["default"].DISCONNECTED; - self.disconnected(_this37.client.options.autoReconnect); + self.disconnected(_this38.client.options.autoReconnect); }; this.websocket.onerror = function (e) { client.emit("error", e); self.websocket = null; self.state = _ConnectionState2["default"].DISCONNECTED; - self.disconnected(_this37.client.options.autoReconnect); + self.disconnected(_this38.client.options.autoReconnect); }; this.websocket.onmessage = function (e) { @@ -1771,11 +1819,11 @@ var InternalClient = (function () { self.user = self.users.add(new _StructuresUser2["default"](data.user, client)); - _this37.forceFetchCount = {}; - _this37.forceFetchQueue = []; - _this37.forceFetchLength = 1; - _this37.autoReconnectInterval = 1000; - _this37.sessionID = data.session_id; + _this38.forceFetchCount = {}; + _this38.forceFetchQueue = []; + _this38.forceFetchLength = 1; + _this38.autoReconnectInterval = 1000; + _this38.sessionID = data.session_id; data.guilds.forEach(function (server) { if (!server.unavailable) { @@ -2239,7 +2287,7 @@ var InternalClient = (function () { data.id = data.id || user.id; data.avatar = data.avatar || user.avatar; data.discriminator = data.discriminator || user.discriminator; - _this37.email = data.email || _this37.email; + _this38.email = data.email || _this38.email; var presenceUser = new _StructuresUser2["default"](data, client); @@ -2297,7 +2345,7 @@ var InternalClient = (function () { } break; case _Constants.PacketType.USER_NOTE_UPDATE: - if (_this37.user.bot) { + if (_this38.user.bot) { return; } var user = self.users.get("id", data.id); @@ -2401,7 +2449,7 @@ var InternalClient = (function () { break; case _Constants.PacketType.FRIEND_ADD: - if (_this37.user.bot) { + if (_this38.user.bot) { return; } if (data.type === 1) { @@ -2432,7 +2480,7 @@ var InternalClient = (function () { } break; case _Constants.PacketType.FRIEND_REMOVE: - if (_this37.user.bot) { + if (_this38.user.bot) { return; } var user = self.friends.get("id", data.id); diff --git a/lib/Constants.js b/lib/Constants.js index 18dbbd5d2..bc2f9b89e 100644 --- a/lib/Constants.js +++ b/lib/Constants.js @@ -76,6 +76,12 @@ var Endpoints = Constants.Endpoints = { CHANNEL_MESSAGE: function CHANNEL_MESSAGE(channelID, messageID) { return Endpoints.CHANNEL_MESSAGES(channelID) + "/" + messageID; }, + CHANNEL_PINS: function CHANNEL_PINS(channelID) { + return Endpoints.CHANNEL(channelID) + "/pins"; + }, + CHANNEL_PIN: function CHANNEL_PIN(channelID, messageID) { + return Endpoints.CHANNEL_PINS(channelID) + "/" + messageID; + }, // friends FRIENDS: API + "/users/@me/relationships" diff --git a/lib/Structures/Message.js b/lib/Structures/Message.js index 16db2b847..5402baf7c 100644 --- a/lib/Structures/Message.js +++ b/lib/Structures/Message.js @@ -48,6 +48,7 @@ var Message = (function (_Equality) { this.embeds = data.embeds; this.timestamp = Date.parse(data.timestamp); this.everyoneMentioned = data.mention_everyone || data.everyoneMentioned; + this.pinned = data.pinned; this.id = data.id; if (data.edited_timestamp) { @@ -128,6 +129,14 @@ var Message = (function (_Equality) { return this.client.replyTTS.apply(this.client, _UtilArgumentRegulariser.reg(this, arguments)); }; + Message.prototype.pin = function pin() { + return this.client.pinMessage.apply(this.client, _UtilArgumentRegulariser.reg(this, arguments)); + }; + + Message.prototype.unpin = function unpin() { + return this.client.unpinMessage.apply(this.client, req(this, arguments)); + }; + _createClass(Message, [{ key: "sender", get: function get() { diff --git a/src/Client/Client.js b/src/Client/Client.js index 60b6107d6..fccc63a72 100644 --- a/src/Client/Client.js +++ b/src/Client/Client.js @@ -639,6 +639,91 @@ export default class Client extends EventEmitter { .then(dataCallback(callback), errorCallback(callback)); } + /** + * Pins a message to a channel. + * @param {MessageResolvable} message to pin. + * @returns {Promise} resolves null if successful, otherwise rejects with an error. + * @example + * // pin message - callback + * client.pinMessage(msg, (err) => { + * if(!err) { + * console.log("Successfully pinned message") + * } else { + * console.log("Couldn't pin the message: " + err); + * } + * }); + * @example + * // pin message - promise + * client.pinMessage(msg) + * .then(() => { + * console.log("Successfully pinned message"); + * }) + * .catch(err => console.log("Couldn't pin the message: " + err)); + */ + + pinMessage(msg, callback = (/*err*/) => { }) { + return this.internal.pinMessage(msg) + .then(dataCallback(callback), errorCallback(callback)); + } + + /** + * Unpins a message to a server. + * @param {MessageResolvable} message to unpin. + * @returns {Promise} resolves null if successful, otherwise rejects with an error. + * @example + * // unpin message - callback + * client.unpinMessage(msg, (err) => { + * if(!err) { + * console.log("Successfully unpinned message") + * } else { + * console.log("Couldn't pin the message: " + err); + * } + * }); + * @example + * // unpin message - promise + * client.unpinMessage(msg) + * .then(() => { + * console.log("Successfully unpinned message"); + * }) + * .catch(err => console.log("Couldn't unpin the message: " + err)); + */ + + unpinMessage(msg, callback = (/*err*/) => { }) { + return this.internal.unpinMessage(msg) + .then(dataCallback(callback), errorCallback(callback)); + } + + /** + * Gets all pinned messages of a channel. + * @param {TextChannelResolvable} where to get the pins from. + * @returns {Promise, Error>} Resolves with an array of messages if successful, otherwise rejects with an error. + * @example + * // log all pinned messages - callback + * client.getPinnedMessages(channel, (err, messages) => { + * if(!err) { + * for(var message of messages) { + * console.log(message.content); + * } + * } else { + * console.log("Couldn't fetch pins: " + err); + * } + * }); + * @example + * // log all pinned messages - promise + * client.getPinnedMessages(channel) + * .then(messages => { + * for(var message of messages) { + * console.log(message.content); + * } + * }) + * .catch(err => console.log("Couldn't fetch pins: " + err)); + */ + + getPinnedMessages(channel, callback = (/*err, messages*/) => { }) { + return this.internal.getPinnedMessages(channel) + .then(dataCallback(callback), errorCallback(callback)); + } + /** * Gets the banned users of a server (if the client has permission to) * @param {ServerResolvable} server server to get banned users of diff --git a/src/Client/InternalClient.js b/src/Client/InternalClient.js index a52fd7063..ddec40a69 100644 --- a/src/Client/InternalClient.js +++ b/src/Client/InternalClient.js @@ -776,6 +776,12 @@ export default class InternalClient { qsObject.after = res.id; } } + if (options.around) { + const res = this.resolver.resolveMessage(options.around); + if (res) { + qsObject.around = res.id + } + } return this.apiRequest( "get", @@ -813,7 +819,56 @@ export default class InternalClient { .then(res => channel.messages.add( new Message(res, channel, this.client) )); - }) + }); + } + + // def pinMessage + pinMessage(msg) { + var message = this.resolver.resolveMessage(msg); + + if(!message) { + return Promise.reject(new Error("Supplied message did not resolve to a message")); + } + + return this.apiRequest( + "put", + `${Endpoints.CHANNEL_PIN(msg.channel.id, msg.id)}`, + true + ); + } + + // def unpinMessage + unpinMessage(msg) { + var message = this.resolver.resolveMessage(msg); + + if(!message) { + return Promise.reject(new Error("Supplied message did not resolve to a message")); + } + + if(!message.pinned) { + return Promise.reject(new Error("Supplied message is not pinned")); + } + + return this.apiRequest( + "del", + `${Endpoints.CHANNEL_PIN(msg.channel.id, msg.id)}`, + true + ); + } + + // def getPinnedMessages + getPinnedMessages(_channel) { + return this.resolver.resolveChannel(_channel) + .then(channel => { + return this.apiRequest( + "get", + `${Endpoints.CHANNEL_PINS(channel.id)}`, + true + ) + .then(res => res.map( + msg => channel.messages.add(new Message(msg, channel, this.client)) + )); + }); } // def getBans diff --git a/src/Constants.js b/src/Constants.js index acebc7e93..85feabf2e 100644 --- a/src/Constants.js +++ b/src/Constants.js @@ -37,6 +37,8 @@ const Endpoints = Constants.Endpoints = { CHANNEL_TYPING: (channelID) => `${Endpoints.CHANNEL(channelID) }/typing`, CHANNEL_PERMISSIONS: (channelID) => `${Endpoints.CHANNEL(channelID) }/permissions`, CHANNEL_MESSAGE: (channelID, messageID) => `${Endpoints.CHANNEL_MESSAGES(channelID)}/${messageID}`, + CHANNEL_PINS: (channelID) => `${Endpoints.CHANNEL(channelID) }/pins`, + CHANNEL_PIN: (channelID, messageID) => `${Endpoints.CHANNEL_PINS(channelID) }/${messageID}`, // friends FRIENDS: `${API}/users/@me/relationships` diff --git a/src/Structures/Message.js b/src/Structures/Message.js index 1d82d70df..b91416768 100644 --- a/src/Structures/Message.js +++ b/src/Structures/Message.js @@ -23,6 +23,7 @@ export default class Message extends Equality{ this.embeds = data.embeds; this.timestamp = Date.parse(data.timestamp); this.everyoneMentioned = data.mention_everyone || data.everyoneMentioned; + this.pinned = data.pinned; this.id = data.id; if(data.edited_timestamp) { @@ -93,4 +94,12 @@ export default class Message extends Equality{ replyTTS(){ return this.client.replyTTS.apply(this.client, reg(this, arguments)); } + + pin() { + return this.client.pinMessage.apply(this.client, reg(this, arguments)); + } + + unpin() { + return this.client.unpinMessage.apply(this.client, req(this, arguments)); + } }