diff --git a/README.md b/README.md index 8cd9778f..f2b4277c 100644 --- a/README.md +++ b/README.md @@ -132,7 +132,7 @@ in the appropriate channel's topic to use it. ## Commands -Total: 385 +Total: 386 ### Utility: @@ -264,6 +264,7 @@ Total: 385 ### Events: +* **anime-airing:** Responds with a list of the anime that air today. * **apod:** Responds with today's Astronomy Picture of the Day. * **calendar:** Responds with today's holidays. * **days-until:** Responds with how many days there are until a certain date. diff --git a/commands/events/anime-airing.js b/commands/events/anime-airing.js new file mode 100644 index 00000000..7470ad43 --- /dev/null +++ b/commands/events/anime-airing.js @@ -0,0 +1,72 @@ +const Command = require('../../structures/Command'); +const request = require('node-superfetch'); +const { stripIndents } = require('common-tags'); +const moment = require('moment-timezone'); +const { today, tomorrow } = require('../../util/Util'); +const airingGraphQL = stripIndents` + query AiringSchedule($greater: Int, $lower: Int) { + anime: Page { + results: airingSchedules(airingAt_greater: $greater, airingAt_lesser: $lower) { + airingAt + media { + id + title { + english + romaji + } + } + } + } +`; + +module.exports = class AnimeAiringCommand extends Command { + constructor(client) { + super(client, { + name: 'anime-airing', + aliases: ['anichart', 'airing-anime', 'seasonal-anime', 'anime-seasonal'], + group: 'search', + memberName: 'anime-airing', + description: 'Responds with a list of the anime that air today.', + clientPermissions: ['EMBED_LINKS'], + credit: [ + { + name: 'AniList', + url: 'https://anilist.co/', + reason: 'API', + reasonURL: 'https://anilist.gitbook.io/anilist-apiv2-docs/' + } + ] + }); + } + + async run(msg) { + try { + const anime = await this.getList(); + if (!anime) return msg.say('No anime air today...'); + return msg.say(stripIndents` + **Anime Airing on ${moment().tz('Asia/Tokyo').format('dddd, MMMM Do, YYYY')}** + ${anime.map(ani => { + const title = ani.title.english || ani.title.romaji; + const airingAt = moment(ani.airingAt * 1000).tz('Asia/Tokyo').format('h:mm A'); + return `• ${title} (@${airingAt} JST)` + })} + `); + } catch (err) { + return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); + } + } + + async getList() { + const { body } = await request + .post('https://graphql.anilist.co/') + .send({ + variables: { + greater: Number.parseInt(today().getTime() / 1000, 10), + lower: Number.parseInt(tomorrow().getTime() / 1000, 10) + }, + query: airingGraphQL + }); + if (!body.data.anime.results.length) return null; + return body.data.anime.results; + } +}; diff --git a/package.json b/package.json index 3824739c..910449a3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "xiao", - "version": "113.1.1", + "version": "113.2.0", "description": "Your personal server companion.", "main": "Xiao.js", "scripts": {