Make Anime and Manga use AniList

This commit is contained in:
Daniel Odendahl Jr
2018-10-30 22:34:27 +00:00
parent d0e3c668ce
commit 060b5db03b
6 changed files with 205 additions and 108 deletions
+2 -2
View File
@@ -161,6 +161,7 @@ the [home server](https://discord.gg/sbMe32W).
### Search:
* **anime:** Searches AniList for your query, getting anime results.
* **azur-lane-ship:** Responds with information on an Azur Lane ship.
* **bulbapedia:** Searches Bulbapedia for your query.
* **derpibooru:** Responds with an image from Derpibooru.
@@ -185,10 +186,9 @@ the [home server](https://discord.gg/sbMe32W).
* **jisho:** Defines a word, but with Japanese.
* **kh-wiki:** Searches the Kingdom Hearts Wiki for your query.
* **kickstarter:** Searches Kickstarter for your query.
* **kitsu-anime:** Searches Kitsu.io for your query, getting anime results.
* **kitsu-manga:** Searches Kitsu.io for your query, getting manga results.
* **know-your-meme:** Searches Know Your Meme for your query.
* **league-of-legends-champion:** Responds with information on a League of Legends champion.
* **manga:** Searches AniList for your query, getting manga results.
* **mayo-clinic:** Searches Mayo Clinic for your query.
* **mdn:** Searches MDN for your query.
* **nasa:** Searches NASA's image archive for your query.
+101
View File
@@ -0,0 +1,101 @@
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, $type: MediaType, $isAdult: Boolean) {
anime: Page (perPage: 1) {
results: media (type: $type, isAdult: $isAdult, search: $search) { id }
}
}
`;
const resultGraphQL = stripIndents`
query media($id: Int, $type: MediaType) {
Media(id: $id, type: $type) {
id
title { userPreferred }
coverImage { large }
startDate { year }
description
season
type
status
episodes
isAdult
averageScore
}
}
`;
module.exports = class AnimeCommand extends Command {
constructor(client) {
super(client, {
name: 'anime',
aliases: ['anilist-anime', 'anilist', 'mal'],
group: 'search',
memberName: 'anime',
description: 'Searches AniList for your query, getting anime results.',
clientPermissions: ['EMBED_LINKS'],
args: [
{
key: 'query',
prompt: 'What anime would you like to search for?',
type: 'string'
}
]
});
}
async run(msg, { query }) {
try {
const id = await this.search(query, msg.channel.nsfw);
if (!id) return msg.say('Could not find any results.');
const anime = await this.fetchAnime(id);
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)
.setTitle(anime.title.userPreferred)
.setDescription(shorten(anime.description))
.addField(' Type', `${anime.type} - ${anime.status}`, true)
.addField(' Episodes', anime.episodes, true)
.addField(' Season', `${anime.season} ${anime.startDate.year}`, true)
.addField(' Average Score', `${anime.averageScore}/10`, true)
.addField(' Adult?', anime.isAdult ? 'Yes' : 'No', true)
.addField(' Average Score', `${anime.averageScore}/10`, true);
return msg.embed(embed);
} catch (err) {
return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`);
}
}
async search(query, nsfw) {
const { body } = await request
.post('https://graphql.anilist.co/')
.send({
variables: {
search: query,
type: 'ANIME',
isAdult: Boolean(nsfw)
},
query: searchGraphQL
});
if (!body.data.anime.results.length) return null;
return body.data.anime.results[0].id;
}
async fetchAnime(id) {
const { body } = await request
.post('https://graphql.anilist.co/')
.send({
variables: {
id,
type: 'ANIME'
},
query: resultGraphQL
});
return body.data.Media;
}
};
-50
View File
@@ -1,50 +0,0 @@
const Command = require('../../structures/Command');
const moment = require('moment');
const { MessageEmbed } = require('discord.js');
const request = require('node-superfetch');
const { shorten, formatNumber, firstUpperCase } = require('../../util/Util');
module.exports = class KitsuAnimeCommand extends Command {
constructor(client) {
super(client, {
name: 'kitsu-anime',
aliases: ['my-anime-list-anime', 'mal-anime', 'anime'],
group: 'search',
memberName: 'kitsu-anime',
description: 'Searches Kitsu.io for your query, getting anime results.',
clientPermissions: ['EMBED_LINKS'],
args: [
{
key: 'query',
prompt: 'What anime would you like to search for?',
type: 'string'
}
]
});
}
async run(msg, { query }) {
try {
const { text } = await request
.get('https://kitsu.io/api/edge/anime')
.query({ 'filter[text]': query });
const body = JSON.parse(text);
if (!body.data.length) return msg.say('Could not find any results.');
const data = body.data[0].attributes;
const embed = new MessageEmbed()
.setColor(0xF75239)
.setAuthor('Kitsu.io', 'https://i.imgur.com/lVqooyd.png', 'https://kitsu.io/explore/anime')
.setURL(`https://kitsu.io/anime/${data.slug}`)
.setThumbnail(data.posterImage ? data.posterImage.original : null)
.setTitle(data.canonicalTitle)
.setDescription(shorten(data.synopsis))
.addField(' Type', `${firstUpperCase(data.showType)} - ${firstUpperCase(data.status)}`, true)
.addField(' Episodes', data.episodeCount ? formatNumber(data.episodeCount) : '???', true)
.addField(' Start Date', data.startDate ? moment.utc(data.startDate).format('MM/DD/YYYY') : '???', true)
.addField(' End Date', data.endDate ? moment.utc(data.endDate).format('MM/DD/YYYY') : '???', true);
return msg.embed(embed);
} catch (err) {
return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`);
}
}
};
-55
View File
@@ -1,55 +0,0 @@
const Command = require('../../structures/Command');
const moment = require('moment');
const { MessageEmbed } = require('discord.js');
const request = require('node-superfetch');
const { oneLine } = require('common-tags');
const { shorten, formatNumber, firstUpperCase } = require('../../util/Util');
module.exports = class KitsuMangaCommand extends Command {
constructor(client) {
super(client, {
name: 'kitsu-manga',
aliases: ['my-anime-list-manga', 'mal-manga', 'manga'],
group: 'search',
memberName: 'kitsu-manga',
description: 'Searches Kitsu.io for your query, getting manga results.',
clientPermissions: ['EMBED_LINKS'],
args: [
{
key: 'query',
prompt: 'What manga would you like to search for?',
type: 'string'
}
]
});
}
async run(msg, { query }) {
try {
const { text } = await request
.get('https://kitsu.io/api/edge/manga')
.query({ 'filter[text]': query });
const body = JSON.parse(text);
if (!body.data.length) return msg.say('Could not find any results.');
const data = body.data[0].attributes;
const embed = new MessageEmbed()
.setColor(0xF75239)
.setAuthor('Kitsu.io', 'https://i.imgur.com/lVqooyd.png', 'https://kitsu.io/explore/manga')
.setURL(`https://kitsu.io/manga/${data.slug}`)
.setThumbnail(data.posterImage ? data.posterImage.original : null)
.setTitle(data.canonicalTitle)
.setDescription(shorten(data.synopsis))
.addField(' Type', `${firstUpperCase(data.subtype)} - ${firstUpperCase(data.status)}`, true)
.addField(' Volumes / Chapters', oneLine`
${data.volumeCount ? formatNumber(data.volumeCount) : '???'}
/
${data.chapterCount ? formatNumber(data.chapterCount) : '???'}
`, true)
.addField(' Start Date', data.startDate ? moment.utc(data.startDate).format('MM/DD/YYYY') : '???', true)
.addField(' End Date', data.endDate ? moment.utc(data.endDate).format('MM/DD/YYYY') : '???', true);
return msg.embed(embed);
} catch (err) {
return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`);
}
}
};
+101
View File
@@ -0,0 +1,101 @@
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, $type: MediaType, $isAdult: Boolean) {
anime: Page (perPage: 1) {
results: media (type: $type, isAdult: $isAdult, search: $search) { id }
}
}
`;
const resultGraphQL = stripIndents`
query media($id: Int, $type: MediaType) {
Media(id: $id, type: $type) {
id
title { userPreferred }
coverImage { large }
startDate { year }
description
type
status
volumes
chapters
isAdult
averageScore
}
}
`;
module.exports = class MangaCommand extends Command {
constructor(client) {
super(client, {
name: 'manga',
aliases: ['anilist-manga'],
group: 'search',
memberName: 'manga',
description: 'Searches AniList for your query, getting manga results.',
clientPermissions: ['EMBED_LINKS'],
args: [
{
key: 'query',
prompt: 'What manga would you like to search for?',
type: 'string'
}
]
});
}
async run(msg, { query }) {
try {
const id = await this.search(query, msg.channel.nsfw);
if (!id) return msg.say('Could not find any results.');
const manga = await this.fetchAnime(id);
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)
.setTitle(manga.title.userPreferred)
.setDescription(shorten(manga.description))
.addField(' Type', `${manga.type} - ${manga.status}`, true)
.addField(' Chapters / Volumes', `${manga.chapters}/${manga.volumes}`, true)
.addField(' Year', manga.startDate.year, true)
.addField(' Average Score', `${manga.averageScore}/10`, true)
.addField(' Adult?', manga.isAdult ? 'Yes' : 'No', true)
.addField(' Average Score', `${manga.averageScore}/10`, true);
return msg.embed(embed);
} catch (err) {
return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`);
}
}
async search(query, nsfw) {
const { body } = await request
.post('https://graphql.anilist.co/')
.send({
variables: {
search: query,
type: 'MANGA',
isAdult: Boolean(nsfw)
},
query: searchGraphQL
});
if (!body.data.anime.results.length) return null;
return body.data.anime.results[0].id;
}
async fetchAnime(id) {
const { body } = await request
.post('https://graphql.anilist.co/')
.send({
variables: {
id,
type: 'MANGA'
},
query: resultGraphQL
});
return body.data.Media;
}
};
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "xiao",
"version": "96.2.0",
"version": "97.0.0",
"description": "Your personal server companion.",
"main": "Xiao.js",
"scripts": {