Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/alexis190392/bot-discord-necord-discord.js
Este es un proyecto en forma de tutorial en español, para la creacion de bot para Discord
https://github.com/alexis190392/bot-discord-necord-discord.js
discord-bot discord-js discord-js-bot discordjs necord necordjs nestjs
Last synced: about 2 months ago
JSON representation
Este es un proyecto en forma de tutorial en español, para la creacion de bot para Discord
- Host: GitHub
- URL: https://github.com/alexis190392/bot-discord-necord-discord.js
- Owner: Alexis190392
- Created: 2024-03-12T03:46:48.000Z (10 months ago)
- Default Branch: master
- Last Pushed: 2024-03-15T13:15:47.000Z (10 months ago)
- Last Synced: 2024-11-17T04:38:17.722Z (about 2 months ago)
- Topics: discord-bot, discord-js, discord-js-bot, discordjs, necord, necordjs, nestjs
- Language: TypeScript
- Homepage:
- Size: 451 KB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
> El desarrollo de este repositorio se encuenta en desarrollo al dia de la fecha: 15/03/2024
---
Haz click para ver.Descargo de Responsabilidad:
Este bot de Discord, utilizando la biblioteca Necord, tiene fines recreativos y de entretenimiento.
La información proporcionada por el bot puede no ser completamente precisa o actualizada. No me hago responsable de las decisiones tomadas basándose en la información proporcionada por el bot.El uso del bot está sujeto a cambios sin previo aviso. No garantizamos la disponibilidad continua, la funcionalidad o la precisión de los comandos proporcionados.
Este bot puede contener enlaces a sitios web de terceros. No respaldamos ni asumimos responsabilidad por el contenido de esos sitios.
Los usuarios son responsables de cumplir con los términos de servicio de Discord y cualquier otra regulación aplicable al utilizar este bot.
Al utilizar este bot, aceptas este descargo de responsabilidad y los términos de uso asociados.
---
## Descripción rápida
#### Este es un proyecto basado en Necord realizado sobre Nest a modo de prueba y tutorial (pero en español).
___
## Antes de empezar, necesitamos instalar algunas cositas:
[//]: # (> ### TIP )
>> Cabe aclarar que es necesario tener instalado [Node.js](https://nodejs.org/)### Instalar [Necord](https://necord.org/), y su dependencia [Discord.js](https://discord.js.org/)
```bash
$ yarn add necord discord.js
```### CLI: Interfaz de Línea de Comandos
```bash
$ yarn global add @nestjs/cli
#Comandos propios de Necord
$ yarn add --dev @necord/schematics
```# Configuración inicial del bot
Primero y principal necesitamos configurar nuestro bot con el token que nos provee Discord.[Discord Developer Portal](https://discord.com/developers/applications)
> 1. New Aplication.
> 2. Ingresamos el nombre de como lo llamaremos al bot y aceptamos términos.
> 3. Nos vamos a la pestaña **Bot** y presionamos en **Reset token** para obtener nuestro token.
> 4. Lo copiamos y anotamos para el siguiente paso.
> 5. Vamos a la pestaña **OAuth**.
> 6. En **Default Authorization Link** elegimos **In-app Authorization**.
> 7. Nos aparecen los **SCOPES**, seleccionamos **bot** y **applications.commands**.
> 8. Luego, en **BOT PERMISSIONS** elegimos los permisos que veas más adecuados al desarrollo.
> 9. Una ves seleccionados, en la parte inferior de la página se generará un enlace, el cual es al que debes ir para agregar el bot a tu servidor.
> > ###### **NOTA**: Guarda el enlace para uso futuro
## Variables de entornoConstruyo las variables de entorno en el archivo ```.env``` para la configuracion de token y futuras propiedades:
> Renombrar ```.env-template``` a ```.env```
### Instalamos dependencias:
Éstas dependencias nos permitirán hacer uso de las variables de entorno:
```bash
$ yarn add @nestjs/config dotenv
```
e importamos `ConfigModule.forRoot()` en el modulo `app.module.ts`.
Código: app.module.ts
```typescript
import { Module } from '@nestjs/common';
import { ConfigModule } from "@nestjs/config";@Module({
imports: [
ConfigModule.forRoot(),
],
controllers: [],
providers: [],
})
export class AppModule {}
```Luego, importamos `NecordModule.forRoot()` y configuramos nuestra variable de entorno con el mismo nombre que se encontraba en `.env` de la siguiente manera:
````typescript
NecordModule.forRoot({
token: process.env.ENV_TOKEN_NAME,
})
````
Código: app.module.ts
```typescript
import { Module } from '@nestjs/common';
import { ConfigModule } from "@nestjs/config";
import { NecordModule } from "necord";@Module({
imports: [
ConfigModule.forRoot(),
NecordModule.forRoot({
token: process.env.DISCORD_TOKEN,
//y agregamos y guild para empezar a detectar el token y levantar bot
intents: [IntentsBitField.Flags.Guilds],
}),
],
controllers: [],
providers: [],
})
export class AppModule {}
```Una vez realizado todo lo anterior, ya podemos poner en marcha para probar por primera vez nuestro bot funcionando:
```bash
$ yarn start:dev
```> ###### NOTA:
> ###### Para los casos en que el bot no responda o funcione incorrectamente mientras hacemos pruebas, pero nuestro código está corriendo sin errores:
> ###### 1. Expulsar el bot del servidor
> ###### 2. Volver a invitarlo mediante el enlace que guardamos en un comienzo.
> > ###### Esta falla suele suceder, debido a la cache de discord. Para evitar demoras en las pruebas, la desinstalacion e instalacion del bot genera una nueva caché dejando invalidada la anterior.
>
>
>
___# Ahora comenzemos...
## Slash commandPara poder realizar los comandos de barra diagonal ( **/** ) o slash command, primero generamos un nuevo recurso:
```bash
$ nest g res slash-commands
```
Solo nos quedaremos con el **module** y **services**. (Lo demas se puede eliminar por el momento).Con el decorador `@SlashCommand()` podemos empezar a generar el primer comando de barra diagonal o 'Slash command'.
Para generarlo, deberemos ingresar algunas propiedades, principalmente `name` que hacer referencia al comando `/name`, y `description` para mostrar una descripción del comando:
```typescript
@SlashCommand({
name: 'ping',
description: 'Ping-Pong Command',
})
```
Luego, usamos el decorador ``@Context`` para enviar argumentos, en este caso ``[interaction]`` y del tipo ``SlashCommandContext`````typescript
@SlashCommand({
name: 'ping',
description: 'Ping-Pong Command',
})
public async onPing(@Context() [interaction]: SlashCommandContext){
....
}
```
Y para devolver la respuesta por mensaje, retornamos la respuesta de `[interaction]` mediante ``.reply`` añadiendo la propiedad ``content`` y el valor a retornar.```typescript
return interaction.reply({ content: 'Pong!' });
```
Código: slash-commands.service.ts
```typescript
import { Injectable } from '@nestjs/common';
import { Context,
SlashCommand,
SlashCommandContext
} from 'necord';@Injectable()
export class SlashCommandsService {@SlashCommand({
name: 'ping',
description: 'Ping-Pong Command',
})
public async onPing(@Context() [interaction]: SlashCommandContext) {
return interaction.reply({ content: 'Pong!' });
}
}
```---
## Context menusPara generar menues contextuales, tanto en usuarios ccomo mensajes, usaremos el decorador ``@UserCommand()``. Agregandole la propiedad `name:` nombraremos nuestra opcion del menu.
```typescript
@UserCommand({ name: 'Obtener avatar' })
public async getUserAvatar(
@Context() [interaction]: UserCommandContext,
...
) {
return interaction.reply({
....
});
}
```![img.png](images/images-readme/img.png)
Para esto podriamos hacer, por ejemplo un embed que nos muestre el nombre del usuario y la imagen de perfil.
1. Primero agregaremos `@TargetUser() user: User` para obtener el usuario.
2. Retornaremos, en este caso, un embed, conformado solo por el el nombre del usuario y la imagen de perfil.
```typescript
@UserCommand({ name: 'Obtener avatar' })
public async getUserAvatar(
@Context() [interaction]: UserCommandContext,
@TargetUser() user: User
) {
return interaction.reply({
embeds: [
new EmbedBuilder().setTitle(`Avatar de ${user.username}`).setImage(user.displayAvatarURL({size:4096}))
]
});
}
```>###### Puede ver más en [EmbedBuilder](https://discord.js.org/)
El resultado de este código sera de la siguiente manera:\
![img.png](images/images-readme/img2.png)---
## Components### Buttons
Para la creacion de Botones utilizamos `ButtonBuilder()`
```typescript
new ButtonBuilder()
.setCustomId('primary')
.setLabel('Primary')
.setStyle(ButtonStyle.Primary);
```
>> ###### Ver mas en: [ButtonBuilder()](https://discord.js.org/docs/packages/builders/main/ButtonBuilder:Class)
>
Luego con ``ActionRowBuilder()`` agregamos cada boton generado a una fila de botones:```typescript
const rowbuttons = new ActionRowBuilder()
.addComponents(primary, secondary, success, danger, link);
```Y luego generamos la respuesta a mostrar, colocanto el contenido y la fila de botones:
````typescript
await interaction.reply({
content: 'Selecciona un botón',
components: [rowbuttons],
});
````
Generamos un nuevo slash command ``/botones`` y se veria de la siguiente manera: \![img_1.png](images/images-readme/img3.png)
*(Imagen ejemplo del código funcional)*### String select
Para la creacion de de la lista de opciones utilizamos `StringSelectMenuBuilder()`
```typescript
new StringSelectMenuBuilder()
.setCustomId('pokemons')
.setPlaceholder('Pokemones!')
.addOptions(
new StringSelectMenuOptionBuilder()
.setLabel('Bulbasaur')
.setDescription('The dual-type Grass/Poison Seed Pokémon.')
.setValue('bulbasaur')
.setEmoji('💚'),
new StringSelectMenuOptionBuilder()
.setLabel('Charmander')
.setDescription('The Fire-type Lizard Pokémon.')
.setValue('charmander')
.setEmoji('🧡'),
new StringSelectMenuOptionBuilder()
.setLabel('Squirtle')
.setDescription('The Water-type Tiny Turtle Pokémon.')
.setValue('squirtle')
.setEmoji('💙'),
);
```
>> ###### Ver mas en:
>>[StringSelectMenuBuilder()](https://discord.js.org/docs/packages/builders/main/StringSelectMenuBuilder:Class)\
>>[StringSelectMenuOptionBuilder()](https://discord.js.org/docs/packages/builders/main/StringSelectMenuOptionBuilder:Class)Generamos un nuevo slash command ``/string-select`` y se veria de la siguiente manera:
![img.png](images/images-readme/img4.png)
![img_1.png](images/images-readme/img5.png)
*(Imagenes ejemplo del código funcional)*Vale aclarar que tambien existen otros componentes similares:
User Select
```typescript
new UserSelectMenuBuilder()
.setCustomId('USER_SELECT_MENU')
.setPlaceholder('Select a user')
.setMaxValues(1)
.setMinValues(1)
```
Role Select
```typescript
new RoleSelectMenuBuilder()
.setCustomId('ROLE_SELECT_MENU')
.setPlaceholder('Select a role')
.setMaxValues(1)
.setMinValues(1)
```
Channel Select
```typescript
new ChannelSelectMenuBuilder()
.setCustomId('CHANNEL_SELECT_MENU')
.setPlaceholder('Select a channel')
.setMaxValues(1)
.setMinValues(1)
```
Mentionable Select
```typescript
new MentionableSelectMenuBuilder()
.setCustomId('MENTIONABLE_SELECT_MENU')
.setPlaceholder('Select a user/role')
.setMaxValues(1)
.setMinValues(1)
```Pero al final, la implementación termina siendo igual a la de Buttons.
___