Character command, tons of anilist command improvements

This commit is contained in:
Daniel Odendahl Jr
2019-02-16 02:14:31 +00:00
parent 54fdd30c3d
commit 75fe841d83
5 changed files with 147 additions and 18 deletions
+2 -1
View File
@@ -47,7 +47,7 @@ Xiao is a Discord bot coded in JavaScript with
7. Run `npm i -g pm2` to install PM2.
8. Run `pm2 start Xiao.js --name xiao` to run the bot.
## Commands (333)
## Commands (334)
### Utility:
* **eval:** Executes JavaScript code.
@@ -159,6 +159,7 @@ Xiao is a Discord bot coded in JavaScript with
* **azur-lane:** Responds with information on an Azur Lane ship.
* **book:** Searches Google Books for a book.
* **bulbapedia:** Searches Bulbapedia for your query.
* **character:** Searches AniList for your query, getting character results.
* **danbooru:** Responds with an image from Danbooru, with optional query.
* **define:** Defines a word.
* **derpibooru:** Responds with an image from Derpibooru.
+25 -9
View File
@@ -18,11 +18,15 @@ const resultGraphQL = stripIndents`
english
userPreferred
}
coverImage { large }
coverImage {
large
medium
}
startDate { year }
description
description(asHtml: false)
season
type
siteUrl
status
episodes
isAdult
@@ -30,6 +34,18 @@ const resultGraphQL = stripIndents`
}
}
`;
const seasons = {
WINTER: 'Winter',
SPRING: 'Spring',
SUMMER: 'Summer',
FALL: 'Fall'
};
const statuses = {
FINISHED: 'Finished',
RELEASING: 'Releasing',
NOT_YET_RELEASED: 'Unreleased',
CANCELLED: 'Cancelled'
};
module.exports = class AnimeCommand extends Command {
constructor(client) {
@@ -58,14 +74,14 @@ module.exports = class AnimeCommand extends Command {
const embed = new MessageEmbed()
.setColor(0x02A9FF)
.setAuthor('AniList', 'https://i.imgur.com/iUIRC7v.png', 'https://anilist.co/')
.setURL(`https://anilist.co/anime/${anime.id}`)
.setThumbnail(anime.coverImage.large || null)
.setURL(anime.siteUrl)
.setThumbnail(anime.coverImage.large || anime.coverImage.medium || null)
.setTitle(anime.title.english || anime.title.userPreferred)
.setDescription(anime.description ? shorten(anime.description.replace(/(<br>)+/g, '\n')) : 'No description.')
.addField(' Status', anime.status, true)
.addField(' Episodes', anime.episodes, true)
.addField(' Season', `${anime.season} ${anime.startDate.year}`, true)
.addField(' Average Score', `${anime.meanScore}/100`, true);
.setDescription(anime.description ? shorten(anime.description) : 'No description.')
.addField(' Status', statuses[anime.status], true)
.addField(' Episodes', anime.episodes || '???', true)
.addField(' Season', anime.season ? `${seasons[anime.season]} ${anime.startDate.year}` : '???', true)
.addField(' Average Score', anime.meanScore ? `${anime.meanScore}/100` : '???', true);
return msg.embed(embed);
} catch (err) {
return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`);
+105
View File
@@ -0,0 +1,105 @@
const Command = require('../../structures/Command');
const { MessageEmbed } = require('discord.js');
const request = require('node-superfetch');
const { stripIndents } = require('common-tags');
const { shorten } = require('../../util/Util');
const searchGraphQL = stripIndents`
query ($search: String) {
characters: Page (perPage: 1) {
results: characters (search: $search) { id }
}
}
`;
const resultGraphQL = stripIndents`
query ($id: Int!) {
Character (id: $id) {
id
name { native }
image {
large
medium
}
description(asHtml: false)
siteUrl
media(page: 1, perPage: 10) {
edges {
node {
title {
english
userPreferred
}
type
siteUrl
}
}
}
}
}
`;
const types = {
ANIME: 'Anime',
MANGA: 'Manga'
};
module.exports = class CharacterCommand extends Command {
constructor(client) {
super(client, {
name: 'character',
aliases: ['anilist-character', 'anime-character', 'manga-character', 'manga-char', 'ani-char', 'char'],
group: 'search',
memberName: 'character',
description: 'Searches AniList for your query, getting character results.',
clientPermissions: ['EMBED_LINKS'],
args: [
{
key: 'query',
prompt: 'What character would you like to search for?',
type: 'string'
}
]
});
}
async run(msg, { query }) {
try {
const id = await this.search(query);
if (!id) return msg.say('Could not find any results.');
const character = await this.fetchCharacter(id);
const embed = new MessageEmbed()
.setColor(0x02A9FF)
.setAuthor('AniList', 'https://i.imgur.com/iUIRC7v.png', 'https://anilist.co/')
.setURL(character.siteUrl)
.setThumbnail(character.image.large || character.image.medium || null)
.setTitle(character.name.native)
.setDescription(character.description ? shorten(character.description) : 'No description.')
.addField(' Appearances', character.edges.map(edge => {
const title = edge.node.title.english || edge.node.title.userPreferred;
return `[${title} (${types[edge.node.type]})](${edge.node.siteUrl})`;
}).join(', '));
return msg.embed(embed);
} catch (err) {
return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`);
}
}
async search(query) {
const { body } = await request
.post('https://graphql.anilist.co/')
.send({
variables: { search: query },
query: searchGraphQL
});
if (!body.data.characters.results.length) return null;
return body.data.characters.results[0].id;
}
async fetchCharacter(id) {
const { body } = await request
.post('https://graphql.anilist.co/')
.send({
variables: { id },
query: resultGraphQL
});
return body.data.Character;
}
};
+14 -7
View File
@@ -20,7 +20,8 @@ const resultGraphQL = stripIndents`
}
coverImage { large }
startDate { year }
description
description(asHtml: false)
siteUrl
type
status
volumes
@@ -30,6 +31,12 @@ const resultGraphQL = stripIndents`
}
}
`;
const statuses = {
FINISHED: 'Finished',
RELEASING: 'Releasing',
NOT_YET_RELEASED: 'Unreleased',
CANCELLED: 'Cancelled'
};
module.exports = class MangaCommand extends Command {
constructor(client) {
@@ -58,14 +65,14 @@ module.exports = class MangaCommand extends Command {
const embed = new MessageEmbed()
.setColor(0x02A9FF)
.setAuthor('AniList', 'https://i.imgur.com/iUIRC7v.png', 'https://anilist.co/')
.setURL(`https://anilist.co/manga/${manga.id}`)
.setThumbnail(manga.coverImage.large || null)
.setURL(manga.siteUrl)
.setThumbnail(manga.coverImage.large || manga.coverImage.medium || null)
.setTitle(manga.title.english || manga.title.userPreferred)
.setDescription(manga.description ? shorten(manga.description.replace(/(<br>)+/g, '\n')) : 'No description.')
.addField(' Status', manga.status, true)
.setDescription(manga.description ? shorten(manga.description) : 'No description.')
.addField(' Status', statuses[manga.status], true)
.addField(' Chapters / Volumes', `${manga.chapters || '???'}/${manga.volumes || '???'}`, true)
.addField(' Year', manga.startDate.year, true)
.addField(' Average Score', `${manga.meanScore}/100`, true);
.addField(' Year', manga.startDate.year || '???', true)
.addField(' Average Score', manga.meanScore ? `${manga.meanScore}/100` : '???', true);
return msg.embed(embed);
} catch (err) {
return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`);
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "xiao",
"version": "101.2.1",
"version": "101.3.0",
"description": "Your personal server companion.",
"main": "Xiao.js",
"scripts": {