diff --git a/Xiao.js b/Xiao.js index ff75a328..b8579586 100644 --- a/Xiao.js +++ b/Xiao.js @@ -154,6 +154,18 @@ client.on('message', async msg => { const hasEmbed = msg.embeds.length !== 0; if (msg.author.bot || (!hasText && !hasImage && !hasEmbed)) return; if (client.blacklist.user.includes(msg.author.id)) return; + + // Cleverbot handler + const cleverbot = client.cleverbots.get(msg.channel.id); + if (cleverbot) { + if (!hasText) return; + if (!cleverbot.shouldRespond(msg)) return; + const response = await cleverbot.respond(msg.cleanContent); + await msg.reply(response); + return; + } + + // Phone message handler const origin = client.phone.find(call => call.origin.id === msg.channel.id); const recipient = client.phone.find(call => call.recipient.id === msg.channel.id); if (!origin && !recipient) return; diff --git a/commands/other/cleverbot-end.js b/commands/other/cleverbot-end.js new file mode 100644 index 00000000..d28ef4d6 --- /dev/null +++ b/commands/other/cleverbot-end.js @@ -0,0 +1,21 @@ +const Command = require('../../structures/Command'); + +module.exports = class CleverbotEndCommand extends Command { + constructor(client) { + super(client, { + name: 'cleverbot-end', + aliases: ['clevs-end', 'chat-end'], + group: 'other', + memberName: 'cleverbot-end', + description: 'Ends the current Cleverbot chat.' + }); + } + + run(msg) { + if (!this.client.cleverbots.has(msg.channel.id)) { + return msg.say('There is not a Cleverbot conversation in this channel.'); + } + this.client.cleverbots.delete(msg.channel.id); + return msg.reply('Ended the current conversation.'); + } +}; diff --git a/commands/other/cleverbot.js b/commands/other/cleverbot.js index 3a53187b..a718d8ca 100644 --- a/commands/other/cleverbot.js +++ b/commands/other/cleverbot.js @@ -1,7 +1,5 @@ const Command = require('../../structures/Command'); -const request = require('node-superfetch'); -const { CLEVERBOT_KEY } = process.env; -const blankResponses = ['What?', 'Huh?', 'I don\'t understand.', 'Speak up, please.']; +const { stripIndents } = require('common-tags'); module.exports = class CleverbotCommand extends Command { constructor(client) { @@ -10,9 +8,7 @@ module.exports = class CleverbotCommand extends Command { aliases: ['clevs', 'chat'], group: 'other', memberName: 'cleverbot', - description: 'Talk to Cleverbot.', - details: 'Only the bot owner(s) may use this command.', - ownerOnly: true, + description: 'Starts a Cleverbot conversation.', credit: [ { name: 'Cleverbot', @@ -20,35 +16,18 @@ module.exports = class CleverbotCommand extends Command { reason: 'API', reasonURL: 'https://www.cleverbot.com/api/' } - ], - args: [ - { - key: 'text', - prompt: 'What do you want to say to Cleverbot?', - type: 'string' - } ] }); - - this.convos = new Map(); } - async run(msg, { text }) { - try { - const convo = this.convos.get(msg.channel.id); - const { body } = await request - .get('https://www.cleverbot.com/getreply') - .query({ - key: CLEVERBOT_KEY, - cs: convo ? convo.cs : '', - input: text - }); - if (convo) clearTimeout(convo.timeout); - const timeout = setTimeout(() => this.convos.delete(msg.channel.id), 600000); - this.convos.set(msg.channel.id, { cs: body.cs, timeout }); - return msg.reply(body.output || blankResponses[Math.floor(Math.random() * blankResponses.length)]); - } catch (err) { - return msg.reply(`Oh no, an error occurred: \`${err.message}\`. Try again later!`); + run(msg) { + if (this.client.cleverbots.has(msg.channel.id)) { + return msg.say('There is already a Cleverbot conversation in this channel.'); } + const usage = this.client.registry.commands.get('cleverbot-end').usage(); + return msg.reply(stripIndents` + Cleverbot is now active in this channel, replying to ${msg.author}. + To end the conversation, use ${usage}. + `); } }; diff --git a/package.json b/package.json index 356484dd..627fa5ca 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "xiao", - "version": "131.4.0", + "version": "131.5.0", "description": "Your personal server companion.", "main": "Xiao.js", "scripts": { diff --git a/structures/Cleverbot.js b/structures/Cleverbot.js new file mode 100644 index 00000000..0f74c8ba --- /dev/null +++ b/structures/Cleverbot.js @@ -0,0 +1,49 @@ +const request = require('node-superfetch'); +const { CLEVERBOT_KEY } = process.env; +const blankResponses = ['What?', 'Huh?', 'I don\'t understand.', 'Speak up, please.']; + +module.exports = class Cleverbot { + constructor(client, channelID, authorID, key = CLEVERBOT_KEY) { + Object.defineProperty(this, 'client', { value: client }); + + this.channelID = channelID; + this.authorID = authorID; + this.cs = null; + this.timeout = this.setTimeout(); + this.key = key; + } + + async respond(input) { + const { body } = await request + .get('https://www.cleverbot.com/getreply') + .query({ + key: this.key, + cs: this.cs || '', + input + }); + clearTimeout(this.timeout); + this.timeout = this.setTimeout(); + this.cs = body.cs; + return body.output || blankResponses[Math.floor(Math.random() * blankResponses.length)]; + } + + shouldRespond(msg) { + return msg.channel.id === this.channelID && msg.author.id === this.authorID; + } + + setTimeout() { + return setTimeout(() => { + this.manager.delete(this.channelID); + if (!this.channel) return; + this.channel.send('Conversation timed out.').catch(() => null); + }, 600000); + } + + get channel() { + return this.client.channels.cache.get(channelID); + } + + get author() { + return this.client.users.cache.get(authorID); + } +}; diff --git a/structures/Client.js b/structures/Client.js index 2b1f50c4..5311053f 100644 --- a/structures/Client.js +++ b/structures/Client.js @@ -39,6 +39,7 @@ module.exports = class XiaoClient extends CommandoClient { this.pokemon = new PokemonStore(); this.games = new Collection(); this.dispatchers = new Map(); + this.cleverbots = new Map(); this.phone = new PhoneManager(this); this.activities = activities; this.leaveMessages = leaveMsgs;