mirror of
https://github.com/tiramisulabs/seyfert.git
synced 2025-07-01 20:46:08 +00:00
feat: allow interaction server for all clients (#295)
* fix: default callbacks & cache update * feat: allow interaction server for all clients
This commit is contained in:
parent
7f4044469b
commit
961bff0e27
@ -40,6 +40,7 @@ import {
|
|||||||
} from '../common';
|
} from '../common';
|
||||||
|
|
||||||
import { promises } from 'node:fs';
|
import { promises } from 'node:fs';
|
||||||
|
import { isBufferLike } from '../api/utils/utils';
|
||||||
import { HandleCommand } from '../commands/handle';
|
import { HandleCommand } from '../commands/handle';
|
||||||
import { BanShorter } from '../common/shorters/bans';
|
import { BanShorter } from '../common/shorters/bans';
|
||||||
import { VoiceStateShorter } from '../common/shorters/voiceStates';
|
import { VoiceStateShorter } from '../common/shorters/voiceStates';
|
||||||
@ -55,7 +56,7 @@ import type {
|
|||||||
ModalSubmitInteraction,
|
ModalSubmitInteraction,
|
||||||
UserCommandInteraction,
|
UserCommandInteraction,
|
||||||
} from '../structures';
|
} from '../structures';
|
||||||
import type { LocaleString, RESTPostAPIChannelMessageJSONBody } from '../types';
|
import type { APIInteraction, APIInteractionResponse, LocaleString, RESTPostAPIChannelMessageJSONBody } from '../types';
|
||||||
import type { MessageStructure } from './transformers';
|
import type { MessageStructure } from './transformers';
|
||||||
|
|
||||||
export class BaseClient {
|
export class BaseClient {
|
||||||
@ -253,20 +254,17 @@ export class BaseClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async start(
|
async start(
|
||||||
options: Pick<DeepPartial<StartOptions>, 'langsDir' | 'commandsDir' | 'connection' | 'token' | 'componentsDir'> = {
|
options: Pick<
|
||||||
token: undefined,
|
DeepPartial<StartOptions>,
|
||||||
langsDir: undefined,
|
'langsDir' | 'commandsDir' | 'connection' | 'token' | 'componentsDir'
|
||||||
commandsDir: undefined,
|
> = {},
|
||||||
connection: undefined,
|
|
||||||
componentsDir: undefined,
|
|
||||||
},
|
|
||||||
) {
|
) {
|
||||||
await this.loadLangs(options.langsDir);
|
await this.loadLangs(options.langsDir);
|
||||||
await this.loadCommands(options.commandsDir);
|
await this.loadCommands(options.commandsDir);
|
||||||
await this.loadComponents(options.componentsDir);
|
await this.loadComponents(options.componentsDir);
|
||||||
|
|
||||||
const { token: tokenRC, debug } = await this.getRC();
|
const { token: tokenRC, debug } = await this.getRC();
|
||||||
const token = options?.token ?? tokenRC;
|
const token = options.token ?? tokenRC;
|
||||||
BaseClient.assertString(token, 'token is not a string');
|
BaseClient.assertString(token, 'token is not a string');
|
||||||
|
|
||||||
if (this.rest.options.token === 'INVALID') this.rest.options.token = token;
|
if (this.rest.options.token === 'INVALID') this.rest.options.token = token;
|
||||||
@ -283,17 +281,56 @@ export class BaseClient {
|
|||||||
throw new Error('Function not implemented');
|
throw new Error('Function not implemented');
|
||||||
}
|
}
|
||||||
|
|
||||||
private shouldUploadCommands(cachePath: string, guildId?: string) {
|
/**
|
||||||
return this.commands!.shouldUpload(cachePath, guildId).then(should => {
|
*
|
||||||
this.logger.debug(
|
* @param rawBody body of interaction
|
||||||
should
|
* @returns
|
||||||
? `[${guildId ?? 'global'}] Change(s) detected, uploading commands`
|
*/
|
||||||
: `[${guildId ?? 'global'}] commands seems to be up to date`,
|
protected async onInteractionRequest(rawBody: APIInteraction): Promise<{
|
||||||
);
|
headers: { 'Content-Type'?: string };
|
||||||
return should;
|
response: APIInteractionResponse | FormData;
|
||||||
|
}> {
|
||||||
|
return new Promise(async r => {
|
||||||
|
await this.handleCommand.interaction(rawBody, -1, async ({ body, files }) => {
|
||||||
|
let response: FormData | APIInteractionResponse;
|
||||||
|
const headers: { 'Content-Type'?: string } = {};
|
||||||
|
|
||||||
|
if (files) {
|
||||||
|
response = new FormData();
|
||||||
|
for (const [index, file] of files.entries()) {
|
||||||
|
const fileKey = file.key ?? `files[${index}]`;
|
||||||
|
if (isBufferLike(file.data)) {
|
||||||
|
response.append(fileKey, new Blob([file.data], { type: file.contentType }), file.filename);
|
||||||
|
} else {
|
||||||
|
response.append(fileKey, new Blob([`${file.data}`], { type: file.contentType }), file.filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (body) {
|
||||||
|
response.append('payload_json', JSON.stringify(body));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
response = body ?? {};
|
||||||
|
headers['Content-Type'] = 'application/json';
|
||||||
|
}
|
||||||
|
|
||||||
|
return r({
|
||||||
|
headers,
|
||||||
|
response,
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async shouldUploadCommands(cachePath: string, guildId?: string) {
|
||||||
|
const should = await this.commands!.shouldUpload(cachePath, guildId);
|
||||||
|
this.logger.debug(
|
||||||
|
should
|
||||||
|
? `[${guildId ?? 'global'}] Change(s) detected, uploading commands`
|
||||||
|
: `[${guildId ?? 'global'}] commands seems to be up to date`,
|
||||||
|
);
|
||||||
|
return should;
|
||||||
|
}
|
||||||
|
|
||||||
private syncCachePath(cachePath: string) {
|
private syncCachePath(cachePath: string) {
|
||||||
return promises.writeFile(
|
return promises.writeFile(
|
||||||
cachePath,
|
cachePath,
|
||||||
@ -431,7 +468,7 @@ export interface BaseClientOptions {
|
|||||||
| ModalSubmitInteraction
|
| ModalSubmitInteraction
|
||||||
| EntryPointInteraction<boolean>
|
| EntryPointInteraction<boolean>
|
||||||
| When<InferWithPrefix, MessageStructure, never>,
|
| When<InferWithPrefix, MessageStructure, never>,
|
||||||
) => object;
|
) => Record<string, unknown>;
|
||||||
globalMiddlewares?: readonly (keyof RegisteredMiddlewares)[];
|
globalMiddlewares?: readonly (keyof RegisteredMiddlewares)[];
|
||||||
commands?: {
|
commands?: {
|
||||||
defaults?: {
|
defaults?: {
|
||||||
@ -516,7 +553,7 @@ export type RuntimeConfigHTTP = Omit<MakeRequired<RC, 'publicKey' | 'application
|
|||||||
locations: Omit<RC['locations'], 'events'>;
|
locations: Omit<RC['locations'], 'events'>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type InternalRuntimeConfig = Omit<MakeRequired<RC, 'intents'>, 'publicKey' | 'port'>;
|
export type InternalRuntimeConfig = MakeRequired<RC, 'intents'>;
|
||||||
export type RuntimeConfig = OmitInsert<
|
export type RuntimeConfig = OmitInsert<
|
||||||
InternalRuntimeConfig,
|
InternalRuntimeConfig,
|
||||||
'intents',
|
'intents',
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
import { isBufferLike } from '../api/utils/utils';
|
|
||||||
import type { DeepPartial } from '../common';
|
import type { DeepPartial } from '../common';
|
||||||
import type { APIInteraction, APIInteractionResponse } from '../types';
|
|
||||||
import type { BaseClientOptions, StartOptions } from './base';
|
import type { BaseClientOptions, StartOptions } from './base';
|
||||||
import { BaseClient } from './base';
|
import { BaseClient } from './base';
|
||||||
|
|
||||||
@ -13,39 +11,4 @@ export class HttpClient extends BaseClient {
|
|||||||
await super.start(options);
|
await super.start(options);
|
||||||
return this.execute(options.httpConnection ?? {});
|
return this.execute(options.httpConnection ?? {});
|
||||||
}
|
}
|
||||||
|
|
||||||
async onPacket(rawBody: APIInteraction): Promise<{
|
|
||||||
headers: { 'Content-Type'?: string };
|
|
||||||
response: APIInteractionResponse | FormData;
|
|
||||||
}> {
|
|
||||||
return new Promise(async r => {
|
|
||||||
await this.handleCommand.interaction(rawBody, -1, async ({ body, files }) => {
|
|
||||||
let response: FormData | APIInteractionResponse;
|
|
||||||
const headers: { 'Content-Type'?: string } = {};
|
|
||||||
|
|
||||||
if (files) {
|
|
||||||
response = new FormData();
|
|
||||||
for (const [index, file] of files.entries()) {
|
|
||||||
const fileKey = file.key ?? `files[${index}]`;
|
|
||||||
if (isBufferLike(file.data)) {
|
|
||||||
response.append(fileKey, new Blob([file.data], { type: file.contentType }), file.filename);
|
|
||||||
} else {
|
|
||||||
response.append(fileKey, new Blob([`${file.data}`], { type: file.contentType }), file.filename);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (body) {
|
|
||||||
response.append('payload_json', JSON.stringify(body));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
response = body ?? {};
|
|
||||||
headers['Content-Type'] = 'application/json';
|
|
||||||
}
|
|
||||||
|
|
||||||
return r({
|
|
||||||
headers,
|
|
||||||
response,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import type { HttpClient } from './httpclient';
|
import type { UsingClient } from '../commands';
|
||||||
|
|
||||||
export interface HttpServerAdapter {
|
export interface HttpServerAdapter {
|
||||||
client: HttpClient;
|
client: UsingClient;
|
||||||
start?(path: `/${string}`): any;
|
start?(path: `/${string}`): any;
|
||||||
}
|
}
|
||||||
|
@ -224,7 +224,7 @@ export class CommandContext<
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface GuildCommandContext<T extends OptionsRecord = {}, M extends keyof RegisteredMiddlewares = never>
|
export interface GuildCommandContext<T extends OptionsRecord = {}, M extends keyof RegisteredMiddlewares = never>
|
||||||
extends Omit<MakeRequired<CommandContext<T, M>, 'guildId'>, 'guild'> {
|
extends Omit<MakeRequired<CommandContext<T, M>, 'guildId' | 'member'>, 'guild'> {
|
||||||
guild(mode?: 'rest' | 'flow'): Promise<GuildStructure<'cached' | 'api'>>;
|
guild(mode?: 'rest' | 'flow'): Promise<GuildStructure<'cached' | 'api'>>;
|
||||||
guild(mode?: 'cache'): ReturnCache<GuildStructure<'cached'> | undefined>;
|
guild(mode?: 'cache'): ReturnCache<GuildStructure<'cached'> | undefined>;
|
||||||
}
|
}
|
||||||
|
@ -130,7 +130,7 @@ export class EntryPointContext<M extends keyof RegisteredMiddlewares = never> ex
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface GuildEntryPointContext<M extends keyof RegisteredMiddlewares = never>
|
export interface GuildEntryPointContext<M extends keyof RegisteredMiddlewares = never>
|
||||||
extends Omit<MakeRequired<EntryPointContext<M>, 'guildId'>, 'guild'> {
|
extends Omit<MakeRequired<EntryPointContext<M>, 'guildId' | 'member'>, 'guild'> {
|
||||||
guild(mode?: 'rest' | 'flow'): Promise<GuildStructure<'cached' | 'api'>>;
|
guild(mode?: 'rest' | 'flow'): Promise<GuildStructure<'cached' | 'api'>>;
|
||||||
guild(mode?: 'cache'): ReturnCache<GuildStructure<'cached'> | undefined>;
|
guild(mode?: 'cache'): ReturnCache<GuildStructure<'cached'> | undefined>;
|
||||||
}
|
}
|
||||||
|
@ -169,7 +169,7 @@ export class MenuCommandContext<
|
|||||||
export interface GuildMenuCommandContext<
|
export interface GuildMenuCommandContext<
|
||||||
T extends MessageCommandInteraction | UserCommandInteraction,
|
T extends MessageCommandInteraction | UserCommandInteraction,
|
||||||
M extends keyof RegisteredMiddlewares = never,
|
M extends keyof RegisteredMiddlewares = never,
|
||||||
> extends Omit<MakeRequired<MenuCommandContext<T, M>, 'guildId'>, 'guild'> {
|
> extends Omit<MakeRequired<MenuCommandContext<T, M>, 'guildId' | 'member'>, 'guild'> {
|
||||||
guild(mode?: 'rest' | 'flow'): Promise<GuildStructure<'cached' | 'api'>>;
|
guild(mode?: 'rest' | 'flow'): Promise<GuildStructure<'cached' | 'api'>>;
|
||||||
guild(mode?: 'cache'): ReturnCache<GuildStructure<'cached'> | undefined>;
|
guild(mode?: 'cache'): ReturnCache<GuildStructure<'cached'> | undefined>;
|
||||||
}
|
}
|
||||||
|
@ -260,7 +260,7 @@ export interface ContextComponentCommandInteractionMap {
|
|||||||
export interface GuildComponentContext<
|
export interface GuildComponentContext<
|
||||||
Type extends keyof ContextComponentCommandInteractionMap,
|
Type extends keyof ContextComponentCommandInteractionMap,
|
||||||
M extends keyof RegisteredMiddlewares = never,
|
M extends keyof RegisteredMiddlewares = never,
|
||||||
> extends Omit<MakeRequired<ComponentContext<Type, M>, 'guildId'>, 'guild'> {
|
> extends Omit<MakeRequired<ComponentContext<Type, M>, 'guildId' | 'member'>, 'guild'> {
|
||||||
guild(mode?: 'rest' | 'flow'): Promise<GuildStructure<'cached' | 'api'>>;
|
guild(mode?: 'rest' | 'flow'): Promise<GuildStructure<'cached' | 'api'>>;
|
||||||
guild(mode?: 'cache'): ReturnCache<GuildStructure<'cached'> | undefined>;
|
guild(mode?: 'cache'): ReturnCache<GuildStructure<'cached'> | undefined>;
|
||||||
}
|
}
|
||||||
|
@ -196,7 +196,7 @@ export class ModalContext<M extends keyof RegisteredMiddlewares = never> extends
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface GuildModalContext<M extends keyof RegisteredMiddlewares = never>
|
export interface GuildModalContext<M extends keyof RegisteredMiddlewares = never>
|
||||||
extends Omit<MakeRequired<ModalContext<M>, 'guildId'>, 'guild'> {
|
extends Omit<MakeRequired<ModalContext<M>, 'guildId' | 'member'>, 'guild'> {
|
||||||
guild(mode?: 'rest' | 'flow'): Promise<GuildStructure<'cached' | 'api'>>;
|
guild(mode?: 'rest' | 'flow'): Promise<GuildStructure<'cached' | 'api'>>;
|
||||||
guild(mode?: 'cache'): ReturnCache<GuildStructure<'cached'> | undefined>;
|
guild(mode?: 'cache'): ReturnCache<GuildStructure<'cached'> | undefined>;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user