chore(release): v2.3.75

- fix: VoiceStateUpdate event not working (DM channels + Group DM channels)
- docs: add sendSlash method
- feat: Add new Event: callCreate, callUpdate, callDelete
- fix(GroupDM): method require Class
This commit is contained in:
March 7th
2022-07-15 17:26:25 +07:00
parent fb6ab3f8e8
commit fad6d708b4
17 changed files with 826 additions and 780 deletions

View File

@@ -177,6 +177,7 @@ class BaseGuildTextChannel extends GuildChannel {
createWebhook() {}
setRateLimitPerUser() {}
setNSFW() {}
sendSlash() {}
}
TextBasedChannel.applyToClass(BaseGuildTextChannel, true);

View File

@@ -95,6 +95,7 @@ class DMChannel extends Channel {
awaitMessages() {}
createMessageComponentCollector() {}
awaitMessageComponent() {}
sendSlash() {}
// Doesn't work on DM channels; bulkDelete() {}
// Doesn't work on DM channels; setRateLimitPerUser() {}
// Doesn't work on DM channels; setNSFW() {}
@@ -102,7 +103,7 @@ class DMChannel extends Channel {
// URL: https://discord.com/api/v9/channels/DMchannelId/call/ring
/**
* Call this DMChannel. Return discordjs/voice VoiceConnection
* @param {Object} options Options for the call (selfDeaf, selfMute: Boolean)
* @param {CallOptions} options Options for the call
* @returns {Promise<VoiceConnection>}
*/
call(options = {}) {

View File

@@ -4,7 +4,6 @@ const { Collection } = require('@discordjs/collection');
const { joinVoiceChannel, entersState, VoiceConnectionStatus } = require('@discordjs/voice');
const { Channel } = require('./Channel');
const Invite = require('./Invite');
const User = require('./User');
const TextBasedChannel = require('./interfaces/TextBasedChannel');
const { Error } = require('../errors');
const MessageManager = require('../managers/MessageManager');
@@ -128,41 +127,67 @@ class PartialGroupDMChannel extends Channel {
return this.icon && this.client.rest.cdn.GDMIcon(this.id, this.icon, format, size);
}
/**
* Adds a user to this Group DM Channel.
* @param {UserResolvable} user User to add to the group
* @returns {Promise<PartialGroupDMChannel>}
*/
async addMember(user) {
if (this.ownerId !== this.client.user.id) {
return Promise.reject(new Error('NOT_OWNER_GROUP_DM_CHANNEL'));
}
if (!(user instanceof User)) {
return Promise.reject(new TypeError('User is not an instance of Discord.User'));
user = this.client.users.resolveId(user);
if (!user) {
return Promise.reject(new TypeError('User is not a User or User ID'));
}
if (this.recipients.get(user.id)) return Promise.reject(new Error('USER_ALREADY_IN_GROUP_DM_CHANNEL'));
if (this.recipients.get(user)) return Promise.reject(new Error('USER_ALREADY_IN_GROUP_DM_CHANNEL'));
//
await this.client.api.channels[this.id].recipients[user.id].put();
this.recipients.set(user.id, user);
await this.client.api.channels[this.id].recipients[user].put();
this.recipients.set(user, this.client.users.cache.get(user));
return this;
}
/**
* Removes a user from this Group DM Channel.
* @param {UserResolvable} user User to remove from the group
* @returns {Promise<PartialGroupDMChannel>}
*/
async removeMember(user) {
if (this.ownerId !== this.client.user.id) {
return Promise.reject(new Error('NOT_OWNER_GROUP_DM_CHANNEL'));
}
if (!(user instanceof User)) {
return Promise.reject(new TypeError('User is not an instance of Discord.User'));
user = this.client.users.resolveId(user);
if (!user) {
return Promise.reject(new TypeError('User is not a User or User ID'));
}
if (!this.recipients.get(user.id)) return Promise.reject(new Error('USER_NOT_IN_GROUP_DM_CHANNEL'));
await this.client.api.channels[this.id].recipients[user.id].delete();
this.recipients.delete(user.id);
if (!this.recipients.get(user)) return Promise.reject(new Error('USER_NOT_IN_GROUP_DM_CHANNEL'));
await this.client.api.channels[this.id].recipients[user].delete();
this.recipients.delete(user);
return this;
}
/**
* Renames this Group DM Channel.
* @param {?string} name Name of the channel
* @returns {Promise<PartialGroupDMChannel>}
*/
setName(name) {
return this.edit({ name });
}
/**
* Sets the icon of this Group DM Channel.
* @param {?(Base64Resolvable|BufferResolvable)} icon Icon of the channel
* @returns {Promise<PartialGroupDMChannel>}
*/
setIcon(icon) {
return this.edit({ icon });
}
/**
* 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: {
@@ -174,6 +199,11 @@ class PartialGroupDMChannel extends Channel {
return invite;
}
/**
* Get all the invites for this Group DM Channel.
* @param {boolean} force Using API to fetch invites or cache
* @returns {Promise<Collection<string, Invite>>}
*/
async fetchInvite(force = false) {
if (this.ownerId !== this.client.user.id) {
return Promise.reject(new Error('NOT_OWNER_GROUP_DM_CHANNEL'));
@@ -184,6 +214,11 @@ class PartialGroupDMChannel extends Channel {
return this.invites;
}
/**
* Delete invites from this Group DM Channel.
* @param {Invite} invite Invite to add to the channel
* @returns {Promise<PartialGroupDMChannel>}
*/
async removeInvite(invite) {
if (this.ownerId !== this.client.user.id) {
return Promise.reject(new Error('NOT_OWNER_GROUP_DM_CHANNEL'));
@@ -203,11 +238,16 @@ class PartialGroupDMChannel extends Channel {
send() {}
sendTyping() {}
/**
* @typedef {Object} CallOptions
* @property {boolean} [selfDeaf] Whether to deafen yourself
* @property {boolean} [selfMute] Whether to mute yourself
*/
// Testing feature: Call
// URL: https://discord.com/api/v9/channels/DMchannelId/call/ring
/**
* Call this Group DMChannel. Return discordjs/voice VoiceConnection
* @param {Object} options Options for the call (selfDeaf, selfMute: Boolean)
* @param {CallOptions} options Options for the call
* @returns {Promise<VoiceConnection>}
*/
call(options = {}) {

View File

@@ -3,6 +3,7 @@
const { default: Collection } = require('@discordjs/collection');
const Base = require('./Base');
const ClientApplication = require('./ClientApplication');
const VoiceState = require('./VoiceState');
const TextBasedChannel = require('./interfaces/TextBasedChannel');
const { Error } = require('../errors');
const { RelationshipTypes } = require('../util/Constants');
@@ -189,6 +190,15 @@ class User extends Base {
return this.client.user.notes.get(this.id);
}
/**
* The voice state of this member
* @type {VoiceState}
* @readonly
*/
get voice() {
return this.client.voiceStates.cache.get(this.id) ?? new VoiceState({ client: this.client }, { user_id: this.id });
}
_ProfilePatch(data) {
if (!data) return;
@@ -351,6 +361,26 @@ class User extends Base {
return this.client.rest.cdn.Banner(this.id, this.banner, format, size, dynamic);
}
ring() {
if (!this.dmChannel?.id) return Promise.reject(new Error('USER_NO_DM_CHANNEL'));
if (!this.client.user.voice?.channelId || !this.client.callVoice) {
return Promise.reject(new Error('CLIENT_NO_CALL'));
}
return new Promise((resolve, reject) => {
this.client.api
.channels(this.dmChannel.id)
.call.ring.post({
data: {
recipients: [this.id],
},
})
.then(() => resolve(true))
.catch(e => {
reject(e);
});
});
}
/**
* The Discord "tag" (e.g. `hydrabolt#0001`) for this user
* @type {?string}

View File

@@ -396,10 +396,11 @@ class TextBasedChannel {
* Send Slash to this channel
* @param {Snowflake} botId Bot Id (Supports application ID - not bot)
* @param {string} commandName Command name
* @param {...?string} args Command arguments
* @param {...?string|string[]} args Command arguments
* @returns {Promise<Snowflake>} Nonce (Discord Timestamp) when command was sent
*/
async sendSlash(botId, commandName, ...args) {
args = args.flat(2);
if (!botId) throw new Error('Bot ID is required');
// ? maybe ...
const user = await this.client.users.fetch(botId).catch(() => {});