mirror of
https://github.com/discordeno/discordeno.git
synced 2026-06-16 03:18:17 +00:00
integration and interaction handlers
This commit is contained in:
+14
-3
@@ -67,7 +67,7 @@ import { iconBigintToHash, iconHashToBigInt } from "./util/hash.ts";
|
|||||||
import { validateLength } from "./util/validate_length.ts";
|
import { validateLength } from "./util/validate_length.ts";
|
||||||
import { processGlobalQueue } from "./rest/process_global_queue.ts";
|
import { processGlobalQueue } from "./rest/process_global_queue.ts";
|
||||||
import { ChannelPinsUpdate } from "./types/channels/channel_pins_update.ts";
|
import { ChannelPinsUpdate } from "./types/channels/channel_pins_update.ts";
|
||||||
import { ApplicationCommandTypes, Emoji } from "./types/mod.ts";
|
import { ApplicationCommandTypes, Emoji, IntegrationCreateUpdate } from "./types/mod.ts";
|
||||||
import { ApplicationCommandOption } from "./types/mod.ts";
|
import { ApplicationCommandOption } from "./types/mod.ts";
|
||||||
import { handleGuildLoaded } from "./handlers/guilds/GUILD_LOADED_DD.ts";
|
import { handleGuildLoaded } from "./handlers/guilds/GUILD_LOADED_DD.ts";
|
||||||
import {
|
import {
|
||||||
@@ -119,6 +119,8 @@ import {
|
|||||||
handleIntegrationUpdate,
|
handleIntegrationUpdate,
|
||||||
handleIntegrationDelete,
|
handleIntegrationDelete,
|
||||||
} from "./handlers/mod.ts";
|
} from "./handlers/mod.ts";
|
||||||
|
import { DiscordenoInteraction, transformInteraction } from "./transformers/interaction.ts";
|
||||||
|
import { DiscordenoIntegration, transformIntegration } from "./transformers/integration.ts";
|
||||||
|
|
||||||
export async function createBot(options: CreateBotOptions) {
|
export async function createBot(options: CreateBotOptions) {
|
||||||
return {
|
return {
|
||||||
@@ -227,9 +229,12 @@ export function createEventHandlers(events: Partial<EventHandlers>): EventHandle
|
|||||||
function ignore() {}
|
function ignore() {}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
channelCreate: events.channelCreate ?? ignore,
|
|
||||||
debug: events.debug ?? ignore,
|
debug: events.debug ?? ignore,
|
||||||
dispatchRequirements: events.dispatchRequirements ?? ignore,
|
dispatchRequirements: events.dispatchRequirements ?? ignore,
|
||||||
|
integrationCreate: events.integrationCreate ?? ignore,
|
||||||
|
integrationDelete: events.integrationDelete ?? ignore,
|
||||||
|
interactionCreate: events.interactionCreate ?? ignore,
|
||||||
|
channelCreate: events.channelCreate ?? ignore,
|
||||||
voiceChannelLeave: events.voiceChannelLeave ?? ignore,
|
voiceChannelLeave: events.voiceChannelLeave ?? ignore,
|
||||||
channelDelete: events.channelDelete ?? ignore,
|
channelDelete: events.channelDelete ?? ignore,
|
||||||
channelPinsUpdate: events.channelPinsUpdate ?? ignore,
|
channelPinsUpdate: events.channelPinsUpdate ?? ignore,
|
||||||
@@ -470,6 +475,8 @@ export interface Transformers {
|
|||||||
message: typeof transformMessage;
|
message: typeof transformMessage;
|
||||||
role: typeof transformRole;
|
role: typeof transformRole;
|
||||||
voiceState: typeof transformVoiceState;
|
voiceState: typeof transformVoiceState;
|
||||||
|
interaction: typeof transformInteraction;
|
||||||
|
integration: typeof transformIntegration,
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createTransformers(options: Partial<Transformers>) {
|
export function createTransformers(options: Partial<Transformers>) {
|
||||||
@@ -482,6 +489,7 @@ export function createTransformers(options: Partial<Transformers>) {
|
|||||||
message: options.message || transformMessage,
|
message: options.message || transformMessage,
|
||||||
role: options.role || transformRole,
|
role: options.role || transformRole,
|
||||||
voiceState: options.voiceState || transformVoiceState,
|
voiceState: options.voiceState || transformVoiceState,
|
||||||
|
integration: options.integration || transformIntegration,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -591,6 +599,10 @@ export interface GatewayManager {
|
|||||||
|
|
||||||
export interface EventHandlers {
|
export interface EventHandlers {
|
||||||
debug: (text: string) => unknown;
|
debug: (text: string) => unknown;
|
||||||
|
interactionCreate: (bot: Bot, interaction: DiscordenoInteraction) => any;
|
||||||
|
integrationCreate: (bot: Bot, integration: DiscordenoIntegration) => any;
|
||||||
|
integrationDelete: (bot: Bot, payload: { id: bigint; guildId: bigint; applicationId?: bigint }) => any;
|
||||||
|
integrationsUpdate: (bot: Bot, integration: DiscordenoIntegration) => any;
|
||||||
channelCreate: (bot: Bot, channel: DiscordenoChannel) => any;
|
channelCreate: (bot: Bot, channel: DiscordenoChannel) => any;
|
||||||
dispatchRequirements: (bot: Bot, data: GatewayPayload, shardId: number) => any;
|
dispatchRequirements: (bot: Bot, data: GatewayPayload, shardId: number) => any;
|
||||||
voiceChannelLeave: (bot: Bot, voiceState: DiscordenoVoiceState, channel: DiscordenoChannel) => any;
|
voiceChannelLeave: (bot: Bot, voiceState: DiscordenoVoiceState, channel: DiscordenoChannel) => any;
|
||||||
@@ -643,7 +655,6 @@ export interface EventHandlers {
|
|||||||
guildCreate: (bot: Bot, guild: DiscordenoGuild) => any;
|
guildCreate: (bot: Bot, guild: DiscordenoGuild) => any;
|
||||||
guildDelete: (bot: Bot, id: bigint, guild?: DiscordenoGuild) => any;
|
guildDelete: (bot: Bot, id: bigint, guild?: DiscordenoGuild) => any;
|
||||||
guildUpdate: (bot: Bot, guild: DiscordenoGuild, cachedGuild?: DiscordenoGuild) => any;
|
guildUpdate: (bot: Bot, guild: DiscordenoGuild, cachedGuild?: DiscordenoGuild) => any;
|
||||||
integrationsUpdate: (bot: Bot, data: { guildId: bigint }) => any;
|
|
||||||
raw: (bot: Bot, data: GatewayPayload, shardId: number) => any;
|
raw: (bot: Bot, data: GatewayPayload, shardId: number) => any;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,11 @@
|
|||||||
import { eventHandlers } from "../../bot.ts";
|
import { Bot } from "../../bot.ts";
|
||||||
import type { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts";
|
import type { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts";
|
||||||
import type { IntegrationCreateUpdate } from "../../types/integrations/integration_create_update.ts";
|
import type { IntegrationCreateUpdate } from "../../types/integrations/integration_create_update.ts";
|
||||||
|
import { SnakeCasedPropertiesDeep } from "../../types/util.ts";
|
||||||
|
|
||||||
export function handleIntegrationCreate(data: DiscordGatewayPayload) {
|
export function handleIntegrationCreate(bot: Bot, data: DiscordGatewayPayload) {
|
||||||
eventHandlers.integrationCreate?.(data.d as IntegrationCreateUpdate);
|
bot.events.integrationCreate(
|
||||||
|
bot,
|
||||||
|
bot.transformers.integration(bot, data.d as SnakeCasedPropertiesDeep<IntegrationCreateUpdate>)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,14 @@
|
|||||||
import { eventHandlers } from "../../bot.ts";
|
import { Bot } from "../../bot.ts";
|
||||||
import type { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts";
|
import type { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts";
|
||||||
import type { IntegrationDelete } from "../../types/integrations/integration_delete.ts";
|
import type { IntegrationDelete } from "../../types/integrations/integration_delete.ts";
|
||||||
|
import { SnakeCasedPropertiesDeep } from "../../types/util.ts";
|
||||||
|
|
||||||
export function handleIntegrationDelete(data: DiscordGatewayPayload) {
|
export function handleIntegrationDelete(bot: Bot, data: DiscordGatewayPayload) {
|
||||||
eventHandlers.integrationDelete?.(data.d as IntegrationDelete);
|
const payload = data.d as SnakeCasedPropertiesDeep<IntegrationDelete>;
|
||||||
|
|
||||||
|
bot.events.integrationDelete(bot, {
|
||||||
|
id: bot.transformers.snowflake(payload.id),
|
||||||
|
guildId: bot.transformers.snowflake(payload.guild_id),
|
||||||
|
applicationId: payload.application_id ? bot.transformers.snowflake(payload.application_id) : undefined,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,11 @@
|
|||||||
import { eventHandlers } from "../../bot.ts";
|
import { Bot } from "../../bot.ts";
|
||||||
import type { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts";
|
import type { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts";
|
||||||
import type { IntegrationCreateUpdate } from "../../types/integrations/integration_create_update.ts";
|
import type { IntegrationCreateUpdate } from "../../types/integrations/integration_create_update.ts";
|
||||||
|
import { SnakeCasedPropertiesDeep } from "../../types/util.ts";
|
||||||
|
|
||||||
export function handleIntegrationUpdate(data: DiscordGatewayPayload) {
|
export function handleIntegrationUpdate(bot: Bot, data: DiscordGatewayPayload) {
|
||||||
eventHandlers.integrationUpdate?.(data.d as IntegrationCreateUpdate);
|
bot.events.integrationsUpdate(
|
||||||
|
bot,
|
||||||
|
bot.transformers.integration(bot, data.d as SnakeCasedPropertiesDeep<IntegrationCreateUpdate>)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,52 +1,8 @@
|
|||||||
import { eventHandlers } from "../../bot.ts";
|
import { Bot } from "../../bot.ts";
|
||||||
import { cacheHandlers } from "../../cache.ts";
|
|
||||||
import { createDiscordenoMessage, DiscordenoMessage } from "../../structures/message.ts";
|
|
||||||
import { structures } from "../../structures/mod.ts";
|
|
||||||
import type { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts";
|
import type { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts";
|
||||||
import type { BigInteraction, Interaction } from "../../types/interactions/interaction.ts";
|
import type { Interaction } from "../../types/interactions/interaction.ts";
|
||||||
import type { GuildMemberWithUser } from "../../types/members/guild_member.ts";
|
import { SnakeCasedPropertiesDeep } from "../../types/util.ts";
|
||||||
import { snowflakeToBigint } from "../../util/bigint.ts";
|
|
||||||
|
|
||||||
export async function handleInteractionCreate(data: DiscordGatewayPayload) {
|
export async function handleInteractionCreate(bot: Bot, data: DiscordGatewayPayload) {
|
||||||
const basePayload = data.d as Interaction;
|
bot.events.interactionCreate(bot, bot.transformers.interaction(bot, data.d as SnakeCasedPropertiesDeep<Interaction>));
|
||||||
|
|
||||||
const payload = {
|
|
||||||
...basePayload,
|
|
||||||
id: snowflakeToBigint(basePayload.id),
|
|
||||||
applicationId: snowflakeToBigint(basePayload.applicationId),
|
|
||||||
guildId: basePayload.guildId ? snowflakeToBigint(basePayload.guildId) : undefined,
|
|
||||||
channelId: basePayload.channelId ? snowflakeToBigint(basePayload.channelId) : undefined,
|
|
||||||
member: basePayload.member
|
|
||||||
? {
|
|
||||||
...basePayload.member,
|
|
||||||
roles: basePayload.member.roles.map((id) => snowflakeToBigint(id)),
|
|
||||||
user: {
|
|
||||||
...basePayload.member.user,
|
|
||||||
id: snowflakeToBigint(basePayload.member.user.id),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
: undefined,
|
|
||||||
user: basePayload.user
|
|
||||||
? {
|
|
||||||
...basePayload.user,
|
|
||||||
id: snowflakeToBigint(basePayload.user.id),
|
|
||||||
}
|
|
||||||
: undefined,
|
|
||||||
message: basePayload.message ? createDiscordenoMessage(basePayload.message) : undefined,
|
|
||||||
} as BigInteraction;
|
|
||||||
|
|
||||||
if (payload.member) payload.user = payload.member.user;
|
|
||||||
|
|
||||||
const discordenoMember = payload.guildId && basePayload.member
|
|
||||||
? await structures.createDiscordenoMember(basePayload.member, payload.guildId)
|
|
||||||
: undefined;
|
|
||||||
|
|
||||||
if (discordenoMember) {
|
|
||||||
await cacheHandlers.set("members", discordenoMember.id, discordenoMember);
|
|
||||||
eventHandlers.interactionGuildCreate?.(payload, discordenoMember);
|
|
||||||
} else {
|
|
||||||
eventHandlers.interactionDMCreate?.(payload);
|
|
||||||
}
|
|
||||||
|
|
||||||
eventHandlers.interactionCreate?.(payload, discordenoMember);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,91 @@
|
|||||||
|
import { Bot } from "../bot.ts";
|
||||||
|
import { IntegrationCreateUpdate } from "../types/integrations/integration_create_update.ts";
|
||||||
|
import { DiscordIntegrationExpireBehaviors } from "../types/mod.ts";
|
||||||
|
import { SnakeCasedPropertiesDeep } from "../types/util.ts";
|
||||||
|
import { DiscordenoUser } from "./member.ts";
|
||||||
|
|
||||||
|
export function transformIntegration(bot: Bot, payload: SnakeCasedPropertiesDeep<IntegrationCreateUpdate>) {
|
||||||
|
return {
|
||||||
|
guildId: bot.transformers.snowflake(payload.guild_id),
|
||||||
|
id: bot.transformers.snowflake(payload.id),
|
||||||
|
name: payload.name,
|
||||||
|
type: payload.type,
|
||||||
|
enabled: payload.enabled,
|
||||||
|
syncing: payload.syncing,
|
||||||
|
roleId: payload.role_id ? bot.transformers.snowflake(payload.role_id) : undefined,
|
||||||
|
enableEmoticons: payload.enable_emoticons,
|
||||||
|
expireBehavior: payload.expire_behavior,
|
||||||
|
expireGracePeriod: payload.expire_grace_period,
|
||||||
|
user: payload.user ? bot.transformers.user(bot, payload.user) : undefined,
|
||||||
|
account: {
|
||||||
|
id: bot.transformers.snowflake(payload.account.id),
|
||||||
|
name: payload.account.name,
|
||||||
|
},
|
||||||
|
syncedAt: payload.synced_at ? Date.parse(payload.synced_at) : undefined,
|
||||||
|
subscriberCount: payload.subscriber_count,
|
||||||
|
revoked: payload.revoked,
|
||||||
|
application: payload.application
|
||||||
|
? {
|
||||||
|
id: bot.transformers.snowflake(payload.application.id),
|
||||||
|
name: payload.application.name,
|
||||||
|
icon: payload.application.icon ? bot.utils.iconHashToBigInt(payload.application.icon) : undefined,
|
||||||
|
description: payload.application.description,
|
||||||
|
summary: payload.application.summary,
|
||||||
|
bot: payload.application.bot ? bot.transformers.user(bot, payload.application.bot) : undefined,
|
||||||
|
}
|
||||||
|
: undefined,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DiscordenoIntegration {
|
||||||
|
/** The guild id for where this integration is location. */
|
||||||
|
guildId: bigint;
|
||||||
|
/** Integration Id */
|
||||||
|
id: bigint;
|
||||||
|
/** Integration name */
|
||||||
|
name: string;
|
||||||
|
/** Integration type (twitch, youtube or discord) */
|
||||||
|
type: "twitch" | "youtube" | "discord";
|
||||||
|
/** Is this integration enabled */
|
||||||
|
enabled: boolean;
|
||||||
|
/** Is this integration syncing */
|
||||||
|
syncing?: boolean;
|
||||||
|
/** Role Id that this integration uses for "subscribers" */
|
||||||
|
roleId?: bigint;
|
||||||
|
/** Whether emoticons should be synced for this integration (twitch only currently) */
|
||||||
|
enableEmoticons?: boolean;
|
||||||
|
/** The behavior of expiring subscribers */
|
||||||
|
expireBehavior?: DiscordIntegrationExpireBehaviors;
|
||||||
|
/** The grace period (in days) before expiring subscribers */
|
||||||
|
expireGracePeriod?: number;
|
||||||
|
/** User for this integration */
|
||||||
|
user?: DiscordenoUser;
|
||||||
|
/** Integration account information */
|
||||||
|
account: {
|
||||||
|
/** Id of the account */
|
||||||
|
id: bigint;
|
||||||
|
/** Name of the account */
|
||||||
|
name: string;
|
||||||
|
};
|
||||||
|
/** When this integration was last synced */
|
||||||
|
syncedAt?: number;
|
||||||
|
/** How many subscribers this integration has */
|
||||||
|
subscriberCount?: number;
|
||||||
|
/** Has this integration been revoked */
|
||||||
|
revoked?: boolean;
|
||||||
|
/** The bot/OAuth2 application for discord integrations */
|
||||||
|
application?: {
|
||||||
|
/** The id of the app */
|
||||||
|
id: bigint;
|
||||||
|
/** The name of the app */
|
||||||
|
name: string;
|
||||||
|
/** the icon hash of the app */
|
||||||
|
icon?: bigint;
|
||||||
|
/** The description of the app */
|
||||||
|
description: string;
|
||||||
|
/** The summary of the app */
|
||||||
|
summary: string;
|
||||||
|
/** The bot associated with this application */
|
||||||
|
bot?: DiscordenoUser;
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
import { Bot } from "../bot.ts";
|
||||||
|
import { Interaction, Role } from "../types/mod.ts";
|
||||||
|
import { SnakeCasedPropertiesDeep } from "../types/util.ts";
|
||||||
|
import { DiscordenoMember, DiscordenoUser } from "./member.ts";
|
||||||
|
import { DiscordenoMessage } from "./message.ts";
|
||||||
|
|
||||||
|
export function transformInteraction(bot: Bot, payload: SnakeCasedPropertiesDeep<Interaction>): DiscordenoInteraction {
|
||||||
|
const guildId = payload.guild_id ? bot.transformers.snowflake(payload.guild_id) : undefined;
|
||||||
|
|
||||||
|
return {
|
||||||
|
// UNTRANSFORMED STUFF HERE
|
||||||
|
type: payload.type,
|
||||||
|
token: payload.token,
|
||||||
|
version: payload.version,
|
||||||
|
|
||||||
|
// TRANSFORMED STUFF BELOW
|
||||||
|
guildId,
|
||||||
|
id: bot.transformers.snowflake(payload.id),
|
||||||
|
applicationId: bot.transformers.snowflake(payload.application_id),
|
||||||
|
user: bot.transformers.user(bot, payload.member?.user || payload.user!),
|
||||||
|
message: payload.message ? bot.transformers.message(bot, payload.message) : undefined,
|
||||||
|
channelId: payload.channel_id ? bot.transformers.snowflake(payload.channel_id) : undefined,
|
||||||
|
member: payload.member && guildId ? bot.transformers.member(bot, payload.member, guildId) : undefined,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DiscordenoInteraction
|
||||||
|
extends Omit<Interaction, "id" | "applicationId" | "guildId" | "channelId" | "member" | "user" | "message"> {
|
||||||
|
/** Id of the interaction */
|
||||||
|
id: bigint;
|
||||||
|
/** Id of the application this interaction is for */
|
||||||
|
applicationId: bigint;
|
||||||
|
/** The guild it was sent from */
|
||||||
|
guildId?: bigint;
|
||||||
|
/** The channel it was sent from */
|
||||||
|
channelId?: bigint;
|
||||||
|
/** Guild member data for the invoking user, including permissions */
|
||||||
|
member?: DiscordenoMember;
|
||||||
|
/** User object for the invoking user, if invoked in a DM */
|
||||||
|
user: DiscordenoUser;
|
||||||
|
/** For the message the button was attached to */
|
||||||
|
message?: DiscordenoMessage;
|
||||||
|
}
|
||||||
@@ -3,7 +3,7 @@ import { Message } from "../types/messages/message.ts";
|
|||||||
import { CHANNEL_MENTION_REGEX } from "../util/constants.ts";
|
import { CHANNEL_MENTION_REGEX } from "../util/constants.ts";
|
||||||
import { SnakeCasedPropertiesDeep } from "../types/util.ts";
|
import { SnakeCasedPropertiesDeep } from "../types/util.ts";
|
||||||
|
|
||||||
export function transformMessage(bot: Bot, data: SnakeCasedPropertiesDeep<Message>) {
|
export function transformMessage(bot: Bot, data: SnakeCasedPropertiesDeep<Message>): DiscordenoMessage {
|
||||||
return {
|
return {
|
||||||
// UNTRANSFORMED STUFF HERE
|
// UNTRANSFORMED STUFF HERE
|
||||||
content: data.content || "",
|
content: data.content || "",
|
||||||
@@ -71,6 +71,9 @@ export interface DiscordenoMessage
|
|||||||
| "author"
|
| "author"
|
||||||
| "applicationId"
|
| "applicationId"
|
||||||
| "thread"
|
| "thread"
|
||||||
|
| "tts"
|
||||||
|
| "pinned"
|
||||||
|
| "mentionEveryone"
|
||||||
> {
|
> {
|
||||||
id: bigint;
|
id: bigint;
|
||||||
/** Whether or not this message was sent by a bot */
|
/** Whether or not this message was sent by a bot */
|
||||||
@@ -83,7 +86,7 @@ export interface DiscordenoMessage
|
|||||||
// For better user experience
|
// For better user experience
|
||||||
|
|
||||||
/** Id of the guild which the massage has been send in. "0n" if it a DM */
|
/** Id of the guild which the massage has been send in. "0n" if it a DM */
|
||||||
guildId: bigint;
|
guildId?: bigint;
|
||||||
/** id of the channel the message was sent in */
|
/** id of the channel the message was sent in */
|
||||||
channelId: bigint;
|
channelId: bigint;
|
||||||
/** If the message is generated by a webhook, this is the webhook's id */
|
/** If the message is generated by a webhook, this is the webhook's id */
|
||||||
|
|||||||
Reference in New Issue
Block a user