diff --git a/backend/src/plugins/Utility/UtilityPlugin.ts b/backend/src/plugins/Utility/UtilityPlugin.ts index e2ba30b0..db17931e 100644 --- a/backend/src/plugins/Utility/UtilityPlugin.ts +++ b/backend/src/plugins/Utility/UtilityPlugin.ts @@ -37,6 +37,7 @@ import { TimeAndDatePlugin } from "../TimeAndDate/TimeAndDatePlugin"; import { VcdisconnectCmd } from "./commands/VcdisconnectCmd"; import { ModActionsPlugin } from "../ModActions/ModActionsPlugin"; import { refreshMembersIfNeeded } from "./refreshMembers"; +import { RoleInfoCmd } from "./commands/RoleInfoCmd"; const defaultOptions: PluginOptions = { config: { @@ -50,6 +51,7 @@ const defaultOptions: PluginOptions = { can_channelinfo: false, can_messageinfo: false, can_userinfo: false, + can_roleinfo: false, can_snowflake: false, can_reload_guild: false, can_nickname: false, @@ -79,6 +81,7 @@ const defaultOptions: PluginOptions = { can_channelinfo: true, can_messageinfo: true, can_userinfo: true, + can_roleinfo: true, can_snowflake: true, can_nickname: true, can_vcmove: true, @@ -138,6 +141,7 @@ export const UtilityPlugin = zeppelinGuildPlugin()("utility", MessageInfoCmd, InfoCmd, SnowflakeInfoCmd, + RoleInfoCmd, ], onLoad(pluginData) { diff --git a/backend/src/plugins/Utility/commands/InfoCmd.ts b/backend/src/plugins/Utility/commands/InfoCmd.ts index 10fc500a..c3a61e5a 100644 --- a/backend/src/plugins/Utility/commands/InfoCmd.ts +++ b/backend/src/plugins/Utility/commands/InfoCmd.ts @@ -9,9 +9,10 @@ import { canReadChannel } from "../../../utils/canReadChannel"; import { getMessageInfoEmbed } from "../functions/getMessageInfoEmbed"; import { getChannelInfoEmbed } from "../functions/getChannelInfoEmbed"; import { getServerInfoEmbed } from "../functions/getServerInfoEmbed"; -import { getChannelId } from "knub/dist/utils"; +import { getChannelId, getRoleId } from "knub/dist/utils"; import { getGuildPreview } from "../functions/getGuildPreview"; import { getSnowflakeInfoEmbed } from "../functions/getSnowflakeInfoEmbed"; +import { getRoleInfoEmbed } from "../functions/getRoleInfoEmbed"; export const InfoCmd = utilityCmd({ trigger: "info", @@ -104,14 +105,25 @@ export const InfoCmd = utilityCmd({ } } - // 7. Arbitrary ID + // 7. Role ID + const roleId = getRoleId(value); + const role = roleId && pluginData.guild.roles.get(roleId); + if (role && userCfg.can_roleinfo) { + const embed = await getRoleInfoEmbed(pluginData, role, message.author.id); + message.channel.createMessage({ embed }); + return; + } + + // TODO: 8. Emoji ID + + // 9. Arbitrary ID if (isValidSnowflake(value) && userCfg.can_snowflake) { const embed = await getSnowflakeInfoEmbed(pluginData, value, true, message.author.id); message.channel.createMessage({ embed }); return; } - // 7. No can do + // 10. No can do sendErrorMessage( pluginData, message.channel, diff --git a/backend/src/plugins/Utility/commands/RoleInfoCmd.ts b/backend/src/plugins/Utility/commands/RoleInfoCmd.ts new file mode 100644 index 00000000..2439a481 --- /dev/null +++ b/backend/src/plugins/Utility/commands/RoleInfoCmd.ts @@ -0,0 +1,28 @@ +import { utilityCmd } from "../types"; +import { commandTypeHelpers as ct } from "../../../commandTypes"; +import { sendErrorMessage } from "../../../pluginUtils"; +import { getRoleInfoEmbed } from "../functions/getRoleInfoEmbed"; + +export const RoleInfoCmd = utilityCmd({ + trigger: ["role", "roleinfo"], + description: "Show information about a role", + usage: "!role 106391128718245888", + permission: "can_roleinfo", + + signature: { + role: ct.role({ required: false }), + }, + + async run({ message, args, pluginData }) { + const roleId = args.role?.id; + const role = roleId && pluginData.guild.roles.get(roleId); + if (!role) { + sendErrorMessage(pluginData, message.channel, "Role not found"); + return; + } + + const embed = await getRoleInfoEmbed(pluginData, role, message.author.id); + + message.channel.createMessage({ embed }); + }, +}); diff --git a/backend/src/plugins/Utility/functions/getRoleInfoEmbed.ts b/backend/src/plugins/Utility/functions/getRoleInfoEmbed.ts new file mode 100644 index 00000000..b7e90236 --- /dev/null +++ b/backend/src/plugins/Utility/functions/getRoleInfoEmbed.ts @@ -0,0 +1,67 @@ +import { EmbedOptions, Role } from "eris"; +import { GuildPluginData } from "knub"; +import { UtilityPluginType } from "../types"; +import { trimLines, preEmbedPadding, EmbedWith } from "../../../utils"; +import moment from "moment-timezone"; +import humanizeDuration from "humanize-duration"; +import { TimeAndDatePlugin } from "../../TimeAndDate/TimeAndDatePlugin"; + +const MENTION = "https://cdn.discordapp.com/attachments/705009450855039042/839284872152481792/mention.png"; + +export async function getRoleInfoEmbed( + pluginData: GuildPluginData, + role: Role, + requestMemberId?: string, +): Promise { + const embed: EmbedWith<"fields"> = { + fields: [], + }; + + embed.author = { + name: `Role: ${role.name}`, + icon_url: MENTION, + }; + + embed.color = role.color; + + const createdAt = moment.utc(role.createdAt, "x"); + const timeAndDate = pluginData.getPlugin(TimeAndDatePlugin); + const tzCreatedAt = requestMemberId + ? await timeAndDate.inMemberTz(requestMemberId, createdAt) + : timeAndDate.inGuildTz(createdAt); + const prettyCreatedAt = tzCreatedAt.format(timeAndDate.getDateFormat("pretty_datetime")); + const roleAge = humanizeDuration(Date.now() - role.createdAt, { + largest: 2, + round: true, + }); + + const rolePerms = Object.keys(role.permissions.json) + .map(p => + p + .replace(/^voice/i, "") + .replace(/([a-z])([A-Z])/g, "$1 $2") + .toLowerCase() + .replace(/(^\w{1})|(\s{1}\w{1})/g, l => l.toUpperCase()), + ) + .join(", "); + + embed.fields.push({ + name: preEmbedPadding + "Role information", + value: trimLines(` + Name: **${role.name}** + ID: \`${role.id}\` + Created: **${roleAge} ago** (\`${prettyCreatedAt}\`) + Position: **${role.position}** + Color: **#${role.color + .toString(16) + .toUpperCase() + .padStart(6, "0")}** + Mentionable: **${role.mentionable ? "Yes" : "No"}** + Hoisted: **${role.hoist ? "Yes" : "No"}** + Permissions: \`${rolePerms}\` + Mention: <@&${role.id}> (\`<@&${role.id}>\`) + `), + }); + + return embed; +} diff --git a/backend/src/plugins/Utility/types.ts b/backend/src/plugins/Utility/types.ts index 8d6de6b4..c51d9c62 100644 --- a/backend/src/plugins/Utility/types.ts +++ b/backend/src/plugins/Utility/types.ts @@ -18,6 +18,7 @@ export const ConfigSchema = t.type({ can_channelinfo: t.boolean, can_messageinfo: t.boolean, can_userinfo: t.boolean, + can_roleinfo: t.boolean, can_snowflake: t.boolean, can_reload_guild: t.boolean, can_nickname: t.boolean,