Saltearse al contenido

Monetización

Con Seyfert ahora puedes controlar las últimas características de monetización de Discord.

Esta sección mostrará la creación básica de botones premium, eventos y comandos.

Entitlements

Los entitlements en Discord representan que un usuario o servidor tiene acceso a una oferta premium en tu aplicación. Con esto puedes saber si un usuario está suscrito a tu aplicación y otorgarle los beneficios que desees.

Recibiendo Eventos

Actualmente hay 3 eventos para los entitlements:

entitlementCreate(entitlement: Entitlement)

Se emite cada vez que se crea un entitlement.

entitlementDelete(entitlement: Entitlement)

Se emite cada vez que se elimina un entitlement. Los entitlements no se eliminan cuando expiran. Esto solo se activa cuando Discord emite un reembolso o el desarrollador elimina el entitlement manualmente.

entitlementUpdate(entitlement: Entitlement)

Se emite cada vez que se actualiza un entitlement, por ejemplo, cuando se renueva la suscripción de un usuario.

events/entitlementCreate.ts
export default
createEvent<"entitlementCreate">(data: {
data: {
name: "entitlementCreate";
once?: boolean;
};
run: (args_0: Entitlement, args_1: UsingClient, args_2: number) => any;
}): {
...;
}

Creates an event with the specified data and run function.

@paramdata - The event data.

@returnsThe created event.

@example const myEvent = createEvent({ data: { name: 'ready', once: true }, run: (user, client, shard) => { client.logger.info(Start ${user.username} on shard #${shard}); } });

createEvent
({
data: {
name: "entitlementCreate";
once?: boolean;
}
data
: {
name: "entitlementCreate"
name
: 'entitlementCreate' },
async
run: (args_0: Entitlement, args_1: UsingClient, args_2: number) => any
run
(
entitlement: Entitlement
entitlement
,
client: UsingClient
client
) {
if (!
entitlement: Entitlement
entitlement
.
userId?: string | undefined
userId
) return;
const
const subscribedUser: User
subscribedUser
= await
client: UsingClient
client
.
BaseClient.users: UsersShorter
users
.
UsersShorter.fetch(userId: string, force?: boolean): Promise<UserStructure>
fetch
(
entitlement: Entitlement
entitlement
.
userId?: string
userId
);
client: UsingClient
client
.
BaseClient.messages: MessageShorter
messages
.
MessageShorter.write(channelId: string, { files, ...body }: MessageCreateBodyRequest): Promise<MessageStructure>
write
('LOG_CHANNEL_ID', {
content?: string | undefined

The message contents (up to 2000 characters)

content
: `${
const subscribedUser: User
subscribedUser
.
globalName: string | null
globalName
} (${
const subscribedUser: User
subscribedUser
.
DiscordBase<APIUser>.id: string
id
}) se ha suscrito a ${
entitlement: Entitlement
entitlement
.
skuId: string
skuId
}`,
});
},
});

Botón Premium

Ahora puedes crear un Botón que redirija a cualquier artículo en tu tienda, como una suscripción, consumible, etc.

Este tipo de botón no necesita un CustomID o Label, pero sí necesita un SkuID, que puedes obtener desde el menú de tu tienda en https://discord.com/developers/applications/{APP_ID}/skus

import {
class Button

Represents a button component.

Button
} from 'seyfert';
import { ButtonStyle } from 'seyfert/lib/types';
new
new Button(data?: Partial<APIButtonComponent>): Button

Creates a new Button instance.

@paramdata - The initial data for the button.

Button
()
.
Button.setSKUId(skuId: string): Button
setSKUId
('STORE_ITEM_SKU_ID')
.
Button.setStyle(style: ButtonStyle): Button
setStyle
(ButtonStyle.
function (enum member) ButtonStyle.Premium = 6
Premium
)

Comandos / Interacciones

En cada Interacción también puedes obtener todos los entitlements activos, con ellos puedes detectar si el usuario tiene alguna suscripción, consumibles, etc.

Ejemplo:

commands/premium.ts
import {
function Declare(declare: CommandDeclareOptions): <T extends {
new (...args: any[]): object;
}>(target: T) => {
new (...args: any[]): {
name: string;
nsfw: boolean | undefined;
props: ExtraProps | undefined;
contexts: InteractionContextType[];
integrationTypes: ApplicationIntegrationType[];
defaultMemberPermissions: bigint | undefined;
botPermissions: bigint | undefined;
description: string;
type: ApplicationCommandType;
guildId?: string[];
ignore?: IgnoreCommand;
aliases?: string[];
handler?: EntryPointCommandHandlerType;
};
} & T
Declare
,
class Command
Command
, type
class CommandContext<T extends OptionsRecord = {}, M extends keyof RegisteredMiddlewares = never>
interface CommandContext<T extends OptionsRecord = {}, M extends keyof RegisteredMiddlewares = never>
CommandContext
,
class ActionRow<T extends BuilderComponents>

Represents an Action Row component in a message.

ActionRow
,
class Button

Represents a button component.

Button
} from 'seyfert';
import { ButtonStyle } from 'seyfert/lib/types';
@
function Declare(declare: CommandDeclareOptions): <T extends {
new (...args: any[]): object;
}>(target: T) => {
new (...args: any[]): {
name: string;
nsfw: boolean | undefined;
props: ExtraProps | undefined;
contexts: InteractionContextType[];
integrationTypes: ApplicationIntegrationType[];
defaultMemberPermissions: bigint | undefined;
botPermissions: bigint | undefined;
description: string;
type: ApplicationCommandType;
guildId?: string[];
ignore?: IgnoreCommand;
aliases?: string[];
handler?: EntryPointCommandHandlerType;
};
} & T
Declare
({
name: string
name
: 'premium',
description: string
description
: 'Comando premium',
})
export class
class PremiumCommand
PremiumCommand
extends
class Command
Command
{
PremiumCommand.run(ctx: CommandContext): Promise<void | WebhookMessage> | undefined
run
(
ctx: CommandContext<{}, never>
ctx
:
class CommandContext<T extends OptionsRecord = {}, M extends keyof RegisteredMiddlewares = never>
interface CommandContext<T extends OptionsRecord = {}, M extends keyof RegisteredMiddlewares = never>
CommandContext
) {
const
const allEntitlements: Entitlement[]
allEntitlements
=
ctx: CommandContext<{}, never>
ctx
.
CommandContext<{}, never>.interaction: ChatInputCommandInteraction<boolean>
interaction
.
BaseInteraction<boolean, APIChatInputApplicationCommandInteraction>.entitlements: Entitlement[]
entitlements
;
const
const isPremium: boolean
isPremium
=
const allEntitlements: Entitlement[]
allEntitlements
.
Array<Entitlement>.some(predicate: (value: Entitlement, index: number, array: Entitlement[]) => unknown, thisArg?: any): boolean

Determines whether the specified callback function returns true for any element of an array.

@parampredicate A function that accepts up to three arguments. The some method calls the predicate function for each element in the array until the predicate returns a value which is coercible to the Boolean value true, or until the end of the array.

@paramthisArg An object to which the this keyword can refer in the predicate function. If thisArg is omitted, undefined is used as the this value.

some
(
ent: Entitlement
ent
=>
ent: Entitlement
ent
.
userId?: string | undefined
userId
===
ctx: CommandContext<{}, never>
ctx
.
CommandContext<{}, never>.author: User
author
.
DiscordBase<APIUser>.id: string
id
);
const
const row: ActionRow<BuilderComponents>
row
= new
new ActionRow<BuilderComponents>({ components, ...data }?: Partial<APIActionRowComponent<APIActionRowComponentTypes>>): ActionRow<...>

Creates a new instance of the ActionRow class.

@paramdata - Optional data to initialize the Action Row.

@example const actionRow = new ActionRow({ components: [buttonRawJSON] });

ActionRow
()
.
ActionRow<BuilderComponents>.setComponents(component: BuilderComponents[]): ActionRow<BuilderComponents>

Sets the components of the Action Row.

@paramcomponent - The components to set.

@returnsThe updated Action Row instance.

@example actionRow.setComponents([buttonComponent1, buttonComponent2]);

setComponents
([
new
new Button(data?: Partial<APIButtonComponent>): Button

Creates a new Button instance.

@paramdata - The initial data for the button.

Button
()
.
Button.setSKUId(skuId: string): Button
setSKUId
('STORE_ITEM_SKU_ID')
.
Button.setStyle(style: ButtonStyle): Button
setStyle
(ButtonStyle.
function (enum member) ButtonStyle.Premium = 6
Premium
)
]);
if (!
const isPremium: boolean
isPremium
) return
ctx: CommandContext<{}, never>
ctx
.
CommandContext<{}, never>.editOrReply<false>(body: InteractionCreateBodyRequest | InteractionMessageUpdateBodyRequest, withResponse?: false | undefined): Promise<...>
editOrReply
({
content: string
content
: '¡Haz clic en este botón para suscribirte y obtener acceso al comando!',
ResolverProps.components?: APIActionRowComponent<APIMessageActionRowComponent>[] | ActionRow<BuilderComponents>[] | undefined
components
: [
const row: ActionRow<BuilderComponents>
row
]
});
// Premium code
}
}