diff --git a/commands/search/danbooru.js b/commands/search/danbooru.js index f5b8e956..7027003d 100644 --- a/commands/search/danbooru.js +++ b/commands/search/danbooru.js @@ -8,13 +8,14 @@ module.exports = class DanbooruCommand extends Command { aliases: ['danbooru-image'], group: 'search', memberName: 'danbooru', - description: 'Searches Danbooru for your query.', + description: 'Responds with an image from Danbooru, with optional query.', nsfw: true, args: [ { key: 'query', prompt: 'What image would you like to search for?', type: 'string', + default: '', validate: query => { if (!query.includes(' ')) return true; return 'Invalid query, please only search for one tag at a time.'; diff --git a/commands/search/deviantart.js b/commands/search/deviantart.js new file mode 100644 index 00000000..74505442 --- /dev/null +++ b/commands/search/deviantart.js @@ -0,0 +1,68 @@ +const { Command } = require('discord.js-commando'); +const snekfetch = require('snekfetch'); +const { list } = require('../../util/Util'); +const { DEVIANTART_ID, DEVIANTART_SECRET } = process.env; +const sections = ['dailydeviations', 'hot', 'newest', 'popular', 'undiscovered']; + +module.exports = class DeviantartCommand extends Command { + constructor(client) { + super(client, { + name: 'deviantart', + group: 'search', + memberName: 'deviantart', + description: 'Responds with an image from a DeviantArt section, with optional query.', + args: [ + { + key: 'section', + prompt: `What section would you like to search? Either ${list(sections, 'or')}.`, + type: 'string', + validate: section => { + if (sections.includes(section.toLowerCase())) return true; + return `Invalid section, please enter either ${list(sections), 'or'}.`; + }, + parse: section => section.toLowerCase() + }, + { + key: 'query', + prompt: 'What image would you like to search for?', + type: 'string', + default: '' + } + ] + }); + + this.token = null; + } + + async run(msg, { section, query }) { + try { + if (!this.token) await this.fetchToken(); + const { body } = await snekfetch + .get(`https://www.deviantart.com/api/v1/oauth2/browse/${section}`) + .query({ + q: query, + limit: 120, + access_token: this.token, + mature_content: msg.channel.nsfw || false + }); + const images = body.results.filter(image => image.content && image.content.src); + if (!images.length) return msg.say('Could not find any results.'); + return msg.say(images[Math.floor(Math.random() * images.length)].content.src); + } catch (err) { + return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); + } + } + + async fetchToken() { + const { body } = await snekfetch + .get('https://www.deviantart.com/oauth2/token') + .query({ + grant_type: 'client_credentials', + client_id: DEVIANTART_ID, + client_secret: DEVIANTART_SECRET + }); + this.token = body.access_token; + this.client.setTimeout(() => { this.token = null; }, body.expires_in * 1000); + return body; + } +}; diff --git a/commands/search/gelbooru.js b/commands/search/gelbooru.js index 398e1ee0..67421e05 100644 --- a/commands/search/gelbooru.js +++ b/commands/search/gelbooru.js @@ -11,13 +11,14 @@ module.exports = class GelbooruCommand extends Command { aliases: ['gelbooru-image'], group: 'search', memberName: 'gelbooru', - description: 'Searches Gelbooru for your query.', + description: 'Responds with an image from Gelbooru, with optional query.', nsfw: true, args: [ { key: 'query', prompt: 'What image would you like to search for?', - type: 'string' + type: 'string', + default: '' } ] }); @@ -31,7 +32,8 @@ module.exports = class GelbooruCommand extends Command { page: 'dapi', s: 'post', q: 'index', - tags: query + tags: query, + limit: 200 }); const body = await xml(text); const data = body.posts.post; diff --git a/commands/search/konachan.js b/commands/search/konachan.js index 09f5f883..a56532d0 100644 --- a/commands/search/konachan.js +++ b/commands/search/konachan.js @@ -8,13 +8,14 @@ module.exports = class KonachanCommand extends Command { aliases: ['konachan-image'], group: 'search', memberName: 'konachan', - description: 'Searches Konachan for your query.', + description: 'Responds with an image from Konachan, with optional query.', nsfw: true, args: [ { key: 'query', prompt: 'What image would you like to search for?', - type: 'string' + type: 'string', + default: '' } ] }); diff --git a/commands/search/safebooru.js b/commands/search/safebooru.js index 85ad4f7f..b80cf96d 100644 --- a/commands/search/safebooru.js +++ b/commands/search/safebooru.js @@ -11,12 +11,13 @@ module.exports = class SafebooruCommand extends Command { aliases: ['safebooru-image'], group: 'search', memberName: 'safebooru', - description: 'Searches Safebooru for your query.', + description: 'Responds with an image from Safebooru, with optional query.', args: [ { key: 'query', prompt: 'What image would you like to search for?', - type: 'string' + type: 'string', + default: '' } ] }); @@ -30,7 +31,8 @@ module.exports = class SafebooruCommand extends Command { page: 'dapi', s: 'post', q: 'index', - tags: query + tags: query, + limit: 200 }); const body = await xml(text); const data = body.posts.post; diff --git a/package.json b/package.json index a41422b0..5611d0e1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "xiaobot", - "version": "54.1.1", + "version": "54.2.0", "description": "Your personal server companion.", "main": "XiaoBot.js", "scripts": {