Guide discord.js
Informations supplémentaires

API REST

Les API REST sont extrêmement populaires sur le web et vous permettent de récupérer gratuitement les données d'un site s'il dispose d'une API disponible via une connexion HTTP.

Faire des requêtes HTTP avec Node

Dans ces exemples, nous utiliserons undici, une excellente bibliothèque pour faire des requêtes HTTP.

Pour installer undici, exécutez la commande suivante :

npm i install undici

Code de base

Pour commencer, vous utiliserez le code de base suivant. Puisque les deux commandes que vous ajouterez dans cette section nécessitent une interaction avec des API externes, vous reporterez la réponse, de sorte que votre application réponde avec un état "pensée...". Vous pouvez ensuite modifier la réponse une fois que vous avez les données dont vous avez besoin :

rest-examples.js
const { Client, EmbedBuilder, Events, GatewayIntentBits } = require('discord.js');

const client = new Client({ intents: [GatewayIntentBits.Guilds] });

client.once(Events.ClientReady, (readyClient) => {
	console.log(`Ready! Logged in as ${readyClient.user.tag}`);
});

client.on(Events.InteractionCreate, async (interaction) => {
	if (!interaction.isChatInputCommand()) return;

	const { commandName } = interaction;
	await interaction.deferReply();
	// ...
});

client.login('your-token-goes-here');

Nous tirons parti de la déstructuration dans ce tutoriel pour maintenir la lisibilité.

Utiliser undici

Undici est un client HTTP/1.1 basé sur Promise, écrit de zéro pour Node.js. Si vous ne connaissez pas déjà les Promises, vous devriez en lire plus ici.

Dans ce tutoriel, vous allez créer un bot avec deux commandes basées sur les API en utilisant les API random.cat et Urban Dictionary.

En haut de votre fichier, importez la fonction de bibliothèque que vous utiliserez :

const { request } = require('undici');

Chat aléatoire

Plus de chats :(

Malheureusement, l'API aws.random.cat ne fonctionne plus. Nous garderons l'exemple tel quel jusqu'à ce que nous trouvions un meilleur exemple !

L'API Random cat est disponible à https://aws.random.cat/meow et retourne une réponse JSON. Pour récupérer les données de l'API, vous allez faire ce qui suit :

const catResult = await request('https://aws.random.cat/meow');
const { file } = await catResult.body.json();

Si vous venez d'ajouter ce code, il semblera que rien ne se passe. Ce que vous ne voyez pas, c'est que vous lancez une requête au serveur random.cat, qui répond avec des données JSON. La fonction helper analyse les données de réponse en un objet JavaScript avec lequel vous pouvez travailler. L'objet aura une propriété file avec la valeur d'un lien vers une image de chat aléatoire.

Ensuite, vous implémenterez cette approche dans une commande d'application :

client.on(Events.InteractionCreate, async (interaction) => {
	// ...
	if (commandName === 'cat') {
		const catResult = await request('https://aws.random.cat/meow');
		const { file } = await catResult.body.json();
		interaction.editReply({ files: [file] });
	}
});

Voici ce qui se passe dans ce code :

  1. Votre application envoie une requête GET à random.cat.
  2. random.cat voit la requête et récupère une URL de fichier aléatoire de sa base de données.
  3. random.cat envoie alors l'URL de ce fichier en tant qu'objet JSON sous forme stringifiée qui contient un lien vers l'image.
  4. undici reçoit la réponse et vous analysez le corps en un objet JSON.
  5. Votre application attache ensuite l'image et l'envoie dans Discord.

Urban Dictionary

L'API d'Urban Dictionary est disponible à https://api.urbandictionary.com/v0/define, accepte un paramètre term et retourne une réponse JSON.

Le code suivant récupérera les données de cette api :

// ...
client.on(Events.InteractionCreate, async (interaction) => {
	// ...
	if (commandName === 'urban') {
		const term = interaction.options.getString('term');
		const query = new URLSearchParams({ term }); 

		const dictResult = await request(`https://api.urbandictionary.com/v0/define?${query}`);
		const { list } = await dictResult.body.json();
	}
});

Ici, vous utilisez la classe native URLSearchParams de JavaScript pour créer une chaîne de requête pour l'URL afin que le serveur Urban Dictionary puisse l'analyser et savoir ce que vous voulez chercher.

Si vous faisiez /urban hello world, l'URL deviendrait https://api.urbandictionary.com/v0/define?term=hello%20world puisque la chaîne "hello world" est encodée.

Vous pouvez obtenir les propriétés respectives du JSON retourné. Si vous le visualisiez dans votre navigateur, cela ressemble généralement à du charabia. Si ce n'est pas le cas, c'est super ! Si c'est le cas, vous devriez obtenir un formateur/visionneuse JSON. Si vous utilisez Chrome, JSON Formatter est l'une des extensions les plus populaires. Si vous n'utilisez pas Chrome, recherchez "JSON formatter/viewer votre navigateur" et obtenez-en un.

Maintenant, si vous regardez le JSON, vous pouvez voir qu'il a une propriété list, qui est un tableau d'objets contenant diverses définitions du terme (maximum 10). Quelque chose que vous voulez toujours faire lors de la création de commandes basées sur les API est de gérer le cas où aucun résultat n'est disponible. Donc, si vous jetez un terme aléatoire dedans (par exemple njaksdcas) et que vous regardez la réponse, le tableau list devrait être vide. Maintenant, vous êtes prêt à commencer à écrire !

Comme expliqué ci-dessus, vous voulez vérifier si l'API a retourné des réponses pour votre requête, et renvoyer la définition si c'est le cas :

if (commandName === 'urban') {
	// ...
	if (!list.length) {
		return interaction.editReply(`Aucun résultat trouvé pour **${term}**.`);
	}

	interaction.editReply(`**${term}**: ${list[0].definition}`);
}

Ici, vous ne récupérez que le premier objet du tableau d'objets appelé list et récupérez sa propriété definition.

Si vous avez suivi le tutoriel, vous devriez avoir quelque chose comme ceci :

Maintenant, vous pouvez le faire un embed pour un formatage plus facile.

Vous pouvez définir la fonction helper suivante en haut de votre fichier. Dans le code ci-dessous, vous pouvez utiliser cette fonction pour tronquer les données retournées et vous assurer que l'embed ne génère pas d'erreur, car les valeurs des champs dépassent 1024 caractères.

const trim = (str, max) => (str.length > max ? `${str.slice(0, max - 3)}...` : str);

Et voici comment vous pouvez construire l'embed à partir des données de l'API :

const [answer] = list;

const embed = new EmbedBuilder()
	.setColor(0xefff00)
	.setTitle(answer.word)
	.setURL(answer.permalink)
	.addFields(
		{ name: 'Définition', value: trim(answer.definition, 1_024) },
		{ name: 'Exemple', value: trim(answer.example, 1_024) },
		{ name: 'Évaluation', value: `${answer.thumbs_up} pouces levés. ${answer.thumbs_down} pouces baissés.` },
	);

interaction.editReply({ embeds: [embed] });

Découvrez les composants d'affichage pour une approche plus récente du formatage des messages ! Vous pouvez lire la section composants d'affichage de ce guide pour en savoir plus sur leur utilisation !