mirror of
https://github.com/tiramisulabs/seyfert.git
synced 2025-07-02 21:16:09 +00:00
feat(commands): closes #39
This commit is contained in:
parent
527b09e3e4
commit
b4ad1865e1
@ -347,3 +347,24 @@ export function GUILD_APPLICATION_COMMANDS_PERMISSIONS(appId: Snowflake, guildId
|
||||
if (commandId) return `/applications/${appId}/guilds/${guildId}/commands/${commandId}/permissions`;
|
||||
return `/applications/${appId}/guilds/${guildId}/commands/permissions`;
|
||||
}
|
||||
|
||||
|
||||
export function APPLICATION_COMMANDS_LOCALIZATIONS(appId: Snowflake, commandId: Snowflake, withLocalizations?: boolean) {
|
||||
let url = `/applications/${appId}/commands/${commandId}?`;
|
||||
|
||||
if (withLocalizations !== undefined) {
|
||||
url += `withLocalizations=${withLocalizations}`;
|
||||
}
|
||||
|
||||
return url;
|
||||
}
|
||||
|
||||
export function GUILD_APPLICATION_COMMANDS_LOCALIZATIONS(appId: Snowflake, guildId: Snowflake, commandId: Snowflake, withLocalizations?: boolean) {
|
||||
let url = `/applications/${appId}/guilds/${guildId}/commands/${commandId}?`;
|
||||
|
||||
if (withLocalizations !== undefined) {
|
||||
url += `with_localizations=${withLocalizations}`;
|
||||
}
|
||||
|
||||
return url;
|
||||
}
|
||||
|
@ -1,16 +1,84 @@
|
||||
import type { DiscordGetGatewayBot, GatewayBot, GatewayIntents } from "../discordeno/mod.ts";
|
||||
import type {
|
||||
ApplicationCommandPermissionTypes,
|
||||
AtLeastOne,
|
||||
Localization,
|
||||
DiscordApplicationCommand,
|
||||
DiscordApplicationCommandOption,
|
||||
DiscordGuildApplicationCommandPermissions,
|
||||
DiscordGetGatewayBot,
|
||||
GatewayBot,
|
||||
GatewayIntents,
|
||||
} from "../discordeno/mod.ts";
|
||||
|
||||
import type { DiscordGatewayPayload, Shard } from "../discordeno/mod.ts";
|
||||
import type { Events } from "./Actions.ts";
|
||||
import type { PermissionResolvable } from "./structures/Permissions.ts";
|
||||
|
||||
import { Permissions } from "./structures/Permissions.ts";
|
||||
import { Snowflake } from "./Snowflake.ts";
|
||||
import { EventEmitter } from "./util/EventEmmiter.ts";
|
||||
import { createGatewayManager, createRestManager, getBotIdFromToken } from "../discordeno/mod.ts";
|
||||
import { ApplicationCommandTypes, createGatewayManager, createRestManager, getBotIdFromToken } from "../discordeno/mod.ts";
|
||||
|
||||
import * as Routes from "./Routes.ts";
|
||||
import * as Actions from "./Actions.ts";
|
||||
|
||||
export type DiscordRawEventHandler = (shard: Shard, data: DiscordGatewayPayload) => unknown;
|
||||
|
||||
// INTERACTIONS
|
||||
|
||||
/**
|
||||
* @link https://discord.com/developers/docs/interactions/application-commands#endpoints-json-params
|
||||
* */
|
||||
export interface CreateApplicationCommand {
|
||||
name: string;
|
||||
nameLocalizations?: Localization;
|
||||
description: string;
|
||||
descriptionLocalizations?: Localization;
|
||||
type?: ApplicationCommandTypes;
|
||||
options?: DiscordApplicationCommandOption[];
|
||||
defaultMemberPermissions?: PermissionResolvable;
|
||||
dmPermission?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* @link https://discord.com/developers/docs/interactions/application-commands#endpoints-json-params
|
||||
* */
|
||||
export interface CreateContextApplicationCommand extends Omit<CreateApplicationCommand, "options"> {
|
||||
type: ApplicationCommandTypes.Message | ApplicationCommandTypes.User;
|
||||
}
|
||||
|
||||
/**
|
||||
* @link https://discord.com/developers/docs/interactions/application-commands#endpoints-query-string-params
|
||||
* */
|
||||
export interface GetApplicationCommand {
|
||||
guildId?: Snowflake;
|
||||
withLocalizations?: boolean;
|
||||
}
|
||||
|
||||
export interface UpsertApplicationCommands extends CreateApplicationCommand {
|
||||
id?: Snowflake;
|
||||
}
|
||||
|
||||
/**
|
||||
* @link https://discord.com/developers/docs/interactions/application-commands#edit-application-command-permissions
|
||||
* */
|
||||
export interface ApplicationCommandPermissions {
|
||||
id: Snowflake;
|
||||
type: ApplicationCommandPermissionTypes;
|
||||
permission: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* @link https://discord.com/developers/docs/interactions/application-commands#edit-application-command-permissions
|
||||
* */
|
||||
export interface ApplicationCommandPermissions {
|
||||
id: Snowflake;
|
||||
type: ApplicationCommandPermissionTypes;
|
||||
permission: boolean;
|
||||
}
|
||||
|
||||
// END INTERACTIONS
|
||||
|
||||
export interface RestOptions {
|
||||
secretKey?: string;
|
||||
applicationId?: Snowflake;
|
||||
@ -31,11 +99,11 @@ export interface SessionOptions {
|
||||
|
||||
/**
|
||||
* Receives a Token, connects
|
||||
* Most of the command implementations were adapted from Discordeno (https://github.com/discordeno/discordeno)
|
||||
*/
|
||||
export class Session extends EventEmitter {
|
||||
options: SessionOptions;
|
||||
|
||||
// TODO: improve this with CreateShardManager etc
|
||||
rest: ReturnType<typeof createRestManager>;
|
||||
gateway: ReturnType<typeof createGatewayManager>;
|
||||
|
||||
@ -114,6 +182,142 @@ export class Session extends EventEmitter {
|
||||
return super.emit(event, ...params);
|
||||
}
|
||||
|
||||
createApplicationCommand(options: CreateApplicationCommand | CreateContextApplicationCommand, guildId: Snowflake) {
|
||||
return this.rest.runMethod<DiscordApplicationCommand>(
|
||||
this.rest,
|
||||
"POST",
|
||||
guildId
|
||||
? Routes.GUILD_APPLICATION_COMMANDS(this.applicationId, guildId)
|
||||
: Routes.APPLICATION_COMMANDS(this.applicationId),
|
||||
this.isContextApplicationCommand(options) ? {
|
||||
name: options.name,
|
||||
name_localizations: options.nameLocalizations,
|
||||
type: options.type,
|
||||
} : {
|
||||
name: options.name,
|
||||
name_localizations: options.nameLocalizations,
|
||||
description: options.description,
|
||||
description_localizations: options.descriptionLocalizations,
|
||||
type: options.type,
|
||||
options: options.options,
|
||||
default_member_permissions: options.defaultMemberPermissions
|
||||
? new Permissions(options.defaultMemberPermissions).bitfield.toString()
|
||||
: undefined,
|
||||
dm_permission: options.dmPermission,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
deleteApplicationCommand(id: Snowflake, guildId?: Snowflake) {
|
||||
return this.rest.runMethod<undefined>(
|
||||
this.rest,
|
||||
"DELETE",
|
||||
guildId
|
||||
? Routes.GUILD_APPLICATION_COMMANDS(this.applicationId, guildId, id)
|
||||
: Routes.APPLICATION_COMMANDS(this.applicationId, id),
|
||||
);
|
||||
}
|
||||
|
||||
updateApplicationCommandPermissions(
|
||||
guildId: Snowflake,
|
||||
id: Snowflake,
|
||||
bearerToken: string,
|
||||
options: ApplicationCommandPermissions[],
|
||||
) {
|
||||
return this.rest.runMethod<DiscordGuildApplicationCommandPermissions>(
|
||||
this.rest,
|
||||
"PUT",
|
||||
Routes.GUILD_APPLICATION_COMMANDS_PERMISSIONS(this.applicationId, guildId, id),
|
||||
{
|
||||
permissions: options,
|
||||
},
|
||||
{
|
||||
headers: { authorization: `Bearer ${bearerToken}` }
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
fetchApplicationCommand(id: Snowflake, options?: GetApplicationCommand) {
|
||||
return this.rest.runMethod<DiscordApplicationCommand>(
|
||||
this.rest,
|
||||
"GET",
|
||||
options?.guildId
|
||||
? Routes.GUILD_APPLICATION_COMMANDS_LOCALIZATIONS(
|
||||
this.applicationId,
|
||||
options.guildId,
|
||||
id,
|
||||
options?.withLocalizations,
|
||||
)
|
||||
: Routes.APPLICATION_COMMANDS(this.applicationId, id),
|
||||
);
|
||||
}
|
||||
|
||||
fetchApplicationCommandPermissions(guildId: Snowflake) {
|
||||
return this.rest.runMethod<DiscordGuildApplicationCommandPermissions[]>(
|
||||
this.rest,
|
||||
"GET",
|
||||
Routes.GUILD_APPLICATION_COMMANDS_PERMISSIONS(this.applicationId, guildId),
|
||||
);
|
||||
}
|
||||
|
||||
fetchApplicationCommandPermission(guildId: Snowflake, id: Snowflake) {
|
||||
return this.rest.runMethod<DiscordGuildApplicationCommandPermissions>(
|
||||
this.rest,
|
||||
"GET",
|
||||
Routes.GUILD_APPLICATION_COMMANDS_PERMISSIONS(this.applicationId, guildId, id),
|
||||
);
|
||||
}
|
||||
|
||||
upsertApplicationCommand(
|
||||
id: Snowflake,
|
||||
options: AtLeastOne<CreateApplicationCommand> | AtLeastOne<CreateContextApplicationCommand>,
|
||||
guildId?: Snowflake,
|
||||
) {
|
||||
return this.rest.runMethod<DiscordApplicationCommand>(
|
||||
this.rest,
|
||||
"PATCH",
|
||||
guildId
|
||||
? Routes.GUILD_APPLICATION_COMMANDS(this.applicationId, guildId)
|
||||
: Routes.APPLICATION_COMMANDS(this.applicationId, id),
|
||||
this.isContextApplicationCommand(options) ? {
|
||||
name: options.name,
|
||||
type: options.type,
|
||||
} : {
|
||||
name: options.name,
|
||||
description: options.description,
|
||||
type: options.type,
|
||||
options: options.options,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
upsertApplicationCommands(options: Array<UpsertApplicationCommands | CreateContextApplicationCommand>, guildId?: Snowflake) {
|
||||
return this.rest.runMethod<DiscordApplicationCommand[]>(
|
||||
this.rest,
|
||||
"PUT",
|
||||
guildId
|
||||
? Routes.GUILD_APPLICATION_COMMANDS(this.applicationId, guildId)
|
||||
: Routes.APPLICATION_COMMANDS(this.applicationId),
|
||||
options.map((o) => this.isContextApplicationCommand(o) ? {
|
||||
name: o.name,
|
||||
type: o.type,
|
||||
} : {
|
||||
name: o.name,
|
||||
description: o.description,
|
||||
type: o.type,
|
||||
options: o.options,
|
||||
}
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
fetchCommands() {}
|
||||
|
||||
// deno-fmt-ignore
|
||||
isContextApplicationCommand(cmd: AtLeastOne<CreateContextApplicationCommand> | AtLeastOne<CreateApplicationCommand>): cmd is AtLeastOne<CreateContextApplicationCommand> {
|
||||
return cmd.type === ApplicationCommandTypes.Message || cmd.type === ApplicationCommandTypes.User;
|
||||
}
|
||||
|
||||
async start() {
|
||||
const getGatewayBot = () => this.rest.runMethod<DiscordGetGatewayBot>(this.rest, "GET", Routes.GATEWAY_BOT());
|
||||
|
||||
|
@ -134,7 +134,7 @@ export class CommandInteraction extends BaseInteraction implements Model {
|
||||
title: options?.title,
|
||||
};
|
||||
|
||||
if (!this.respond) {
|
||||
if (!this.responded) {
|
||||
await this.session.rest.sendRequest<undefined>(this.session.rest, {
|
||||
url: Routes.INTERACTION_ID_TOKEN(this.id, this.token),
|
||||
method: "POST",
|
||||
|
@ -2,7 +2,9 @@ import type { Model } from "../Base.ts";
|
||||
import type { Snowflake } from "../../Snowflake.ts";
|
||||
import type { Session } from "../../Session.ts";
|
||||
import type { DiscordInteraction, InteractionTypes } from "../../../discordeno/mod.ts";
|
||||
import type { InteractionResponse, InteractionApplicationCommandCallbackData } from "./CommandInteraction.ts";
|
||||
import { MessageComponentTypes } from "../../../discordeno/mod.ts";
|
||||
import CommandInteraction from "./CommandInteraction.ts";
|
||||
import BaseInteraction from "./BaseInteraction.ts";
|
||||
import Message from "../Message.ts";
|
||||
|
||||
@ -40,6 +42,14 @@ export class ComponentInteraction extends BaseInteraction implements Model {
|
||||
isSelectMenu() {
|
||||
return this.componentType === MessageComponentTypes.SelectMenu;
|
||||
}
|
||||
|
||||
sendFollowUp(options: InteractionApplicationCommandCallbackData) {
|
||||
return CommandInteraction.prototype.sendFollowUp.call(this, options);
|
||||
}
|
||||
|
||||
respond(options: InteractionResponse): Promise<Message | undefined> {
|
||||
return CommandInteraction.prototype.respond.call(this, options);
|
||||
}
|
||||
}
|
||||
|
||||
export default ComponentInteraction;
|
||||
|
@ -1229,7 +1229,6 @@ export interface GatewayBot {
|
||||
// UTILS
|
||||
|
||||
export type AtLeastOne<T, U = { [K in keyof T]: Pick<T, K> }> = Partial<T> & U[keyof U];
|
||||
|
||||
export type MakeRequired<T, K extends keyof T> = T & { [P in K]-?: T[P] };
|
||||
|
||||
// THANK YOU YUI FOR SHARING THIS!
|
||||
@ -1243,87 +1242,6 @@ export type Camelize<T> = {
|
||||
: never;
|
||||
};
|
||||
|
||||
/** Non object primitives */
|
||||
export type Primitive =
|
||||
| string
|
||||
| number
|
||||
| symbol
|
||||
| bigint
|
||||
| boolean
|
||||
| undefined
|
||||
| null;
|
||||
// | object <- don't make object a primitive
|
||||
|
||||
/**
|
||||
* alternative to 'object' or '{}'
|
||||
* @example:
|
||||
* export const o: ObjectLiteral = [] as object; // error
|
||||
* export const o: object = []; // no error
|
||||
*/
|
||||
export type ObjectLiteral<T = unknown> = {
|
||||
[K in PropertyKey]: T;
|
||||
};
|
||||
|
||||
/** Array with no utilty methods, aka Object.create(null) */
|
||||
export type ArrayWithNoPrototype<T> = {
|
||||
[index: number]: T | ArrayWithNoPrototype<T>;
|
||||
};
|
||||
|
||||
/**
|
||||
* Allows any type but T
|
||||
* it is recursive
|
||||
* @example
|
||||
* export type RequestData = Record<string, AnythingBut<bigint>>;
|
||||
*/
|
||||
export type AnythingBut<T> = Exclude<
|
||||
| Primitive
|
||||
| {
|
||||
[K in PropertyKey]: AnythingBut<T>;
|
||||
}
|
||||
| ArrayWithNoPrototype<
|
||||
| Primitive
|
||||
| {
|
||||
[K in PropertyKey]: AnythingBut<T>;
|
||||
}
|
||||
>,
|
||||
T
|
||||
>;
|
||||
|
||||
/**
|
||||
* object identity type
|
||||
*/
|
||||
export type Id<T> = T extends infer U ? {
|
||||
[K in keyof U]: U[K];
|
||||
}
|
||||
: never;
|
||||
|
||||
export type KeysWithUndefined<T> = {
|
||||
[K in keyof T]-?: undefined extends T[K] ? K
|
||||
: null extends T[K] ? K
|
||||
: never;
|
||||
}[keyof T];
|
||||
|
||||
type OptionalizeAux<T extends object> = Id<
|
||||
& {
|
||||
[K in KeysWithUndefined<T>]?: Optionalize<T[K]>;
|
||||
}
|
||||
& {
|
||||
[K in Exclude<keyof T, KeysWithUndefined<T>>]: T[K] extends ObjectLiteral ? Optionalize<T[K]> : T[K];
|
||||
}
|
||||
>;
|
||||
|
||||
/**
|
||||
* Makes all of properties in T optional when they're null | undefined
|
||||
* it is recursive
|
||||
*/
|
||||
export type Optionalize<T> = T extends object
|
||||
? T extends Array<unknown>
|
||||
? number extends T["length"] ? T[number] extends object ? Array<OptionalizeAux<T[number]>>
|
||||
: T
|
||||
: Partial<T>
|
||||
: OptionalizeAux<T>
|
||||
: T;
|
||||
|
||||
export type PickPartial<T, K extends keyof T> =
|
||||
& {
|
||||
[P in keyof T]?: T[P] | undefined;
|
||||
|
Loading…
x
Reference in New Issue
Block a user