Almacenando datos con Keyv

Keyvopen in new window es un almacén simple de tipo key-value (clave-valor) que funciona con múltiples backends. Es completamente escalable para el sharding y soporta almacenamiento con JSON.

Instalación

npm install keyv
yarn add keyv
pnpm add keyv

Keyv requiere una dependencia adicional en función del backend que quieras utilizar. Si quieres guardarlo todo en tu computadora, puedes saltarte esta parte. De lo contrario, instala uno de los siguientes:

npm install @keyv/redis
npm install @keyv/mongo
npm install @keyv/sqlite
npm install @keyv/postgres
npm install @keyv/mysql
yarn add @keyv/redis
yarn add @keyv/mongo
yarn add @keyv/sqlite
yarn add @keyv/postgres
yarn add @keyv/mysql
pnpm add @keyv/redis
pnpm add @keyv/mongo
pnpm add @keyv/sqlite
pnpm add @keyv/postgres
pnpm add @keyv/mysql

Crea una instancia de Keyv una vez que hayas instalado Keyv y los controladores necesarios.

const Keyv = require('keyv');

// Uno de los siguientes
const keyv = new Keyv(); // para almacenamiento en tu computador
const keyv = new Keyv('redis://user:pass@localhost:6379');
const keyv = new Keyv('mongodb://user:pass@localhost:27017/dbname');
const keyv = new Keyv('sqlite://path/to/database.sqlite');
const keyv = new Keyv('postgresql://user:pass@localhost:5432/dbname');
const keyv = new Keyv('mysql://user:pass@localhost:3306/dbname');
1
2
3
4
5
6
7
8
9

Asegurate de gestionar errores de conexión.

keyv.on('error', err => console.error('[Keyv] Error de conexión:', err));
1

Para una configuración más detallada, consulta el archivo Keyv readmeopen in new window.

Uso

Keyv ofrece una API similar a la de Map. Sin embargo, sólo cuenta con los métodos set, get, delete y clear. Además, en lugar de devolver datos inmediatamente, estos métodos devuelven promesas que se resuelven con los datos.

(async () => {
	// true
	await keyv.set('foo', 'bar');

	// bar
	await keyv.get('foo');

	// undefined
	await keyv.clear();

	// undefined
	await keyv.get('foo');
})();
1
2
3
4
5
6
7
8
9
10
11
12
13

Aplicación

Aunque Keyv puede ayudarte en cualquier escenario en el que se necesiten datos clave-valor, nos centramos en la configuración de un prefijo por servidor utilizando Sqlite.

CONSEJO

Esta sección seguirá funcionando con cualquier proveedor compatible con Keyv. Recomendamos PostgreSQL para aplicaciones más grandes.

Configuración

const Keyv = require('keyv');
const { Client, Events, GatewayIntentBits } = require('discord.js');
const { globalPrefix, token } = require('./config.json');

const client = new Client({ intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages, GatewayIntentBits.MessageContent] });
const prefixes = new Keyv('sqlite://path/to.sqlite');
1
2
3
4
5
6

Controlador de eventos

Esta guía usa un controlador de comandos muy básico con cierta complejidad añadida para permitir múltiples prefijos. Mira la guía de manejo de comandos para un controlador de comandos más sólido.

client.on(Events.MessageCreate, async message => {
	if (message.author.bot) return;

	let args;
	// gestor de mensajes en un servidor
	if (message.guild) {
		let prefix;

		if (message.content.startsWith(globalPrefix)) {
			prefix = globalPrefix;
		} else {
			// comprueba el prefijo de nivel del servidor
			const guildPrefix = await prefixes.get(message.guild.id);
			if (message.content.startsWith(guildPrefix)) prefix = guildPrefix;
		}

		// si encontramos un prefijo, configura args; de lo contrario, no es un comando
		if (!prefix) return;
		args = message.content.slice(prefix.length).trim().split(/\s+/);
	} else {
		// gestiona mensajes directos
		const slice = message.content.startsWith(globalPrefix) ? globalPrefix.length : 0;
		args = message.content.slice(slice).split(/\s+/);
	}

	// obtiene el primer argumento delimitado por espacios después del prefijo del comando
	const command = args.shift().toLowerCase();
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

Comando con prefijo

Ahora que tienes un manejador de comandos, puedes hacer un comando para permitir que la gente use tu sistema de prefijos.

client.on(Events.MessageCreate, async message => {
	// ...
	if (command === 'prefix') {
		// si hay al menos un argumento, establece el prefijo
		if (args.length) {
			await prefixes.set(message.guild.id, args[0]);
			return message.channel.send(`Establecido con éxito el prefijo a \`${args[0]}\``);
		}

		return message.channel.send(`El prefijo es \`${await prefixes.get(message.guild.id) || globalPrefix}\``);
	}
});


 
 
 
 
 
 
 
 
 

1
2
3
4
5
6
7
8
9
10
11
12

Es probable que desee configurar una validación adicional, como los permisos requeridos y la longitud máxima del prefijo.

Usage

Usuario07/16/2023
.prefix
Bot de pruebas Bot 07/16/2023
El prefijo es .
Usuario07/16/2023
.prefix $
Bot de pruebas Bot 07/16/2023
Establecido con éxito el prefijo a $
Usuario07/16/2023
$prefix
Bot de pruebas Bot 07/16/2023
El prefijo es $

Siguientes pasos

Muchas otras aplicaciones pueden usar Keyv, como la configuración de servidores; crea otra instancia con un namepaceopen in new window diferente para cada configuración. Además, puede extenderseopen in new window para trabajar con cualquier backend de almacenamiento que prefieras.

Dale un vistazo al repositorio de Keyvopen in new window) para más información

Resultado final

Si quieres comparar tu código con el código que hemos construido hasta ahora, puedes revisarlo en el repositorio de GitHub aquí open in new window.