mirror of
https://github.com/arthur-pbty/xiao.git
synced 2026-06-12 15:57:43 +02:00
Make Anime and Manga use AniList
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
};
|
||||
@@ -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!`);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -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!`);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -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
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "xiao",
|
||||
"version": "96.2.0",
|
||||
"version": "97.0.0",
|
||||
"description": "Your personal server companion.",
|
||||
"main": "Xiao.js",
|
||||
"scripts": {
|
||||
|
||||
Reference in New Issue
Block a user