Skip to content

Commit

Permalink
feat(VoiceChannel): Support voice channel statuses (#1496)
Browse files Browse the repository at this point in the history
  • Loading branch information
conorwastakenwastaken authored Jul 20, 2024
1 parent bcf7dee commit a1a449f
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 7 deletions.
18 changes: 15 additions & 3 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -978,6 +978,7 @@ declare namespace Eris {
userUpdate: [user: User, oldUser: PartialUser | null];
voiceChannelJoin: [member: Member, channel: AnyVoiceChannel];
voiceChannelLeave: [member: Member, channel: AnyVoiceChannel];
voiceChannelStatusUpdate: [channel: AnyVoiceChannel, oldChannel: VoiceStatus];
voiceChannelSwitch: [member: Member, newChannel: AnyVoiceChannel, oldChannel: AnyVoiceChannel];
voiceStateUpdate: [member: Member, oldState: OldVoiceState];
warn: [message: string, id?: number];
Expand Down Expand Up @@ -1840,6 +1841,9 @@ declare namespace Eris {
requestToSpeakTimestamp?: Date | null;
suppress?: boolean;
}
interface VoiceStatus {
status: string;
}
interface VoiceStreamCurrent {
buffer: Buffer | null;
bufferingTicks: number;
Expand Down Expand Up @@ -2010,6 +2014,9 @@ declare namespace Eris {
AUTO_MODERATION_RULE_UPDATE: 141;
AUTO_MODERATION_RULE_DELETE: 142;
AUTO_MODERATION_BLOCK_MESSAGE: 143;

VOICE_CHANNEL_STATUS_UPDATE: 192;
VOICE_CHANNEL_STATUS_DELETE: 193;
};
AutoModerationActionTypes: {
BLOCK_MESSAGE: 1;
Expand Down Expand Up @@ -2441,10 +2448,11 @@ declare namespace Eris {
createEvents: 17592186044416n;
useExternalSounds: 35184372088832n;
sendVoiceMessages: 70368744177664n;
allGuild: 29697484783806n;
setVoiceChannelStatus: 281474976710656n;
allGuild: 311172461494462n;
allText: 70904273435729n;
allVoice: 110505548056337n;
all: 140737488355327n;
allVoice: 391980524766993n;
all: 422212465065983n;
};
PremiumTiers: {
NONE: 0;
Expand Down Expand Up @@ -3119,6 +3127,7 @@ declare namespace Eris {
searchGuildMembers(guildID: string, query: string, limit?: number): Promise<Member[]>;
searchGuildMessages(guildID: string, query: SearchOptions): Promise<SearchResults>;
sendChannelTyping(channelID: string): Promise<void>;
setVoiceChannelStatus(channelID: string, status: string, reason?: string): Promise<void>;
syncGuildIntegration(guildID: string, integrationID: string): Promise<void>;
syncGuildTemplate(guildID: string, code: string): Promise<GuildTemplate>;
unbanGuildMember(guildID: string, userID: string, reason?: string): Promise<void>;
Expand Down Expand Up @@ -3471,6 +3480,7 @@ declare namespace Eris {
message?: Message<AnyGuildTextableChannel> | Uncached;
reason: string | null;
role?: Role | { id: string; name: string };
status?: string;
target?: Guild | AnyGuildChannel | Member | Role | Invite | Emoji | Sticker | Message<AnyGuildTextableChannel> | null;
targetID: string;
user: User | Uncached;
Expand Down Expand Up @@ -4254,6 +4264,7 @@ declare namespace Eris {
permissionOverwrites: Collection<PermissionOverwrite>;
position: number;
rtcRegion: string | null;
status?: string;
type: GuildVoiceChannelTypes;
userLimit: number;
videoQualityMode: VideoQualityMode;
Expand All @@ -4265,6 +4276,7 @@ declare namespace Eris {
getInvites(): Promise<Invite<"withMetadata", this>[]>;
join(options?: JoinVoiceChannelOptions): Promise<VoiceConnection>;
leave(): void;
setStatus(status: string, reason?: string): Promise<void>;
}

export class VoiceConnection extends EventEmitter implements SimpleJSON {
Expand Down
14 changes: 14 additions & 0 deletions lib/Client.js
Original file line number Diff line number Diff line change
Expand Up @@ -3996,6 +3996,20 @@ class Client extends EventEmitter {
return this.requestHandler.request("POST", Endpoints.CHANNEL_TYPING(channelID), true);
}

/**
* Set the status of a voice channel. Note: This will not work in stage channels
* @arg {String} channelID The ID of the channel
* @arg {String} status The new voice channel status
* @arg {String} [reason] The reason to be displayed in audit logs
* @returns {Promise}
*/
setVoiceChannelStatus(channelID, status, reason) {
return this.requestHandler.request("PUT", Endpoints.CHANNEL_VOICE_STATUS(channelID), true, {
status,
reason
});
}

/**
* Force a guild integration to sync
* @arg {String} guildID The ID of the guild
Expand Down
12 changes: 9 additions & 3 deletions lib/Constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,10 @@ module.exports.AuditLogActions = {
ROLE_PROMPT_DELETE: 162,

GUILD_HOME_FEATURE_ITEM: 171,
GUILD_HOME_REMOVE_ITEM: 172
GUILD_HOME_REMOVE_ITEM: 172,

VOICE_CHANNEL_STATUS_UPDATE: 192,
VOICE_CHANNEL_STATUS_DELETE: 193
};

module.exports.AutoModerationActionTypes = {
Expand Down Expand Up @@ -576,7 +579,9 @@ const Permissions = {
createGuildExpressions: 1n << 43n,
createEvents: 1n << 44n,
useExternalSounds: 1n << 45n,
sendVoiceMessages: 1n << 46n
sendVoiceMessages: 1n << 46n,

setVoiceChannelStatus: 1n << 48n
};
Permissions.allGuild = Permissions.kickMembers
| Permissions.banMembers
Expand Down Expand Up @@ -632,7 +637,8 @@ Permissions.allVoice = Permissions.createInstantInvite
| Permissions.useEmbeddedActivities
| Permissions.useSoundboard
| Permissions.useExternalSounds
| Permissions.sendVoiceMessages;
| Permissions.sendVoiceMessages
| Permissions.setVoiceChannelStatus;
Permissions.all = Permissions.allGuild | Permissions.allText | Permissions.allVoice;
module.exports.Permissions = Permissions;

Expand Down
21 changes: 21 additions & 0 deletions lib/gateway/Shard.js
Original file line number Diff line number Diff line change
Expand Up @@ -972,6 +972,27 @@ class Shard extends EventEmitter {
}
break;
}
case "VOICE_CHANNEL_STATUS_UPDATE": {
const channel = this.client.getChannel(packet.d.id);
if(!channel) {
break;
}
const oldChannel = {
status: channel.status
};
channel.update({
status: packet.d.status
});
/**
* Fired when a voice channel status is updated
* @event Client#voiceChannelStatusUpdate
* @prop {VoiceChannel} channel The updated voice channel
* @prop {Object} oldChannel The old channel data
* @prop {String?} oldChannel.status The old voice channel status
*/
this.emit("voiceChannelStatusUpdate", channel, oldChannel);
break;
}
case "TYPING_START": {
let member = null;
const guild = this.client.guilds.get(packet.d.guild_id);
Expand Down
1 change: 1 addition & 0 deletions lib/rest/Endpoints.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion lib/structures/GuildAuditLogEntry.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ const {AuditLogActions} = require("../Constants");
* @prop {(Message | Object)?} message The message that was (un)pinned, action types 74/75 (MESSAGE_PIN/UNPIN) only. If the channel or message is not cached, this will be an object with an `id` key. No other property is guaranteed.
* @prop {String?} reason The reason for the action
* @prop {(Role | Object)?} role The role described by the permission overwrite, action types 13-15 (CHANNEL\_OVERWRITE\_CREATE/UPDATE/DELETE) only. If the guild or role is not cached, this could be {id: String, name: String}
* @prop {String?} status The new voice channel status, action type 192 (VOICE\_CHANNEL\_STATUS\_UPDATE) only
* @prop {(CategoryChannel | Guild | Member | Invite | Role | Object | TextChannel | VoiceChannel | NewsChannel)?} target The object of the action target
* If the item or the item's guild (where relevant, not including invites) is not cached, this property will be null
* If the action targets a guild, this could be a Guild object
Expand Down Expand Up @@ -104,14 +105,17 @@ class GuildAuditLogEntry extends Base {
}
}
}
if(data.options.status) {
this.status = data.options.status;
}
}
}

get target() { // pay more, get less
const guildAvailable = this.guild instanceof Guild;
if(this.actionType < 10) { // Guild
return this.guild;
} else if(this.actionType < 20) { // Channel
} else if(this.actionType < 20 || this.actionType === 192 || this.actionType === 193) { // Channel
return this._client.getChannel(this.targetID) || null;
} else if(this.actionType < 30) { // Member
if(this.actionType === AuditLogActions.MEMBER_MOVE || this.actionType === AuditLogActions.MEMBER_DISCONNECT) { // MEMBER_MOVE / MEMBER_DISCONNECT
Expand Down
15 changes: 15 additions & 0 deletions lib/structures/VoiceChannel.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const PermissionOverwrite = require("./PermissionOverwrite");
* @prop {Collection<PermissionOverwrite>} permissionOverwrites Collection of PermissionOverwrites in the channel
* @prop {Number} position The position of the channel
* @prop {String?} rtcRegion The RTC region ID of the channel (automatic when `null`)
* @prop {String?} status The voice channel status
* @prop {Number?} userLimit The max number of users that can join the channel
* @prop {Number?} videoQualityMode The camera video quality mode of the voice channel. `1` is auto, `2` is 720p
* @prop {Collection<Member>} voiceMembers Collection of Members in this channel
Expand Down Expand Up @@ -50,6 +51,9 @@ class VoiceChannel extends GuildTextableChannel {
if(data.video_quality_mode !== undefined) {
this.videoQualityMode = data.video_quality_mode;
}
if(data.status !== undefined) {
this.status = data.status;
}
}

/**
Expand Down Expand Up @@ -117,13 +121,24 @@ class VoiceChannel extends GuildTextableChannel {
return this._client.leaveVoiceChannel.call(this._client, this.id);
}

/**
* Set the status of the voice channel. Note: This will not work in stage channels
* @arg {String} status The new voice channel status
* @arg {String} [reason] The reason to be displayed in audit logs
* @returns {Promise}
*/
setStatus(status, reason) {
return this._client.setVoiceChannelStatus.call(this._client, this.id, status, reason);
}

toJSON(props = []) {
return super.toJSON([
"bitrate",
"nsfw",
"permissionOverwrites",
"position",
"rtcRegion",
"status",
"userLimit",
"videoQualityMode",
"voiceMembers",
Expand Down

0 comments on commit a1a449f

Please sign in to comment.