feat(controllers): add INTEGRATION* gateway events (#459)

* feat(controllers): add INTEGRATION* gateway events

* suggestions

* forgive me, i am forgetful :P

* Update src/types/options.ts

Co-authored-by: Skillz4Killz <23035000+Skillz4Killz@users.noreply.github.com>

Co-authored-by: Skillz4Killz <23035000+Skillz4Killz@users.noreply.github.com>
This commit is contained in:
Ayyan
2021-01-26 18:32:43 +04:00
committed by GitHub
parent 8b3f9a5818
commit 7cd4fda3f4
8 changed files with 149 additions and 13 deletions

View File

@@ -7,6 +7,6 @@ jobs:
- uses: actions/checkout@v2
- uses: denolib/setup-deno@v2
- name: Run fmt check script
run: deno fmt --check
run: deno fmt --check --ignore=./src/types/util.ts
- name: Run lint script
run: deno lint src/** test/** --unstable

View File

@@ -1,6 +1,8 @@
import { eventHandlers, setApplicationID, setBotID } from "../../bot.ts";
import {
DiscordPayload,
IntegrationCreateUpdateEvent,
IntegrationDeleteEvent,
PresenceUpdatePayload,
ReadyPayload,
TypingStartPayload,
@@ -155,3 +157,73 @@ export function handleInternalWebhooksUpdate(data: DiscordPayload) {
options.guild_id,
);
}
export function handleInternalIntegrationCreate(
data: DiscordPayload,
) {
if (data.t !== "INTEGRATION_CREATE") return;
const {
guild_id: guildID,
enable_emoticons: enableEmoticons,
expire_behavior: expireBehavior,
expire_grace_period: expireGracePeriod,
subscriber_count: subscriberCount,
role_id: roleID,
synced_at: syncedAt,
...rest
} = data.d as IntegrationCreateUpdateEvent;
eventHandlers.integrationCreate?.({
...rest,
guildID,
enableEmoticons,
expireBehavior,
expireGracePeriod,
syncedAt,
subscriberCount,
roleID,
});
}
export function handleInternalIntegrationUpdate(data: DiscordPayload) {
if (data.t !== "INTEGRATION_UPDATE") return;
const {
enable_emoticons: enableEmoticons,
expire_behavior: expireBehavior,
expire_grace_period: expireGracePeriod,
role_id: roleID,
subscriber_count: subscriberCount,
synced_at: syncedAt,
guild_id: guildID,
...rest
} = data.d as IntegrationCreateUpdateEvent;
eventHandlers.integrationUpdate?.({
...rest,
guildID,
subscriberCount,
enableEmoticons,
expireGracePeriod,
roleID,
expireBehavior,
syncedAt,
});
}
export function handleInternalIntegrationDelete(data: DiscordPayload) {
if (data.t !== "INTEGRATION_DELETE") return;
const {
guild_id: guildID,
application_id: applicationID,
...rest
} = data.d as IntegrationDeleteEvent;
eventHandlers.integrationDelete?.({
...rest,
applicationID,
guildID,
});
}

View File

@@ -30,6 +30,9 @@ import {
handleInternalMessageUpdate,
} from "./messages.ts";
import {
handleInternalIntegrationCreate,
handleInternalIntegrationDelete,
handleInternalIntegrationUpdate,
handleInternalPresenceUpdate,
handleInternalReady,
handleInternalTypingStart,
@@ -82,6 +85,9 @@ export let controllers = {
USER_UPDATE: handleInternalUserUpdate,
VOICE_STATE_UPDATE: handleInternalVoiceStateUpdate,
WEBHOOKS_UPDATE: handleInternalWebhooksUpdate,
INTEGRATION_CREATE: handleInternalIntegrationCreate,
INTEGRATION_UPDATE: handleInternalIntegrationUpdate,
INTEGRATION_DELETE: handleInternalIntegrationDelete,
};
export type Controllers = typeof controllers;

View File

@@ -1,4 +1,9 @@
import { CreateGuildPayload, PartialUser, UserPayload } from "./guild.ts";
import {
CreateGuildPayload,
Integration,
PartialUser,
UserPayload,
} from "./guild.ts";
import { MemberCreatePayload } from "./member.ts";
import { Activity, Application } from "./message.ts";
import { ClientStatusPayload } from "./presence.ts";
@@ -43,7 +48,10 @@ export interface DiscordPayload {
| "TYPING_START"
| "USER_UPDATE"
| "VOICE_STATE_UPDATE"
| "WEBHOOKS_UPDATE";
| "WEBHOOKS_UPDATE"
| "INTEGRATION_CREATE"
| "INTEGRATION_UPDATE"
| "INTEGRATION_DELETE";
}
export interface DiscordBotGatewayData {
@@ -301,3 +309,17 @@ export type UnavailableGuildPayload = Pick<
CreateGuildPayload,
"id" | "unavailable"
>;
export type IntegrationCreateUpdateEvent = Integration & {
/** id of the guild */
guild_id: string;
};
export interface IntegrationDeleteEvent {
/** integration id */
id: string;
/** id of the guild */
guild_id: string;
/** id of the bot/OAuth2 application for this discord integration */
application_id?: string;
}

View File

@@ -2,7 +2,7 @@ import { Guild } from "../api/structures/mod.ts";
import { ChannelCreatePayload, ChannelTypes } from "./channel.ts";
import { Emoji, StatusType } from "./discord.ts";
import { MemberCreatePayload } from "./member.ts";
import { Activity } from "./message.ts";
import { Activity, Application } from "./message.ts";
import { Permission } from "./permission.ts";
import { ClientStatusPayload } from "./presence.ts";
import { RoleData } from "./role.ts";
@@ -246,7 +246,7 @@ export interface EditIntegrationOptions {
enable_emoticons: boolean;
}
export interface GuildIntegration {
export interface Integration {
/** The integrations unique id */
id: string;
/** the integrations name */
@@ -256,19 +256,32 @@ export interface GuildIntegration {
/** Is this integration enabled */
enabled: boolean;
/** is this integration syncing */
syncing: boolean;
syncing?: boolean;
/** id that this integration uses for "subscribers" */
role_id: string;
role_id?: string;
/** whether emoticons should be synced for this integration (twitch only currently) */
enable_emoticons?: boolean;
/** The behavior of expiring subscribers */
expire_behavior: number;
expire_behavior?: IntegrationExpireBehaviors;
/** The grace period before expiring subscribers */
expire_grace_period: number;
expire_grace_period?: number;
/** The user for this integration */
user: UserPayload;
user?: UserPayload;
/** The integration account information */
account: Account;
/** When this integration was last synced */
synced_at: string;
synced_at?: string;
/** how many subscribers this integration has */
subscriber_count?: number;
/** has this integration been revoked */
revoked?: boolean;
/** The bot/OAuth2 application for discord integrations */
application?: Application;
}
export enum IntegrationExpireBehaviors {
RemoveRole,
Kick,
}
export interface Account {

View File

@@ -188,6 +188,10 @@ export interface Application {
icon: string | null;
/** The name of the application */
name: string;
/** the description of the app */
summary: string;
/** the bot associated with this application */
bot?: UserPayload;
}
export interface Reference {

View File

@@ -8,6 +8,8 @@ import {
import {
DiscordPayload,
Emoji,
IntegrationCreateUpdateEvent,
IntegrationDeleteEvent,
PresenceUpdatePayload,
TypingStartPayload,
VoiceStateUpdatePayload,
@@ -24,6 +26,7 @@ import {
PartialMessage,
ReactionPayload,
} from "./message.ts";
import { Camelize } from "./util.ts";
export interface BotConfig {
token: string;
@@ -208,6 +211,12 @@ export interface EventHandlers {
) => unknown;
/** Sent when a guild channel's webhook is created, updated, or deleted. */
webhooksUpdate?: (channelID: string, guildID: string) => unknown;
/** Sent when an integration is created on a server such as twitch, youtube etc.. */
integrationCreate?: (data: Camelize<IntegrationCreateUpdateEvent>) => unknown;
/** Sent when an integration is updated. */
integrationUpdate?: (data: Camelize<IntegrationCreateUpdateEvent>) => unknown;
/** Sent when an integration is deleted. */
integrationDelete?: (data: Camelize<IntegrationDeleteEvent>) => undefined;
}
/** https://discord.com/developers/docs/topics/gateway#list-of-intents */
@@ -241,6 +250,9 @@ export enum Intents {
GUILD_EMOJIS = 1 << 3,
/** Enables the following events:
* - GUILD_INTEGRATIONS_UPDATE
* - INTEGRATION_CREATE
* - INTEGRATION_UPDATE
* - INTEGRATION_DELETE
*/
GUILD_INTEGRATIONS = 1 << 4,
/** Enables the following events:
@@ -297,5 +309,3 @@ export enum Intents {
*/
DIRECT_MESSAGE_TYPING = 1 << 14,
}
export type ValueOf<T> = T[keyof T];

9
src/types/util.ts Normal file
View File

@@ -0,0 +1,9 @@
export type CamelizeString<T extends PropertyKey> = T extends string
? string extends T ? string
: T extends `${infer F}_${infer R}`
? `${F}${T extends `${infer F}_id` ? Uppercase<R>
: Capitalize<CamelizeString<R>>}`
: T
: T;
export type Camelize<T> = { [K in keyof T as CamelizeString<K>]: T[K] }