From 4c9d8d6cd778ce02e1e817c91d1056f817f33e24 Mon Sep 17 00:00:00 2001 From: Gus Caplan Date: Wed, 22 Feb 2017 14:33:20 -0600 Subject: [PATCH] add lots of group dm features (#1208) * group dm stuff * minor doc changes --- src/client/rest/RESTMethods.js | 18 ++++++++++++++++++ src/structures/ClientUser.js | 23 +++++++++++++++++++++++ src/structures/GroupDMChannel.js | 32 ++++++++++++++++++++++++++++++++ src/util/Constants.js | 3 +++ 4 files changed, 76 insertions(+) diff --git a/src/client/rest/RESTMethods.js b/src/client/rest/RESTMethods.js index 21d83242d..d41412a69 100644 --- a/src/client/rest/RESTMethods.js +++ b/src/client/rest/RESTMethods.js @@ -14,6 +14,7 @@ const Webhook = require('../../structures/Webhook'); const UserProfile = require('../../structures/UserProfile'); const OAuth2Application = require('../../structures/OAuth2Application'); const Channel = require('../../structures/Channel'); +const GroupDMChannel = require('../../structures/GroupDMChannel'); const Guild = require('../../structures/Guild'); const VoiceRegion = require('../../structures/VoiceRegion'); @@ -246,6 +247,23 @@ class RESTMethods { }).then(data => this.client.actions.ChannelCreate.handle(data).channel); } + createGroupDM(options) { + const data = this.client.user.bot ? + { access_tokens: options.accessTokens, nicks: options.nicks } : + { recipients: options.recipients }; + + return this.rest.makeRequest('post', Constants.Endpoints.meChannels, true, data) + .then(res => new GroupDMChannel(this.client, res)); + } + + addUserToGroupDM(channel, options) { + const data = this.client.user.bot ? + { nick: options.nick, access_token: options.accessToken } : + { recipient: options.id }; + return this.rest.makeRequest('put', Constants.Endpoints.dmChannelRecipient(channel.id, options.id), true, data) + .then(() => channel); + } + getExistingDM(recipient) { return this.client.channels.find(channel => channel.recipient && channel.recipient.id === recipient.id diff --git a/src/structures/ClientUser.js b/src/structures/ClientUser.js index 98efc4d5c..7a6afaa25 100644 --- a/src/structures/ClientUser.js +++ b/src/structures/ClientUser.js @@ -301,6 +301,29 @@ class ClientUser extends User { } } + /** + * An object containing either a user or access token, and an optional nickname + * @typedef {Object} GroupDMRecipientOptions + * @property {UserResolvable|Snowflake} [user] User to add to the group dm + * (only available if a user is creating the dm) + * @property {string} [accessToken] Access token to use to add a user to the group dm + * (only available if a bot is creating the dm) + * @property {string} [nick] Permanent nickname (only available if a bot is creating the dm) + */ + + /** + * Create a group dm + * @param {GroupDMRecipientOptions[]} recipients The recipients + * @returns {Promise} + */ + createGroupDM(recipients) { + return this.client.rest.methods.createGroupDM({ + recipients: recipients.map(u => this.client.resolver.resolveUserID(u.user)), + accessTokens: recipients.map(u => u.accessToken), + nicks: recipients.map(u => u.nick), + }); + } + /** * @param {Invite|string} invite Invite or code to accept * @returns {Promise} Joined guild diff --git a/src/structures/GroupDMChannel.js b/src/structures/GroupDMChannel.js index cf6739fd3..ef5767db7 100644 --- a/src/structures/GroupDMChannel.js +++ b/src/structures/GroupDMChannel.js @@ -58,6 +58,24 @@ class GroupDMChannel extends Channel { */ this.ownerID = data.owner_id; + /** + * If the dm is managed by an application + * @type {boolean} + */ + this.managed = data.managed; + + /** + * Application ID of the application that made this group dm, if applicable + * @type {?string} + */ + this.applicationID = data.application_id; + + /** + * Nicknames for group members + * @type {?Collection} + */ + if (data.nicks) this.nicks = new Collection(data.nicks.map(n => [n.id, n.nick])); + if (!this.recipients) { /** * A collection of the recipients of this DM, mapped by their ID. @@ -106,6 +124,20 @@ class GroupDMChannel extends Channel { return equal; } + /** + * Add a user to the dm + * @param {UserResolvable|String} accessTokenOrID Access token or user resolvable + * @param {string} [nick] Permanent nickname to give the user (only available if a bot is creating the dm) + */ + + addUser(accessTokenOrID, nick) { + return this.client.rest.methods.addUserToGroupDM(this, { + nick, + id: this.client.resolver.resolveUserID(accessTokenOrID), + accessToken: accessTokenOrID, + }); + } + /** * When concatenated with a string, this automatically concatenates the channel's name instead of the Channel object. * @returns {string} diff --git a/src/util/Constants.js b/src/util/Constants.js index 873b881b8..d0078d08c 100644 --- a/src/util/Constants.js +++ b/src/util/Constants.js @@ -103,6 +103,7 @@ const Endpoints = exports.Endpoints = { }, me: `${API}/users/@me`, meGuild: (guildID) => `${Endpoints.me}/guilds/${guildID}`, + meChannels: `${API}/users/@me/channels`, meMentions: (limit, roles, everyone, guildID) => `users/@me/mentions?limit=${limit}&roles=${roles}&everyone=${everyone}${guildID ? `&guild_id=${guildID}` : ''}`, relationships: (userID) => `${Endpoints.user(userID)}/relationships`, @@ -143,6 +144,8 @@ const Endpoints = exports.Endpoints = { channelWebhooks: (channelID) => `${Endpoints.channel(channelID)}/webhooks`, channelSearch: (channelID) => `${Endpoints.channelMessages(channelID)}/search`, + dmChannelRecipient: (channelID, recipientID) => `${Endpoints.channel(channelID)}/recipients/${recipientID}`, + // message reactions messageReactions: (channelID, messageID) => `${Endpoints.channelMessage(channelID, messageID)}/reactions`, messageReaction: