add(helpers): connectToVoiceChannel() (#1048)

* feat(helpers): add joinVoiceChannel() helper

* Remove if-statement validating if channelId is present or not

* refactor(helpers): use snakelize()

* Rename to connectToVoiceChannel()

Co-authored-by: ITOH <to@itoh.at>

* Require VIEW_CHANNEL permission including CONNECT

Co-authored-by: ITOH <to@itoh.at>

* Change default value of third argument to {}

* Remove usage of Partial and mark options as optional

* Default selfDeaf to true by default

* .

* Add connectToVoiceChannel() to helpers module

* docs(helpers): add jsdoc block to connectToVoiceChannel()

* Use AtLeastOne type for options

* Default value for selfMute option

* Update src/helpers/voice/connect_to_voice_channel.ts

Co-authored-by: ITOH <to@itoh.at>

Co-authored-by: ITOH <to@itoh.at>
This commit is contained in:
rigormorrtiss
2021-06-16 23:02:21 +04:00
committed by GitHub
parent d5ea8904b9
commit ddf5d9f490
4 changed files with 34 additions and 0 deletions

View File

@@ -134,6 +134,7 @@ import { updateStageInstance } from "./channels/update_stage_instance.ts";
import { getStageInstance } from "./channels/get_stage_instance.ts";
import { deleteStageInstance } from "./channels/delete_stage_instance.ts";
import { isSlashCommand } from "./type_guards/is_slash_command.ts";
import { connectToVoiceChannel } from "./voice/connect_to_voice_channel.ts";
export {
addDiscoverySubcategory,
@@ -146,6 +147,7 @@ export {
batchEditSlashCommandPermissions,
categoryChildren,
channelOverwriteHasPermission,
connectToVoiceChannel,
createChannel,
createEmoji,
createGuild,
@@ -407,6 +409,8 @@ export let helpers = {
getGuildTemplates,
getTemplate,
syncGuildTemplate,
// voice
connectToVoiceChannel,
// webhooks
createWebhook,
deleteWebhookMessage,

View File

@@ -0,0 +1,21 @@
import { DiscordGatewayOpcodes } from "../../types/codes/gateway_opcodes.ts";
import type { UpdateVoiceState } from "../../types/voice/update_voice_state.ts";
import { requireBotChannelPermissions } from "../../util/permissions.ts";
import { calculateShardId } from "../../util/calculate_shard_id.ts";
import { snakelize } from "../../util/utils.ts";
import { ws } from "../../ws/ws.ts";
import type { AtLeastOne } from "../../types/util.ts";
/** Connect or join a voice channel inside a guild. By default, the "selfDeaf" option is true. Requires `CONNECT` and `VIEW_CHANNEL` permissions. */
export async function connectToVoiceChannel(
guildId: bigint,
channelId: bigint,
options?: AtLeastOne<Omit<UpdateVoiceState, "guildId" | "channelId">>
) {
await requireBotChannelPermissions(channelId, ["CONNECT", "VIEW_CHANNEL"]);
ws.sendShardMessage(calculateShardId(guildId), {
op: DiscordGatewayOpcodes.VoiceStateUpdate,
d: snakelize<UpdateVoiceState>({guildId, channelId, selfMute: Boolean(options?.selfMute), selfDeaf: options.selfDeaf ?? true }),
});
}

View File

@@ -149,3 +149,5 @@ export type CamelCasedPropertiesDeep<Value> = Value extends Function
: {
[K in keyof Value as CamelCase<K>]: CamelCasedPropertiesDeep<Value[K]>;
};
export type AtLeastOne<T, U = { [K in keyof T]: Pick<T, K> }> = Partial<T> & U[keyof U];

View File

@@ -0,0 +1,7 @@
import { ws } from "../ws/ws.ts";
export function calculateShardId(guildId: bigint) {
if (ws.maxShards === 1) return 0;
return Number((guildId >> 22n) % BigInt(ws.maxShards - 1));
}