Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support voiceChannelEffectSend event #9308

Open
wants to merge 5 commits into
base: v13
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions src/client/actions/ActionsManager.js
Expand Up @@ -67,6 +67,7 @@ class ActionsManager {
this.register(require('./ThreadMembersUpdate'));
this.register(require('./TypingStart'));
this.register(require('./UserUpdate'));
this.register(require('./VoiceChannelEffectSend'));
this.register(require('./VoiceStateUpdate'));
this.register(require('./WebhooksUpdate'));
}
Expand Down
22 changes: 22 additions & 0 deletions src/client/actions/VoiceChannelEffectSend.js
@@ -0,0 +1,22 @@
'use strict';

const Action = require('./Action');
const VoiceChannelEffect = require('../../structures/VoiceChannelEffect');
const { Events } = require('../../util/Constants');

class VoiceChannelEffectSendAction extends Action {
handle(data) {
const client = this.client;
const guild = client.guilds.cache.get(data.guild_id);
if (!guild) return;
/**
* Emmited when someone sends an effect, such as an emoji reaction,
* in a voice channel the current user is connected to.
* @event Client#voiceChannelEffectSend
* @param {VoiceChannelEffect} voiceChannelEffect The sent voice channel effect
*/
client.emit(Events.VOICE_CHANNEL_EFFECT_SEND, new VoiceChannelEffect(data, guild));
}
}

module.exports = VoiceChannelEffectSendAction;
5 changes: 5 additions & 0 deletions src/client/websocket/handlers/VOICE_CHANNEL_EFFECT_SEND.js
@@ -0,0 +1,5 @@
'use strict';

module.exports = (client, packet) => {
client.actions.VoiceChannelEffectSend.handle(packet.d);
};
1 change: 1 addition & 0 deletions src/client/websocket/handlers/index.js
Expand Up @@ -49,6 +49,7 @@ const handlers = Object.fromEntries([
['USER_UPDATE', require('./USER_UPDATE')],
['PRESENCE_UPDATE', require('./PRESENCE_UPDATE')],
['TYPING_START', require('./TYPING_START')],
['VOICE_CHANNEL_EFFECT_SEND', require('./VOICE_CHANNEL_EFFECT_SEND')],
['VOICE_STATE_UPDATE', require('./VOICE_STATE_UPDATE')],
['VOICE_SERVER_UPDATE', require('./VOICE_SERVER_UPDATE')],
['WEBHOOKS_UPDATE', require('./WEBHOOKS_UPDATE')],
Expand Down
1 change: 1 addition & 0 deletions src/index.js
Expand Up @@ -155,6 +155,7 @@ exports.Typing = require('./structures/Typing');
exports.User = require('./structures/User');
exports.UserContextMenuInteraction = require('./structures/UserContextMenuInteraction');
exports.VoiceChannel = require('./structures/VoiceChannel');
exports.VoiceChannelEffect = require('./structures/VoiceChannelEffect');
exports.VoiceRegion = require('./structures/VoiceRegion');
exports.VoiceState = require('./structures/VoiceState');
exports.Webhook = require('./structures/Webhook');
Expand Down
67 changes: 67 additions & 0 deletions src/structures/VoiceChannelEffect.js
@@ -0,0 +1,67 @@
'use strict';

const { Emoji } = require('./Emoji');
const { AnimationTypes } = require('../util/Constants');

/**
* Represents an effect used in a {@link VoiceChannel}.
*/
class VoiceChannelEffect {
constructor(data, guild) {
/**
* The guild where the effect was sent from.
* @type {Guild}
*/
this.guild = guild;

/**
* The id of the channel the effect was sent in.
* @type {Snowflake}
*/
this.channelId = data.channel_id;

/**
* The id of the user that sent the effect.
* @type {Snowflake}
*/
this.userId = data.user_id;

/**
* The emoji of the effect.
* @type {?Emoji}
*/
this.emoji = data.emoji ? new Emoji(guild.client, data.emoji) : null;

/**
* The animation type of the effect.
* @type {?AnimationType}
*/
this.animationType = data.animation_type ? AnimationTypes[data.animation_type] : null;

/**
* The animation id of the effect.
* @type {?number}
*/
this.animationId = data.animation_id ?? null;
}

/**
* The channel the effect was sent in.
* @type {?VoiceChannel}
* @readonly
*/
get channel() {
return this.guild.channels.cache.get(this.channelId) ?? null;
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

User getter See 9228 (comment)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just realized this doesn't extend Base, would that be possible?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just realized this doesn't extend Base, would that be possible?

Idk structure was copied from jiralite pr lol

Copy link
Contributor Author

@jaw0r3k jaw0r3k Apr 1, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

About user getter i wasnt sure
its a guild object so like e.g. voice state it doesnt have user

/**
* The member that sent the effect.
* @type {?GuildMember}
* @readonly
*/
get member() {
return this.guild.members.cache.get(this.userId) ?? null;
}
}

module.exports = VoiceChannelEffect;
14 changes: 14 additions & 0 deletions src/util/Constants.js
Expand Up @@ -221,6 +221,7 @@
* * THREAD_MEMBERS_UPDATE: threadMembersUpdate
* * USER_UPDATE: userUpdate
* * PRESENCE_UPDATE: presenceUpdate
* * VOICE_CHANNEL_EFFECT_SEND: voiceChannelEffectSend
* * VOICE_SERVER_UPDATE: voiceServerUpdate
* * VOICE_STATE_UPDATE: voiceStateUpdate
* * TYPING_START: typingStart
Expand Down Expand Up @@ -305,6 +306,7 @@
THREAD_MEMBERS_UPDATE: 'threadMembersUpdate',
USER_UPDATE: 'userUpdate',
PRESENCE_UPDATE: 'presenceUpdate',
VOICE_CHANNEL_EFFECT_SEND: 'voiceChannelEffectSend',
VOICE_SERVER_UPDATE: 'voiceServerUpdate',
VOICE_STATE_UPDATE: 'voiceStateUpdate',
TYPING_START: 'typingStart',
Expand Down Expand Up @@ -417,6 +419,7 @@
* * USER_UPDATE
* * PRESENCE_UPDATE
* * TYPING_START
* * VOICE_CHANNEL_EFFECT_SEND
* * VOICE_STATE_UPDATE
* * VOICE_SERVER_UPDATE
* * WEBHOOKS_UPDATE
Expand Down Expand Up @@ -482,6 +485,7 @@
'USER_UPDATE',
'PRESENCE_UPDATE',
'TYPING_START',
'VOICE_CHANNEL_EFFECT_SEND',
'VOICE_STATE_UPDATE',
'VOICE_SERVER_UPDATE',
'WEBHOOKS_UPDATE',
Expand Down Expand Up @@ -533,7 +537,7 @@
'role_connections.write',
];

// TODO: change Integration#expireBehavior to this and clean up Integration

Check warning on line 540 in src/util/Constants.js

View workflow job for this annotation

GitHub Actions / ESLint

Unexpected 'todo' comment: 'TODO: change Integration#expireBehavior...'
/**
* The behavior of expiring subscribers for Integrations. This can be:
* * REMOVE_ROLE
Expand Down Expand Up @@ -1510,6 +1514,15 @@
*/
exports.ForumLayoutTypes = createEnum(['NOT_SET', 'LIST_VIEW', 'GALLERY_VIEW']);

/**
* The animation type of the voice channel effect
* * PREMIUM
* * BASIC
* @typedef {string} AnimationType
* @see {@link https://discord.com/developers/docs/topics/gateway-events#voice-channel-effect-send-animation-types}
*/
exports.AnimationTypes = createEnum(['PREMIUM', 'BASIC']);

exports._cleanupSymbol = Symbol('djsCleanup');

function keyMirror(arr) {
Expand All @@ -1531,6 +1544,7 @@
/**
* @typedef {Object} Constants Constants that can be used in an enum or object-like way.
* @property {Object<ActivityType, number>} ActivityTypes The type of an activity of a users presence.
* @property {Object<AnimationType, number>} AnimationTypes The animation type of the voice channel effect.
* @property {Object<APIError, number>} APIErrors An error encountered while performing an API request.
* @property {Object<ApplicationCommandOptionType, number>} ApplicationCommandOptionTypes
* The type of an {@link ApplicationCommandOption} object.
Expand Down
5 changes: 5 additions & 0 deletions typings/enums.d.ts
Expand Up @@ -10,6 +10,11 @@ export const enum ActivityTypes {
COMPETING = 5,
}

export const enum AnimationTypes {
PREMIUM = 0,
BASIC = 1,
}

export const enum ApplicationCommandTypes {
CHAT_INPUT = 1,
USER = 2,
Expand Down
18 changes: 18 additions & 0 deletions typings/index.d.ts
Expand Up @@ -97,6 +97,7 @@ import {
SortOrderType,
ForumLayoutType,
ApplicationRoleConnectionMetadataTypes,
AnimationTypes,
} from './enums';
import {
APIApplicationRoleConnectionMetadata,
Expand Down Expand Up @@ -160,6 +161,7 @@ import {
RawWelcomeScreenData,
RawWidgetData,
RawWidgetMemberData,
VoiceChannelEffectData,
} from './rawDataTypes';

//#region Classes
Expand Down Expand Up @@ -2809,6 +2811,18 @@ export class VoiceChannel extends TextBasedChannelMixin(BaseGuildVoiceChannel, [
public setVideoQualityMode(videoQualityMode: VideoQualityMode | number, reason?: string): Promise<VoiceChannel>;
}

export class VoiceChannelEffect {
private constructor(data: VoiceChannelEffectData, guild: Guild);
public animationType: AnimationTypes | null;
public animationId: number | null;
public readonly channel: VoiceChannel | null;
public channelId: Snowflake;
public emoji: Emoji | null;
public guild: Guild;
public readonly member: GuildMember | null;
public userId: Snowflake;
}

export class VoiceRegion {
private constructor(data: RawVoiceRegionData);
public custom: boolean;
Expand Down Expand Up @@ -3154,6 +3168,7 @@ export const Constants: {
DefaultMessageNotificationLevels: EnumHolder<typeof DefaultMessageNotificationLevels>;
VerificationLevels: EnumHolder<typeof VerificationLevels>;
MembershipStates: EnumHolder<typeof MembershipStates>;
AnimationTypes: EnumHolder<typeof AnimationTypes>;
AutoModerationRuleTriggerTypes: EnumHolder<typeof AutoModerationRuleTriggerTypes>;
AutoModerationRuleKeywordPresetTypes: EnumHolder<typeof AutoModerationRuleKeywordPresetTypes>;
AutoModerationActionTypes: EnumHolder<typeof AutoModerationActionTypes>;
Expand Down Expand Up @@ -4569,6 +4584,7 @@ export interface ClientEvents extends BaseClientEvents {
threadUpdate: [oldThread: ThreadChannel, newThread: ThreadChannel];
typingStart: [typing: Typing];
userUpdate: [oldUser: User | PartialUser, newUser: User];
voiceChannelEffectSend: [voiceChannelEffect: VoiceChannelEffect];
voiceStateUpdate: [oldState: VoiceState, newState: VoiceState];
webhookUpdate: [channel: TextChannel | NewsChannel | VoiceChannel | ForumChannel];
/** @deprecated Use interactionCreate instead */
Expand Down Expand Up @@ -4827,6 +4843,7 @@ export interface ConstantsEvents {
THREAD_MEMBERS_UPDATE: 'threadMembersUpdate';
USER_UPDATE: 'userUpdate';
PRESENCE_UPDATE: 'presenceUpdate';
VOICE_CHANNEL_EFFECT_SEND: 'voiceChaannelEffectSend';
VOICE_SERVER_UPDATE: 'voiceServerUpdate';
VOICE_STATE_UPDATE: 'voiceStateUpdate';
TYPING_START: 'typingStart';
Expand Down Expand Up @@ -6546,6 +6563,7 @@ export type WSEventType =
| 'USER_UPDATE'
| 'PRESENCE_UPDATE'
| 'TYPING_START'
| 'VOICE_CHANNEL_EFFECT_SEND'
| 'VOICE_STATE_UPDATE'
| 'VOICE_SERVER_UPDATE'
| 'WEBHOOKS_UPDATE'
Expand Down
12 changes: 11 additions & 1 deletion typings/rawDataTypes.d.ts
Expand Up @@ -90,7 +90,8 @@ import type {
AutoModerationRuleTriggerTypes,
InteractionTypes,
MessageComponentTypes,
ApplicationRoleConnectionMetadataTypes
ApplicationRoleConnectionMetadataTypes,
AnimationTypes
} from './enums';

export type RawActivityData = GatewayActivity;
Expand Down Expand Up @@ -279,3 +280,12 @@ export interface APIApplicationRoleConnectionMetadata {
description: string;
description_localizations?: LocalizationMap;
}

export interface VoiceChannelEffectData {
channel_id: Snowflake;
guild_id: Snowflake;
user_id: Snowflake;
emoji?: APIEmoji | null;
animation_type?: AnimationTypes;
animation_id?: number;
}