From 6f5618abe836ff7ecbace17d991333956991fa00 Mon Sep 17 00:00:00 2001 From: ayntee Date: Wed, 14 Apr 2021 10:01:27 +0400 Subject: [PATCH 1/3] Add @ayntee to CODEOWNERS --- .github/CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index f1ab551df..99e1a8ca6 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1 +1 @@ -* @Skillz4Killz @itohatweb +* @ayntee @Skillz4Killz @itohatweb From 702896ef8db7ded2a004f5d2a3ff20149c9b8cbb Mon Sep 17 00:00:00 2001 From: ayntee Date: Wed, 14 Apr 2021 10:07:56 +0400 Subject: [PATCH 2/3] ci(test): add @ayntee --- .github/workflows/test.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c558d9c70..77e52dbeb 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -16,16 +16,16 @@ jobs: deno-version: ${{ matrix.deno }} - name: Cache dependencies run: deno cache --no-check mod.ts - - name: Run test script for Devs - if: ${{ github.actor == 'Skillz4Killz' || github.actor == 'itohatweb' }} - run: deno test --unstable --coverage=coverage -A --no-check tests/mod.ts - - name: Run test script for label + - name: Run test script for maintainers + if: ${{ github.actor === "ayntee" || github.actor == 'Skillz4Killz' || github.actor == 'itohatweb' }} + run: deno test --unstable --coverage=./coverage -A --no-check tests/mod.ts + - name: Run test script if label added if: ${{ github.event_name == 'pull_request' && github.event.action == 'labeled' && github.event.label.name == 'run-tests' }} - run: DISCORD_TOKEN=${{ secrets.DISCORD_TOKEN }} deno test --unstable --coverage=coverage -A --no-check tests/mod.ts + run: DISCORD_TOKEN=${{ secrets.DISCORD_TOKEN }} deno test --unstable --coverage=./coverage --allow-net --no-check tests/mod.ts - name: Create coverage report - run: deno --unstable coverage ./coverage --lcov > coverage.lcov # create coverage report - - name: Collect coverage - uses: codecov/codecov-action@v1.0.10 # upload the report on Codecov + run: deno --unstable coverage ./coverage --lcov > coverage.lcov + - name: Collect and upload the coverage report + uses: codecov/codecov-action@v1.0.10 with: file: ./coverage.lcov env: From a854219b81cb80e396a79da55d93a1fa09693904 Mon Sep 17 00:00:00 2001 From: ayntee Date: Wed, 14 Apr 2021 11:11:22 +0400 Subject: [PATCH 3/3] feat: add support for stage channels (#728) * feat: add support for stage channels * idk * Add helpers for voice state * Rename updateUserVoiceState() to updateVoiceState() * Update src/types/channels/channel_types.ts Co-authored-by: ITOH <72305210+itohatweb@users.noreply.github.com> * Update src/helpers/guilds/update_user_voice_state.ts Co-authored-by: ITOH <72305210+itohatweb@users.noreply.github.com> * Update src/helpers/guilds/update_bot_voice_state.ts Co-authored-by: ITOH <72305210+itohatweb@users.noreply.github.com> Co-authored-by: ITOH <72305210+itohatweb@users.noreply.github.com> --- src/helpers/guilds/update_bot_voice_state.ts | 28 ++++++++++++++++++ src/helpers/guilds/update_user_voice_state.ts | 29 +++++++++++++++++++ src/types/channels/channel_types.ts | 2 ++ src/types/guilds/update_others_voice_state.ts | 13 +++++++++ src/types/guilds/update_self_voice_state.ts | 13 +++++++++ .../permissions/bitwise_permission_flags.ts | 2 ++ src/types/voice/voice_state.ts | 2 ++ src/util/constants.ts | 2 ++ 8 files changed, 91 insertions(+) create mode 100644 src/helpers/guilds/update_bot_voice_state.ts create mode 100644 src/helpers/guilds/update_user_voice_state.ts create mode 100644 src/types/guilds/update_others_voice_state.ts create mode 100644 src/types/guilds/update_self_voice_state.ts diff --git a/src/helpers/guilds/update_bot_voice_state.ts b/src/helpers/guilds/update_bot_voice_state.ts new file mode 100644 index 000000000..5fcf0849c --- /dev/null +++ b/src/helpers/guilds/update_bot_voice_state.ts @@ -0,0 +1,28 @@ +import { RequestManager } from "../../rest/request_manager.ts"; +import { + DiscordUpdateSelfVoiceState, + UpdateSelfVoiceState, +} from "../../types/guilds/update_self_voice_state.ts"; +import { endpoints } from "../../util/constants.ts"; +import { camelKeysToSnakeCase } from "../../util/utils.ts"; + +/** + * Updates the current user's voice state. + * Caveats: + * - `channel_id` must currently point to a stage channel. + * - current user must already have joined `channel_id`. + * - You must have the `MUTE_MEMBERS` permission to unsuppress yourself. You can always suppress yourself. + * - You must have the `REQUEST_TO_SPEAK` permission to request to speak. You can always clear your own request to speak. + * - You are able to set `request_to_speak_timestamp` to any present or future time. + */ +export function updateBotVoiceState( + guildId: string, + data: UpdateSelfVoiceState, +) { + const payload = camelKeysToSnakeCase(data); + + return RequestManager.patch( + endpoints.UPDATE_VOICE_STATE(guildId), + payload, + ); +} diff --git a/src/helpers/guilds/update_user_voice_state.ts b/src/helpers/guilds/update_user_voice_state.ts new file mode 100644 index 000000000..30b87630f --- /dev/null +++ b/src/helpers/guilds/update_user_voice_state.ts @@ -0,0 +1,29 @@ +import { RequestManager } from "../../rest/request_manager.ts"; +import { + DiscordUpdateOthersVoiceState, + UpdateOthersVoiceState, +} from "../../types/guilds/update_others_voice_state.ts"; +import { endpoints } from "../../util/constants.ts"; +import { camelKeysToSnakeCase } from "../../util/utils.ts"; + +/** + * Updates another user's voice state. + * Caveats: + * - `channel_id` must currently point to a stage channel. + * - User must already have joined `channel_id`. + * - You must have the `MUTE_MEMBERS` permission. (Since suppression is the only thing that is available currently.) + * - When unsuppressed, non-bot users will have their `request_to_speak_timestamp` set to the current time. Bot users will not. + * - When suppressed, the user will have their `request_to_speak_timestamp` removed. + */ +export function updateVoiceState( + guildId: string, + userId: string, + data: UpdateOthersVoiceState, +) { + const payload = camelKeysToSnakeCase(data); + + return RequestManager.patch( + endpoints.UPDATE_VOICE_STATE(guildId, userId), + payload, + ); +} diff --git a/src/types/channels/channel_types.ts b/src/types/channels/channel_types.ts index faf61ed7a..e7a47deab 100644 --- a/src/types/channels/channel_types.ts +++ b/src/types/channels/channel_types.ts @@ -14,4 +14,6 @@ export enum DiscordChannelTypes { GUILD_NEWS, /** A channel in which game developers can sell their game on Discord */ GUILD_STORE, + /** A voice channel for hosting events with an audience */ + GUILD_STAGE_VOICE = 13, } diff --git a/src/types/guilds/update_others_voice_state.ts b/src/types/guilds/update_others_voice_state.ts new file mode 100644 index 000000000..6b4c5aa8f --- /dev/null +++ b/src/types/guilds/update_others_voice_state.ts @@ -0,0 +1,13 @@ +import { SnakeCaseProps } from "../util.ts"; + +export interface UpdateOthersVoiceState { + /** The id of the channel the user is currently in */ + channelId: string; + /** Toggles the user's suppress state */ + suppress?: boolean; +} + +// TODO: add corresponding link to the resource +export type DiscordUpdateOthersVoiceState = SnakeCaseProps< + UpdateOthersVoiceState +>; diff --git a/src/types/guilds/update_self_voice_state.ts b/src/types/guilds/update_self_voice_state.ts new file mode 100644 index 000000000..120b60c8e --- /dev/null +++ b/src/types/guilds/update_self_voice_state.ts @@ -0,0 +1,13 @@ +import { SnakeCaseProps } from "../util.ts"; + +export interface UpdateSelfVoiceState { + /** The id of the channel the user is currently in */ + channelId: string; + /** Toggles the user's suppress state */ + suppress?: boolean; + /** Sets the user's request to speak */ + requestToSpeakTimestamp?: string | null; +} + +// TODO: add corresponding link to the resource +export type DiscordUpdateSelfVoiceState = SnakeCaseProps; diff --git a/src/types/permissions/bitwise_permission_flags.ts b/src/types/permissions/bitwise_permission_flags.ts index 8a1aa7c42..67ab6f218 100644 --- a/src/types/permissions/bitwise_permission_flags.ts +++ b/src/types/permissions/bitwise_permission_flags.ts @@ -62,4 +62,6 @@ export enum DiscordBitwisePermissionFlags { MANAGE_WEBHOOKS = 0x20000000, /** Allows management and editing of emojis */ MANAGE_EMOJIS = 0x40000000, + /** Allows for requesting to speak in stage channels. */ + REQUEST_TO_SPEAK = 0x100000000, } diff --git a/src/types/voice/voice_state.ts b/src/types/voice/voice_state.ts index 80dc73673..de03bbb53 100644 --- a/src/types/voice/voice_state.ts +++ b/src/types/voice/voice_state.ts @@ -26,6 +26,8 @@ export interface VoiceState { selfVideo: boolean; /** Whether this user is muted by the current user */ suppress: boolean; + /** The time at which the user requested to speak */ + requestToSpeakTimestamp: string | null; } /** https://discord.com/developers/docs/resources/voice#voice-state-object-voice-state-structure */ diff --git a/src/util/constants.ts b/src/util/constants.ts index adaa4b86e..bff7d1483 100644 --- a/src/util/constants.ts +++ b/src/util/constants.ts @@ -119,6 +119,8 @@ export const endpoints = { `${baseEndpoints.BASE_URL}/guilds/templates/${code}`, GUILD_TEMPLATES: (guildId: string) => `${GUILDS_BASE(guildId)}/templates`, GUILD_PREVIEW: (guildId: string) => `${GUILDS_BASE(guildId)}/preview`, + UPDATE_VOICE_STATE: (guildId: string, userId?: string) => + `${GUILDS_BASE(guildId)}/voice-states/${userId ?? "@me"}`, // Voice VOICE_REGIONS: `${baseEndpoints.BASE_URL}/voice/regions`,