Create GroupDMChannel.js
This commit is contained in:
parent
9bc00229a1
commit
d05b19e89b
315
src/structures/GroupDMChannel.js
Normal file
315
src/structures/GroupDMChannel.js
Normal file
@ -0,0 +1,315 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const { Collection } = require('@discordjs/collection');
|
||||||
|
const { Channel } = require('./Channel');
|
||||||
|
const Invite = require('./Invite');
|
||||||
|
const TextBasedChannel = require('./interfaces/TextBasedChannel');
|
||||||
|
const MessageManager = require('../managers/MessageManager');
|
||||||
|
const DataResolver = require('../util/DataResolver');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a Group DM Channel on Discord.
|
||||||
|
* @extends {Channel}
|
||||||
|
* @implements {TextBasedChannel}
|
||||||
|
*/
|
||||||
|
class GroupDMChannel extends Channel {
|
||||||
|
constructor(client, data) {
|
||||||
|
super(client, data);
|
||||||
|
// Override the channel type so partials have a known type
|
||||||
|
this.type = 'GROUP_DM';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A manager of the messages belonging to this channel
|
||||||
|
* @type {MessageManager}
|
||||||
|
*/
|
||||||
|
this.messages = new MessageManager(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
_patch(data) {
|
||||||
|
super._patch(data);
|
||||||
|
|
||||||
|
if ('recipients' in data && Array.isArray(data.recipients)) {
|
||||||
|
this._recipients = data.recipients;
|
||||||
|
data.recipients.forEach(u => this.client.users._add(u));
|
||||||
|
} else {
|
||||||
|
this._recipients = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ('last_message_id' in data) {
|
||||||
|
/**
|
||||||
|
* The channel's last message id, if one was sent
|
||||||
|
* @type {?Snowflake}
|
||||||
|
*/
|
||||||
|
this.lastMessageId = data.last_message_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ('last_pin_timestamp' in data) {
|
||||||
|
/**
|
||||||
|
* The timestamp when the last pinned message was pinned, if there was one
|
||||||
|
* @type {?number}
|
||||||
|
*/
|
||||||
|
this.lastPinTimestamp = new Date(data.last_pin_timestamp).getTime();
|
||||||
|
} else {
|
||||||
|
this.lastPinTimestamp ??= null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ('owner_id' in data) {
|
||||||
|
/**
|
||||||
|
* Owner ID
|
||||||
|
* @type {Snowflake}
|
||||||
|
*/
|
||||||
|
this.ownerId = data.owner_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ('name' in data) {
|
||||||
|
/**
|
||||||
|
* The name of this Group DM Channel
|
||||||
|
* @type {?string}
|
||||||
|
*/
|
||||||
|
this.name = data.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ('icon' in data) {
|
||||||
|
/**
|
||||||
|
* The hash of the channel icon
|
||||||
|
* @type {?string}
|
||||||
|
*/
|
||||||
|
this.icon = data.icon;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The URL to this channel's icon.
|
||||||
|
* @param {StaticImageURLOptions} [options={}] Options for the Image URL
|
||||||
|
* @returns {?string}
|
||||||
|
*/
|
||||||
|
iconURL({ format, size } = {}) {
|
||||||
|
return this.icon && this.client.rest.cdn.GDMIcon(this.id, this.icon, format, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The recipients of this Group DM Channel.
|
||||||
|
* @type {Collection<Snowflake, User>}
|
||||||
|
* @readonly
|
||||||
|
*/
|
||||||
|
get recipients() {
|
||||||
|
const collect = new Collection();
|
||||||
|
this._recipients.map(recipient => collect.set(recipient.id, this.client.users.cache.get(recipient.id)));
|
||||||
|
collect.set(this.client.user.id, this.client.user);
|
||||||
|
return collect;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The owner of this Group DM Channel
|
||||||
|
* @type {?User}
|
||||||
|
* @readonly
|
||||||
|
*/
|
||||||
|
get owner() {
|
||||||
|
return this.client.users.cache.get(this.ownerId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether this DMChannel is a partial
|
||||||
|
* @type {boolean}
|
||||||
|
* @readonly
|
||||||
|
*/
|
||||||
|
get partial() {
|
||||||
|
return typeof this.lastMessageId === 'undefined';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Leave this Group DM Channel.
|
||||||
|
* @param {?boolean} slient Leave without notifying other members
|
||||||
|
* @returns {Promise<GroupDMChannel>}
|
||||||
|
* @example
|
||||||
|
* // Delete the channel
|
||||||
|
* channel.delete()
|
||||||
|
* .then(console.log)
|
||||||
|
* .catch(console.error);
|
||||||
|
*/
|
||||||
|
async delete(slient = false) {
|
||||||
|
if (typeof slient === 'boolean' && slient) {
|
||||||
|
await this.client.api.channels[this.id].delete({
|
||||||
|
query: {
|
||||||
|
silent: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
await this.client.api.channels[this.id].delete();
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When concatenated with a string, this automatically returns the recipient's mention instead of the
|
||||||
|
* GroupDMChannel object.
|
||||||
|
* @returns {string}
|
||||||
|
* @example
|
||||||
|
* // Logs: Hello from Group Test!
|
||||||
|
* console.log(`Hello from ${channel}!`);
|
||||||
|
*/
|
||||||
|
toString() {
|
||||||
|
return (
|
||||||
|
this.name ??
|
||||||
|
this._recipients
|
||||||
|
.filter(user => user.id !== this.client.user.id)
|
||||||
|
.map(user => user.username)
|
||||||
|
.join(', ')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
toJSON() {
|
||||||
|
const json = super.toJSON({
|
||||||
|
createdTimestamp: true,
|
||||||
|
});
|
||||||
|
json.iconURL = this.iconURL();
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The data for editing a channe;.
|
||||||
|
* @typedef {Object} GroupDMChannelEditData
|
||||||
|
* @property {string} [name] The name of the channel
|
||||||
|
* @property {?(BufferResolvable|Base64Resolvable)} [icon] The icon of the channel
|
||||||
|
* @property {GuildMemberResolvable} [owner] The owner of the channel
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Edit channel data
|
||||||
|
* @param {GroupDMChannelEditData} data Data
|
||||||
|
* @returns {Promise<GroupDMChannel>}
|
||||||
|
* @example
|
||||||
|
* // Set the channel name
|
||||||
|
* channel.edit({
|
||||||
|
* name: 'Group Test',
|
||||||
|
* })
|
||||||
|
* .then(updated => console.log(`New channel name ${updated}`))
|
||||||
|
* .catch(console.error);
|
||||||
|
*/
|
||||||
|
async edit(data) {
|
||||||
|
const _data = {};
|
||||||
|
if ('name' in data) _data.name = data.name?.trim() ?? null;
|
||||||
|
if (typeof data.icon !== 'undefined') {
|
||||||
|
_data.icon = await DataResolver.resolveImage(data.icon);
|
||||||
|
}
|
||||||
|
if ('owner' in data) {
|
||||||
|
_data.owner = data.owner;
|
||||||
|
}
|
||||||
|
const newData = await this.client.api.channels[this.id].patch({
|
||||||
|
data: _data,
|
||||||
|
});
|
||||||
|
|
||||||
|
return this.client.actions.ChannelUpdate.handle(newData).updated;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renames this Group DM Channel.
|
||||||
|
* @param {?string} name Name of the channel
|
||||||
|
* @returns {Promise<GroupDMChannel>}
|
||||||
|
*/
|
||||||
|
setName(name) {
|
||||||
|
return this.edit({ name });
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the icon of this Group DM Channel.
|
||||||
|
* @param {?(Base64Resolvable|BufferResolvable)} icon Icon of the channel
|
||||||
|
* @returns {Promise<GroupDMChannel>}
|
||||||
|
*/
|
||||||
|
setIcon(icon) {
|
||||||
|
return this.edit({ icon });
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Changes the owner of this Group DM Channel.
|
||||||
|
* @param {UserResolvable} user User to transfer ownership to
|
||||||
|
* @returns {Promise<GroupDMChannel>}
|
||||||
|
*/
|
||||||
|
setOwner(user) {
|
||||||
|
const id = this.client.users.resolveId(user);
|
||||||
|
if (this.ownerId === id) {
|
||||||
|
return Promise.resolve(this);
|
||||||
|
}
|
||||||
|
return this.edit({ owner: id });
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a user to this Group DM Channel.
|
||||||
|
* @param {UserResolvable} user User to add to the group
|
||||||
|
* @returns {Promise<GroupDMChannel>}
|
||||||
|
*/
|
||||||
|
async addUser(user) {
|
||||||
|
user = this.client.users.resolveId(user);
|
||||||
|
await this.client.api.channels[this.id].recipients[user].put();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes a user from this Group DM Channel.
|
||||||
|
* @param {UserResolvable} user User to remove from the group
|
||||||
|
* @returns {Promise<GroupDMChannel>}
|
||||||
|
*/
|
||||||
|
async removeUser(user) {
|
||||||
|
user = this.client.users.resolveId(user);
|
||||||
|
await this.client.api.channels[this.id].recipients[user].delete();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the invite for this Group DM Channel.
|
||||||
|
* @returns {Promise<Invite>}
|
||||||
|
*/
|
||||||
|
async getInvite() {
|
||||||
|
const inviteCode = await this.client.api.channels(this.id).invites.post({
|
||||||
|
data: {
|
||||||
|
max_age: 86400,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return new Invite(this.client, inviteCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all the invites for this Group DM Channel.
|
||||||
|
* @returns {Promise<Collection<string, Invite>>}
|
||||||
|
*/
|
||||||
|
async fetchAllInvite() {
|
||||||
|
const invites = await this.client.api.channels(this.id).invites.get();
|
||||||
|
return new Collection(invites.map(invite => [invite.code, new Invite(this.client, invite)]));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete invites from this Group DM Channel.
|
||||||
|
* @param {InviteResolvable} invite Invite to add to the channel
|
||||||
|
* @returns {Promise<GroupDMChannel>}
|
||||||
|
*/
|
||||||
|
async removeInvite(invite) {
|
||||||
|
// Resolve
|
||||||
|
let code = invite?.code;
|
||||||
|
if (!code && URL.canParse(invite)) code = new URL(invite).pathname.slice(1);
|
||||||
|
else code = invite;
|
||||||
|
await this.client.api.channels(this.id).invites[invite].delete();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// These are here only for documentation purposes - they are implemented by TextBasedChannel
|
||||||
|
/* eslint-disable no-empty-function */
|
||||||
|
get lastMessage() {}
|
||||||
|
get lastPinAt() {}
|
||||||
|
send() {}
|
||||||
|
sendTyping() {}
|
||||||
|
createMessageCollector() {}
|
||||||
|
awaitMessages() {}
|
||||||
|
createMessageComponentCollector() {}
|
||||||
|
awaitMessageComponent() {}
|
||||||
|
// Doesn't work on DM channels; setRateLimitPerUser() {}
|
||||||
|
// Doesn't work on DM channels; setNSFW() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
TextBasedChannel.applyToClass(GroupDMChannel, true, [
|
||||||
|
'fetchWebhooks',
|
||||||
|
'createWebhook',
|
||||||
|
'setRateLimitPerUser',
|
||||||
|
'setNSFW',
|
||||||
|
]);
|
||||||
|
|
||||||
|
module.exports = GroupDMChannel;
|
Loading…
Reference in New Issue
Block a user