diff --git a/README.md b/README.md index 9492f717..227e3350 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ Xiao is a Discord bot coded in JavaScript with 300 commands, she is one of the most feature-filled bots out there, and formerly served over 10,000 servers with a uniquely devoted fanbase. -## Commands (305) +## Commands (311) ### Utility: * **prefix**: Shows or sets the command prefix. @@ -327,6 +327,14 @@ served over 10,000 servers with a uniquely devoted fanbase. * **roman-numeral**: Converts a number to roman numerals. * **units**: Converts units to/from other units. +### Server Tags: +* **tag**: Responds with a tag in this server. +* **tag-add**: Adds a tag for this server. +* **tag-edit**: Edits a tag in this server. +* **tag-info**: Responds with detailed information on a tag in this server. +* **tag-remove**: Removes a tag for this server. +* **tag-source**: Responds with the base markdown of a tag in this server. + ### Role Management: * **add-open-role**: Sets a role as open. diff --git a/Xiao.js b/Xiao.js index 72d5a6f8..a61a124a 100644 --- a/Xiao.js +++ b/Xiao.js @@ -31,6 +31,7 @@ client.registry ['avatar-edit', 'Avatar Manipulation'], ['text-edit', 'Text Manipulation'], ['number-edit', 'Number Manipulation'], + ['tags', 'Server Tags'], ['role-manage', 'Role Management'], ['portal', 'Portal Messages'], ['other', 'Other'], diff --git a/commands/tags/add.js b/commands/tags/add.js new file mode 100644 index 00000000..3971d05d --- /dev/null +++ b/commands/tags/add.js @@ -0,0 +1,42 @@ +const { Command } = require('discord.js-commando'); +const Tag = require('../../models/Tag'); + +module.exports = class TagAddCommand extends Command { + constructor(client) { + super(client, { + name: 'tag-add', + aliases: ['add-tag'], + group: 'tags', + memberName: 'add', + description: 'Adds a tag for this server.', + guildOnly: true, + args: [ + { + key: 'id', + prompt: 'What should the ID of the tag be?', + type: 'string', + max: 50, + parse: id => id.toLowerCase() + }, + { + key: 'text', + prompt: 'What should the content of the tag be?', + type: 'string', + max: 1000 + } + ] + }); + } + + async run(msg, { id, text }) { + const tag = await Tag.findOne({ where: { id, guildID: msg.guild.id } }); + if (tag) return msg.reply(`A tag with the ID **${id}** already exists.`); + await Tag.create({ + userID: msg.author.id, + guildID: msg.guild.id, + id, + text + }); + return msg.reply(`Added the tag **${id}**.`); + } +}; diff --git a/commands/tags/edit.js b/commands/tags/edit.js new file mode 100644 index 00000000..c33c36e3 --- /dev/null +++ b/commands/tags/edit.js @@ -0,0 +1,40 @@ +const { Command } = require('discord.js-commando'); +const Tag = require('../../models/Tag'); + +module.exports = class TagEditCommand extends Command { + constructor(client) { + super(client, { + name: 'tag-edit', + aliases: ['edit-tag'], + group: 'tags', + memberName: 'edit', + description: 'Edits a tag in this server.', + guildOnly: true, + args: [ + { + key: 'id', + prompt: 'What is the ID of the tag you want to edit?', + type: 'string', + max: 50, + parse: id => id.toLowerCase() + }, + { + key: 'text', + prompt: 'What should the new content of the tag be?', + type: 'string', + max: 1000 + } + ] + }); + } + + async run(msg, { id, text }) { + const tag = await Tag.findOne({ where: { id, guildID: msg.guild.id } }); + if (!tag) return msg.reply(`A tag with the ID **${id}** doesn\'t exist.`); + if (!msg.channel.permissionsFor(msg.author).has('MANAGE_MESSAGES') && tag.userID !== msg.author.id) { + return msg.reply('You can only edit your own tags.'); + } + await Tag.update({ text }, { where: { id, guild: msg.guild.id } }); + return msg.reply(`Edited the tag **${id}**.`); + } +}; diff --git a/commands/tags/info.js b/commands/tags/info.js new file mode 100644 index 00000000..96af9146 --- /dev/null +++ b/commands/tags/info.js @@ -0,0 +1,45 @@ +const { Command } = require('discord.js-commando'); +const { MessageEmbed } = require('discord.js'); +const Tag = require('../../models/Tag'); + +module.exports = class TagInfoCommand extends Command { + constructor(client) { + super(client, { + name: 'tag-info', + group: 'tags', + memberName: 'info', + description: 'Responds with detailed information on a tag in this server.', + guildOnly: true, + clientPermissions: ['EMBED_LINKS'], + args: [ + { + key: 'id', + prompt: 'What is the ID of the tag you want to get information on?', + type: 'string', + max: 50, + parse: id => id.toLowerCase() + } + ] + }); + } + + async run(msg, { id }) { + const tag = await Tag.findOne({ where: { id, guildID: msg.guild.id } }); + if (!tag) return msg.reply(`A tag with the ID **${id}** doesn\'t exist.`); + let author; + try { + const authorUser = await this.client.users.fetch(tag.userID); + author = authorUser.tag; + } catch (err) { + author = '???'; + } + const embed = new MessageEmbed() + .setColor(0x00AE86) + .setThumbnail(msg.guild.iconURL()) + .addField('❯ ID', tag.id, true) + .addField('❯ Author', author, true) + .addField('❯ Created On', new Date(tag.createdAt).toDateString(), true) + .addField('❯ Modified On', new Date(tag.updatedAt).toDateString(), true); + return msg.embed(embed); + } +}; diff --git a/commands/tags/remove.js b/commands/tags/remove.js new file mode 100644 index 00000000..3d084576 --- /dev/null +++ b/commands/tags/remove.js @@ -0,0 +1,34 @@ +const { Command } = require('discord.js-commando'); +const Tag = require('../../models/Tag'); + +module.exports = class TagRemoveCommand extends Command { + constructor(client) { + super(client, { + name: 'tag-remove', + aliases: ['tag-delete', 'remove-tag', 'delete-tag'], + group: 'tags', + memberName: 'remove', + description: 'Removes a tag for this server.', + guildOnly: true, + args: [ + { + key: 'id', + prompt: 'What is the ID of the tag you want to remove?', + type: 'string', + max: 50, + parse: id => id.toLowerCase() + } + ] + }); + } + + async run(msg, { id }) { + const tag = await Tag.findOne({ where: { id, guildID: msg.guild.id } }); + if (!tag) return msg.reply(`A tag with the ID **${id}** doesn\'t exist.`); + if (!msg.channel.permissionsFor(msg.author).has('MANAGE_MESSAGES') && tag.userID !== msg.author.id) { + return msg.reply('You can only delete your own tags.'); + } + await tag.destroy(); + return msg.reply(`Removed the tag **${id}**.`); + } +}; diff --git a/commands/tags/source.js b/commands/tags/source.js new file mode 100644 index 00000000..db29fc6e --- /dev/null +++ b/commands/tags/source.js @@ -0,0 +1,29 @@ +const { Command } = require('discord.js-commando'); +const Tag = require('../../models/Tag'); + +module.exports = class TagSourceCommand extends Command { + constructor(client) { + super(client, { + name: 'tag-source', + group: 'tags', + memberName: 'source', + description: 'Responds with the base markdown of a tag in this server.', + guildOnly: true, + args: [ + { + key: 'id', + prompt: 'What is the ID of the tag you want view the source of?', + type: 'string', + max: 50, + parse: id => id.toLowerCase() + } + ] + }); + } + + async run(msg, { id }) { + const tag = await Tag.findOne({ where: { id, guildID: msg.guild.id } }); + if (!tag) return msg.reply(`A tag with the ID **${id}** doesn\'t exist.`); + return msg.code('md', tag.text); + } +}; diff --git a/commands/tags/tag.js b/commands/tags/tag.js new file mode 100644 index 00000000..d00abee1 --- /dev/null +++ b/commands/tags/tag.js @@ -0,0 +1,29 @@ +const { Command } = require('discord.js-commando'); +const Tag = require('../../models/Tag'); + +module.exports = class TagCommand extends Command { + constructor(client) { + super(client, { + name: 'tag', + group: 'tags', + memberName: 'tag', + description: 'Responds with a tag in this server.', + guildOnly: true, + args: [ + { + key: 'id', + prompt: 'What is the ID of the tag you want view?', + type: 'string', + max: 50, + parse: id => id.toLowerCase() + } + ] + }); + } + + async run(msg, { id }) { + const tag = await Tag.findOne({ where: { id, guildID: msg.guild.id } }); + if (!tag) return msg.reply(`A tag with the ID **${id}** doesn\'t exist.`); + return msg.say(tag.text); + } +}; diff --git a/models/Tag.js b/models/Tag.js new file mode 100644 index 00000000..c405a7e3 --- /dev/null +++ b/models/Tag.js @@ -0,0 +1,23 @@ +const Sequelize = require('sequelize'); +const Database = require('../structures/PostgreSQL'); + +const Tag = Database.db.define('tag', { + userID: { + type: Sequelize.STRING, + allowNull: false + }, + guildID: { + type: Sequelize.STRING, + allowNull: false + }, + text: { + type: Sequelize.STRING, + allowNull: false + }, + id: { + type: Sequelize.STRING, + allowNull: false + } +}, { timestamps: true }); + +module.exports = Tag; diff --git a/package.json b/package.json index 75cd66be..48964cc8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "xiao", - "version": "73.1.1", + "version": "73.2.0", "description": "Your personal server companion.", "main": "Xiao.js", "scripts": {