235 lines
6.2 KiB
TypeScript
235 lines
6.2 KiB
TypeScript
import { ApplyOptions } from '@sapphire/decorators';
|
|
import { Command } from '@sapphire/framework';
|
|
import { PaginatedMessage } from '@sapphire/discord.js-utilities';
|
|
import { env } from '../../env';
|
|
import axios from 'axios';
|
|
|
|
@ApplyOptions<Command.Options>({
|
|
name: 'game-search',
|
|
description: 'Search for video game information',
|
|
preconditions: ['isCommandDisabled']
|
|
})
|
|
export class ChuckNorrisCommand extends Command {
|
|
public override registerApplicationCommands(registry: Command.Registry) {
|
|
registry.registerChatInputCommand(builder =>
|
|
builder
|
|
.setName(this.name)
|
|
.setDescription(this.description)
|
|
.addStringOption(option =>
|
|
option
|
|
.setName('game')
|
|
.setDescription('The game you want to look up?')
|
|
.setRequired(true)
|
|
)
|
|
);
|
|
}
|
|
|
|
public override async chatInputRun(
|
|
interaction: Command.ChatInputCommandInteraction
|
|
) {
|
|
if (!env.RAWG_API) {
|
|
return interaction.reply({
|
|
content: 'This command is disabled because the RAWG API key is not set.'
|
|
});
|
|
}
|
|
|
|
const title = interaction.options.getString('game', true);
|
|
const filteredTitle = this.filterTitle(title);
|
|
|
|
const game = await this.getGameDetails(filteredTitle);
|
|
|
|
if (!game) {
|
|
return interaction.reply({
|
|
content: 'No game found with that name'
|
|
});
|
|
}
|
|
|
|
const PaginatedEmbed = new PaginatedMessage();
|
|
|
|
const firstPageTuple: string[] = []; // releaseDate, esrbRating, userRating
|
|
|
|
if (game.tba) {
|
|
firstPageTuple.push('TBA');
|
|
} else if (!game.released) {
|
|
firstPageTuple.push('None Listed');
|
|
} else {
|
|
firstPageTuple.push(game.released);
|
|
}
|
|
|
|
if (!game.esrb_rating) {
|
|
firstPageTuple.push('None Listed');
|
|
} else {
|
|
firstPageTuple.push(game.esrb_rating.name);
|
|
}
|
|
|
|
if (!game.rating) {
|
|
firstPageTuple.push('None Listed');
|
|
} else {
|
|
firstPageTuple.push(game.rating + '/5');
|
|
}
|
|
|
|
PaginatedEmbed.addPageEmbed(embed =>
|
|
embed
|
|
.setTitle(`Game Info: ${game.name}`)
|
|
.setDescription(
|
|
'>>> ' +
|
|
'**Game Description**\n' +
|
|
game.description_raw.slice(0, 2000) +
|
|
'...'
|
|
)
|
|
.setColor('Grey')
|
|
.setThumbnail(game.background_image)
|
|
.addFields(
|
|
{ name: 'Released', value: '> ' + firstPageTuple[0], inline: true },
|
|
{
|
|
name: 'ESRB Rating',
|
|
value: '> ' + firstPageTuple[1],
|
|
inline: true
|
|
},
|
|
{ name: 'Score', value: '> ' + firstPageTuple[2], inline: true }
|
|
)
|
|
.setTimestamp()
|
|
);
|
|
|
|
const developerArray: string[] = [];
|
|
if (game.developers.length) {
|
|
for (let i = 0; i < game.developers.length; ++i) {
|
|
developerArray.push(game.developers[i].name);
|
|
}
|
|
} else {
|
|
developerArray.push('None Listed');
|
|
}
|
|
|
|
const publisherArray: string[] = [];
|
|
if (game.publishers.length) {
|
|
for (let i = 0; i < game.publishers.length; ++i) {
|
|
publisherArray.push(game.publishers[i].name);
|
|
}
|
|
} else {
|
|
publisherArray.push('None Listed');
|
|
}
|
|
|
|
const platformArray: string[] = [];
|
|
if (game.platforms.length) {
|
|
for (let i = 0; i < game.platforms.length; ++i) {
|
|
platformArray.push(game.platforms[i].platform.name);
|
|
}
|
|
} else {
|
|
platformArray.push('None Listed');
|
|
}
|
|
|
|
const genreArray: string[] = [];
|
|
if (game.genres.length) {
|
|
for (let i = 0; i < game.genres.length; ++i) {
|
|
genreArray.push(game.genres[i].name);
|
|
}
|
|
} else {
|
|
genreArray.push('None Listed');
|
|
}
|
|
|
|
const retailerArray: string[] = [];
|
|
if (game.stores.length) {
|
|
for (let i = 0; i < game.stores.length; ++i) {
|
|
retailerArray.push(
|
|
`[${game.stores[i].store.name}](${game.stores[i].url})`
|
|
);
|
|
}
|
|
} else {
|
|
retailerArray.push('None Listed');
|
|
}
|
|
|
|
PaginatedEmbed.addPageEmbed(embed =>
|
|
embed
|
|
.setTitle(`Game Info: ${game.name}`)
|
|
.setColor('Grey')
|
|
.setThumbnail(game.background_image_additional ?? game.background_image)
|
|
// Row 1
|
|
.addFields(
|
|
{
|
|
name: developerArray.length == 1 ? 'Developer' : 'Developers',
|
|
value: '> ' + developerArray.toString().replace(/,/g, ', '),
|
|
inline: true
|
|
},
|
|
{
|
|
name: publisherArray.length == 1 ? 'Publisher' : 'Publishers',
|
|
value: '> ' + publisherArray.toString().replace(/,/g, ', '),
|
|
inline: true
|
|
},
|
|
{
|
|
name: platformArray.length == 1 ? 'Platform' : 'Platforms',
|
|
value: '> ' + platformArray.toString().replace(/,/g, ', '),
|
|
inline: true
|
|
}
|
|
)
|
|
// Row 2
|
|
.addFields(
|
|
{
|
|
name: genreArray.length == 1 ? 'Genre' : 'Genres',
|
|
value: '> ' + genreArray.toString().replace(/,/g, ', '),
|
|
inline: true
|
|
},
|
|
{
|
|
name: retailerArray.length == 1 ? 'Retailer' : 'Retailers',
|
|
value:
|
|
'> ' +
|
|
retailerArray.toString().replace(/,/g, ', ').replace(/`/g, '')
|
|
}
|
|
)
|
|
.setTimestamp()
|
|
);
|
|
if (PaginatedEmbed.actions.size > 0)
|
|
PaginatedEmbed.actions.delete('@sapphire/paginated-messages.goToPage');
|
|
return PaginatedEmbed.run(interaction);
|
|
}
|
|
|
|
private filterTitle(title: string) {
|
|
return title.replace(/ /g, '-').replace(/' /g, '').toLowerCase();
|
|
}
|
|
|
|
private getGameDetails(query: string): Promise<any> {
|
|
return new Promise(async function (resolve, reject) {
|
|
const url = `https://api.rawg.io/api/games/${encodeURIComponent(
|
|
query
|
|
)}?key=${env.RAWG_API}`;
|
|
try {
|
|
const response = await axios.get(url);
|
|
if (response.status === 429) {
|
|
reject(':x: Rate Limit exceeded. Please try again in a few minutes.');
|
|
}
|
|
if (response.status === 503) {
|
|
reject(
|
|
':x: The service is currently unavailable. Please try again later.'
|
|
);
|
|
}
|
|
if (response.status === 404) {
|
|
reject(`:x: Error: ${query} was not found`);
|
|
}
|
|
if (response.status !== 200) {
|
|
reject(
|
|
':x: There was a problem getting game from the API, make sure you entered a valid game tittle'
|
|
);
|
|
}
|
|
|
|
let body = response.data;
|
|
if (body.redirect) {
|
|
const redirect = await axios.get(
|
|
`https://api.rawg.io/api/games/${body.slug}?key=${env.RAWG_API}`
|
|
);
|
|
body = redirect.data;
|
|
}
|
|
// 'id' is the only value that must be present to all valid queries
|
|
if (!body.id) {
|
|
reject(
|
|
':x: There was a problem getting data from the API, make sure you entered a valid game title'
|
|
);
|
|
}
|
|
resolve(body);
|
|
} catch (e) {
|
|
reject(
|
|
'There was a problem getting data from the API, make sure you entered a valid game title'
|
|
);
|
|
}
|
|
});
|
|
}
|
|
}
|