diff --git a/app.js b/app.js index 82049519..9f94c070 100644 --- a/app.js +++ b/app.js @@ -76,28 +76,6 @@ require("fs") // Slash Command Logic // /// //////////////////////////////////////////////////////////// -app.command(slashCommand, async ({ command, ack, respond }) => { - await ack(); - const userCommand = parseCommand(command); - - switch (userCommand.command) { - case "help": - await respond(helpMarkdown); - } -}); - -(async () => { - await app.start(3000); - webserver.listen(process.env.PORT || 3000); - - winston.info("⚡️ Bolt app is running!"); -})(); - -/// //////////////////////////////////////////////////////////// -// Functions // -/// //////////////////////////////////////////////////////////// - -// Parse Command Function function parseCommand(command) { const parsed = { // Default values for each parameter @@ -120,10 +98,37 @@ function parseCommand(command) { return parsed; } +app.command(slashCommand, async ({ command, ack, respond }) => { + await ack(); + const userCommand = parseCommand(command); + + switch (userCommand.command) { + case "help": + await respond(helpMarkdown); + break; + default: + await respond(errorMarkdown); + } +}); + +(async () => { + await app.start(3000); + webserver.listen(process.env.PORT || 3000); + + winston.info("⚡️ Bolt app is running!"); +})(); + /// //////////////////////////////////////////////////////////// // Variables // /// //////////////////////////////////////////////////////////// +const errorMarkdown = ` +:well: Command does not exist. +Here is a list of commands that actually work: + +/gratibot help: talks about what Gratibot can do! +`; + // Text is rendered into help command const helpMarkdown = ` :wave: Hi there! Let's take a look at what I can do! diff --git a/config.js b/config.js index 6ca26419..7c2ad69d 100644 --- a/config.js +++ b/config.js @@ -18,24 +18,17 @@ config.botName = process.env.BOT_NAME || "gratibot"; config.slashCommand = process.env.SLASH_COMMAND || "/gratibot"; config.usersExemptFromMaximum = process.env.EXEMPT_USERS?.split(",") || [ - "U037FL37G", - "U8T585Y8J", - "U04KTAJRS5T", - "U0K32MUSF", + "U037FL37G", // Chris Blackburn + "U8T585Y8J", // Jeremy Hayes + "U04KTAJRS5T", // Mike Denton + "U0K32MUSF", // Robert Kelly ]; config.initialGoldenRecognitionHolder = process.env.GOLDEN_RECOGNIZE_HOLDER || "UE1QRFSSY"; config.redemptionAdmins = process.env.REDEMPTION_ADMINS?.split(",") || [ - "U6BS54PJM", - "U02KPMFA9DG", - "U04666K57CP", -]; - -config.usersDeduction = process.env.USERS_DEDUCTION?.split(",") || [ - "U04666K57CP", // Danielle - "U8T585Y8J", // Jeremy - "U02KPMFA9DG", // Smith + "U02KPMFA9DG", // Smith Mize + "U04666K57CP", // Danielle Johnson ]; module.exports = config; diff --git a/features/deduction.js b/features/deduction.js new file mode 100644 index 00000000..a82c46d7 --- /dev/null +++ b/features/deduction.js @@ -0,0 +1,87 @@ +const deduction = require("../service/deduction"); +const winston = require("../winston"); +const { redemptionAdmins } = require("../config"); +const { userRegex } = require("../regex"); +const { directMention } = require("@slack/bolt"); +const { directMessage, anyOf } = require("../middleware"); + +module.exports = function (app) { + app.message( + "deduct", + anyOf(directMention(), directMessage()), + respondToDeduction + ); +}; + +async function respondToDeduction({ message, client }) { + winston.info("@gratibot deduction Called", { + func: "feature.deduction.respondToDeduction", + callingUser: message.user, + slackMessage: message.text, + }); + + const userInfo = await client.users.info({ user: message.user }); + if (!userInfo.ok) { + winston.error("Slack API returned error from users.info", { + func: "feature.deduction.respondToDeduction", + callingUser: message.user, + slackMessage: message.text, + error: userInfo.error, + }); + await client.chat.postEphemeral({ + channel: message.channel, + user: message.user, + text: `Something went wrong while creating your deduction. When retreiving user information from Slack, the API responded with the following error: ${userInfo.error}`, + }); + return; + } + + if (!redemptionAdmins.includes(message.user)) { + await client.chat.postEphemeral({ + channel: message.channel, + user: message.user, + text: `You are not allowed to create deductions.`, + }); + return; + } + + const messageText = message.text.split(" "); + + if ( + messageText.length < 4 || + !userRegex.test(messageText[2]) || + isNaN(+messageText[3]) + ) { + await client.chat.postEphemeral({ + channel: message.channel, + user: message.user, + text: `You must specify a user and value to deduct. Example: \`@gratibot deduct @user 5\``, + }); + return; + } + + const user = messageText[2].match(userRegex)[1]; + const value = +messageText[3]; + + if (!(await deduction.isBalanceSufficent(user, value))) { + await client.chat.postEphemeral({ + channel: message.channel, + user: message.user, + text: `<@${user}> does not have a large enough balance to deduct ${value} fistbumps.`, + }); + return; + } + + await deduction.createDeduction(user, value, message.text); + const deductionInfo = await deduction.createDeduction( + user, + value, + message.text + ); + + await client.chat.postMessage({ + channel: message.channel, + user: message.user, + text: `A deduction of ${value} fistbumps has been made for <@${user}>. Deduction ID is \`${deductionInfo._id}\``, + }); +} diff --git a/features/redeem.js b/features/redeem.js index b2362771..7698e35f 100644 --- a/features/redeem.js +++ b/features/redeem.js @@ -51,13 +51,18 @@ async function redeemItem({ ack, body, context, client }) { }); } - let redemptionMessage = `<@${userID}> has redeemed ${itemName} for ${itemCost} fistbumps.`; - const deductionInfo = await deduction.createDeduction( - userID, - itemCost, - redemptionMessage - ); - redemptionMessage += ` Deduction ID is \`${deductionInfo._id}\``; + let redemptionMessage = `<@${userID}> has selected ${itemName}`; + if (itemName === "Liatrio Store") { + redemptionMessage += `. Please provide the link of the item from the .`; + } else { + redemptionMessage += ` for ${itemCost} fistbumps.`; + const deductionInfo = await deduction.createDeduction( + userID, + itemCost, + redemptionMessage + ); + redemptionMessage += ` Deduction ID is \`${deductionInfo._id}\``; + } await client.chat.postMessage({ channel: result.channel.id, token: context.botToken, diff --git a/regex.js b/regex.js new file mode 100644 index 00000000..1b480744 --- /dev/null +++ b/regex.js @@ -0,0 +1,9 @@ +var regex = {}; + +regex.userRegex = /<@([^>]+)>/; +regex.deductRegex = /<@([^|>]+)\|/; // For Slash command +regex.groupRegex = //g; +regex.tagRegex = /#(\S+)/g; +regex.generalEmojiRegex = /:([a-z-_']+):/g; + +module.exports = regex; diff --git a/rewards.json b/rewards.json index d3e0f354..291a12df 100644 --- a/rewards.json +++ b/rewards.json @@ -1,4 +1,10 @@ [ + { + "name": "Liatrio Store", + "description": "Choose an item from the . 2 Fistbumps = 1 Dollar.", + "imageURL": "https://gratibotjtest.blob.core.windows.net/gratibotimages/Liatrio_Logo.png", + "cost": 0 + }, { "name": "Pre-Loved Laptop", "description": "Pre-Loved Laptop",