diff --git a/docs/CHANGELOG.md b/CHANGELOG.md similarity index 96% rename from docs/CHANGELOG.md rename to CHANGELOG.md index d766777f..a5ef449a 100644 --- a/docs/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ 2. Use mongodb connection pools 3. Expand bounty copies to lvl2+ 4. Add Pradhumna Pancholi#3700 to POAP manager list +5. Allow lvl2+ contributors, admin, and genesis squad to use /poap command ## 1.3.2-RELEASE (2021-08-27) diff --git a/src/app/app.ts b/src/app/app.ts index d034464d..ca455b5a 100644 --- a/src/app/app.ts +++ b/src/app/app.ts @@ -13,9 +13,9 @@ const creator = new SlashCreator({ token: process.env.DISCORD_BOT_TOKEN, }); -creator.on('debug', (message) => console.log(message)); -creator.on('warn', (message) => console.warn(message)); -creator.on('error', (error) => console.error(error)); +creator.on('debug', (message) => console.log(`debug: ${ message }`)); +creator.on('warn', (message) => console.warn(`warn: ${ message }`)); +creator.on('error', (error) => console.error(`error: ${ error }`)); creator.on('synced', () => console.info('Commands synced!')); creator.on('commandRegister', (command) => console.info(`Registered command ${command.commandName}`)); creator.on('commandError', (command, error) => console.error(`Command ${command.commandName}:`, error)); diff --git a/src/app/commands/bounty/Bounty.ts b/src/app/commands/bounty/Bounty.ts index 8d23b2dc..e664d1e2 100644 --- a/src/app/commands/bounty/Bounty.ts +++ b/src/app/commands/bounty/Bounty.ts @@ -189,6 +189,16 @@ export default class Bounty extends SlashCommand { id: roleIds.level4, permission: true, }, + { + type: ApplicationCommandPermissionType.ROLE, + id: roleIds.admin, + permission: true, + }, + { + type: ApplicationCommandPermissionType.ROLE, + id: roleIds.genesisSquad, + permission: true, + }, ], }, }); diff --git a/src/app/commands/poap/poap.ts b/src/app/commands/poap/poap.ts index 451de36c..5c649778 100644 --- a/src/app/commands/poap/poap.ts +++ b/src/app/commands/poap/poap.ts @@ -13,6 +13,7 @@ import EndPOAP from '../../service/poap/EndPOAP'; import ValidationError from '../../errors/ValidationError'; import poapEvents from '../../service/constants/poapEvents'; import DistributePOAP from '../../service/poap/DistributePOAP'; +import roleIds from '../../service/constants/roleIds'; module.exports = class poap extends SlashCommand { constructor(creator: SlashCreator) { @@ -106,18 +107,44 @@ module.exports = class poap extends SlashCommand { }, defaultPermission: false, permissions: { - [process.env.DISCORD_SERVER_ID]: getAllowedUsers(), + [process.env.DISCORD_SERVER_ID]: [ + { + type: ApplicationCommandPermissionType.ROLE, + id: roleIds.level2, + permission: true, + }, + { + type: ApplicationCommandPermissionType.ROLE, + id: roleIds.level3, + permission: true, + }, + { + type: ApplicationCommandPermissionType.ROLE, + id: roleIds.level4, + permission: true, + }, + { + type: ApplicationCommandPermissionType.ROLE, + id: roleIds.admin, + permission: true, + }, + { + type: ApplicationCommandPermissionType.ROLE, + id: roleIds.genesisSquad, + permission: true, + }, + ], }, }); } - + async run(ctx: CommandContext) { if (ctx.user.bot) return; console.log(`start /poap ${ctx.user.username}#${ctx.user.discriminator}`); - + const { guildMember } = await ServiceUtils.getGuildAndMember(ctx); let command: Promise; - + try { switch (ctx.subcommands[0]) { case 'start': @@ -172,4 +199,21 @@ export const getAllowedUsers = (): ApplicationCommandPermissions[] =>{ permission: true, }); return allowedPermissions; -}; \ No newline at end of file +}; + +// TODO: pass this as a DM conversation... looks like client is not available until after slash commands are set +// export const getAllVoiceChannels = async (): Promise => { +// // const voiceChannels: Collection = client.channels.cache.filter(guildChannel => guildChannel.type === ChannelTypes.GUILD_VOICE.toString()); +// // const choices = []; +// // for (const channel of voiceChannels.values()) { +// // choices.push({ +// // name: channel.type, +// // value: channel.id, +// // }); +// // } +// // return choices; +// return [{ +// name: 'blank', +// value: 'asdfsdf', +// }]; +// }; \ No newline at end of file diff --git a/src/app/service/help/HowToPOAP.ts b/src/app/service/help/HowToPOAP.ts index 6d85cfdd..235f3958 100644 --- a/src/app/service/help/HowToPOAP.ts +++ b/src/app/service/help/HowToPOAP.ts @@ -9,9 +9,7 @@ export default (): MessageOptions => { fields: [ { name: '-> /poap start', - value: 'Start keeping track of attendees in the voice channel. The voice channel depends on the event.\n\n ' + - 'Community Call: Community Calls (stage)\n' + - 'Dev Guild: dev workroom', + value: 'Start keeping track of attendees in the voice channel. Once started it must be stopped by the same user.', inline: false, }, { diff --git a/src/app/utils/BountyUtils.ts b/src/app/utils/BountyUtils.ts index 4da40337..f94e1195 100644 --- a/src/app/utils/BountyUtils.ts +++ b/src/app/utils/BountyUtils.ts @@ -79,14 +79,7 @@ const BountyUtils = { }, validateNumberOfCopies(guildMember: GuildMember, copies: number): void { - const isLevel2 = ServiceUtils.isLevel2(guildMember); - const isLevel3 = ServiceUtils.isLevel3(guildMember); - const isLevel4 = ServiceUtils.isLevel4(guildMember); - const isAdmin = ServiceUtils.isAdmin(guildMember); - - if (!(isLevel2 || isLevel3 || isLevel4 || isAdmin)) { - throw new ValidationError('Must be `level 2+` to publish multiple copies.'); - } + ServiceUtils.validateLevel2AboveMembers(guildMember); if (copies > 100) { throw new ValidationError('Max number of copies is `100`.'); diff --git a/src/app/utils/ServiceUtils.ts b/src/app/utils/ServiceUtils.ts index 55e99c7c..a3363815 100644 --- a/src/app/utils/ServiceUtils.ts +++ b/src/app/utils/ServiceUtils.ts @@ -5,6 +5,7 @@ import { CommandContext } from 'slash-create'; import { Guild, GuildMember, Role, RoleManager } from 'discord.js'; import client from '../app'; import roleIDs from '../service/constants/roleIds'; +import ValidationError from '../errors/ValidationError'; const ServiceUtils = { async getGuildAndMember(ctx: CommandContext): Promise<{ guild: Guild, guildMember: GuildMember }> { @@ -41,6 +42,10 @@ const ServiceUtils = { return guildMember.roles.cache.some(role => role.id === roleIDs.level4); }, + isGenesisSquad(guildMember: GuildMember): boolean { + return guildMember.roles.cache.some(role => role.id === roleIDs.genesisSquad); + }, + isAnyLevel(guildMember: GuildMember): boolean { console.log(guildMember.roles.cache); return guildMember.roles.cache.some(role => role.id === roleIDs.level1 @@ -56,6 +61,18 @@ const ServiceUtils = { }; return (new Date(dateIso)).toLocaleString('en-US', options); }, + + validateLevel2AboveMembers(guildMember: GuildMember): void { + const isLevel2 = ServiceUtils.isLevel2(guildMember); + const isLevel3 = ServiceUtils.isLevel3(guildMember); + const isLevel4 = ServiceUtils.isLevel4(guildMember); + const isGenesisSquad = ServiceUtils.isGenesisSquad(guildMember); + const isAdmin = ServiceUtils.isAdmin(guildMember); + + if (!(isLevel2 || isLevel3 || isLevel4 || isAdmin || isGenesisSquad)) { + throw new ValidationError('Must be `level 2` or above member.'); + } + }, }; export default ServiceUtils; \ No newline at end of file