diff --git a/package.json b/package.json index 1e51792..c7b70da 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "debug": "^3.1.0", "dotenv": "^4.0.0", "express": "^4.15.2", + "pg": "^8.11.3", "tsscmp": "^1.0.6" }, "devDependencies": { diff --git a/src/dbConfig.js b/src/dbConfig.js new file mode 100644 index 0000000..362778d --- /dev/null +++ b/src/dbConfig.js @@ -0,0 +1,14 @@ +module.exports = { + production: { + client: 'pg', + connection: process.env.DATABASE_URL, + pool: { + min: 2, + max: 10 + }, + migrations: { + tablename: '', + directory: '' + }, + } + }; \ No newline at end of file diff --git a/src/index.js b/src/index.js index 1fccf93..8b5116e 100644 --- a/src/index.js +++ b/src/index.js @@ -34,7 +34,7 @@ app.get('/', (req, res) => { * Endpoint to receive /helpdesk slash command from Slack. * Checks verification token and opens a dialog to capture more info. */ -app.post('/command', async (req, res) => { +app.post('/project', async (req, res) => { // Verify the signing secret if (!signature.isVerified(req)) { debug('Verification token mismatch'); @@ -58,7 +58,7 @@ app.post('/command', async (req, res) => { /* * Endpoint to receive the dialog submission. Checks the verification token - * and creates a Helpdesk ticket + * and creates a project */ app.post('/interactive', (req, res) => { // Verify the signing secret @@ -69,9 +69,10 @@ app.post('/interactive', (req, res) => { const body = JSON.parse(req.body.payload); res.send(''); + ticket.create(body.user.id, body.view); }); -const server = app.listen(process.env.PORT || 5000, () => { +const server = app.listen(process.env.PORT || 3000, () => { console.log('Express server listening on port %d in %s mode', server.address().port, app.settings.env); }); diff --git a/src/payloads.js b/src/payloads.js index 90b4e73..2f46ac8 100644 --- a/src/payloads.js +++ b/src/payloads.js @@ -2,13 +2,13 @@ module.exports = { confirmation: context => { return { channel: context.channel_id, - text: 'Helpdesk ticket created!', + text: 'Project created!', blocks: JSON.stringify([ { type: 'section', text: { type: 'mrkdwn', - text: '*Helpdesk ticket created!*' + text: '*Project created!*' } }, { @@ -18,7 +18,7 @@ module.exports = { type: 'section', text: { type: 'mrkdwn', - text: `*Title*\n${context.title}\n\n*Description*\n${context.description}` + text: `*Title*\n${context.name}\n` } }, { @@ -26,7 +26,7 @@ module.exports = { elements: [ { type: 'mrkdwn', - text: `*Urgency*: ${context.urgency}` + text: `*Business Unit*: ${context.bu}` } ] } @@ -40,7 +40,7 @@ module.exports = { type: 'modal', title: { type: 'plain_text', - text: 'Submit a helpdesk ticket' + text: 'Propose Project' }, callback_id: 'submit-ticket', submit: { @@ -49,70 +49,259 @@ module.exports = { }, blocks: [ { - block_id: 'title_block', + block_id: 'bu_block', type: 'input', label: { type: 'plain_text', - text: 'Title' + text: 'Business Unit' }, element: { - action_id: 'title', + action_id: 'bu', + type: 'static_select', + options: [ + { + text: { + type: "plain_text", + text: "AMER" + }, + value: "amer" + }, + { + text: { + type: "plain_text", + text: "EMEA" + }, + value: "emea" + }, + { + text: { + type: "plain_text", + text: "APAC" + }, + value: "apac" + } + ] + }, + optional: false + }, + { + block_id: 'name_block', + type: 'input', + label: { + type: 'plain_text', + text: 'Project Name' + }, + element: { + action_id: 'name', type: 'plain_text_input' }, - hint: { + optional: false + }, + { + block_id: 'type_block', + type: 'input', + label: { type: 'plain_text', - text: '30 second summary of the problem' + text: 'Type' + }, + element: { + action_id: 'type', + type: 'static_select', + options: [ + { + text: { + type: "plain_text", + text: "Campaign" + }, + value: "campaign" + }, + { + text: { + type: "plain_text", + text: "Commerce" + }, + value: "commerce" + }, + { + text: { + type: "plain_text", + text: "Automation" + }, + value: "automation" + } + ] } }, { - block_id: 'description_block', + block_id: 'brief_block', type: 'input', label: { type: 'plain_text', - text: 'Description' + text: 'Brief' }, element: { - action_id: 'description', - type: 'plain_text_input', - multiline: true + action_id: 'brief', + type: 'plain_text_input' }, - optional: true + optional: false }, { - block_id: 'urgency_block', + block_id: 'need_block', type: 'input', label: { type: 'plain_text', - text: 'Importance' + text: 'Need' }, element: { - action_id: 'urgency', - type: 'static_select', + action_id: 'need', + type: 'multi_static_select', + placeholder: { + type: 'plain_text', + text: 'Select needs' + }, options: [ { text: { type: "plain_text", - text: "High" + text: "Copy" }, - value: "high" + value: "copy" }, { text: { type: "plain_text", - text: "Medium" + text: "Creative" }, - value: "medium" + value: "creative" }, { text: { type: "plain_text", - text: "Low" + text: "Journey" }, - value: "low" + value: "journey" } ] }, - optional: true + optional: false + }, + { + block_id: 'comm_block', + type: 'input', + label: { + type: 'plain_text', + text: 'Communications' + }, + element: { + action_id: 'communications', + type: 'number_input', + is_decimal_allowed: false + } + }, + { + block_id: 'languages_block', + type: 'input', + label: { + type: 'plain_text', + text: 'Languages' + }, + element: { + action_id: 'languages', + type: 'multi_static_select', + options: [ + { + text: { + type: "plain_text", + text: "English" + }, + value: "english" + }, + { + text: { + type: "plain_text", + text: "Spanish" + }, + value: "spanish" + }, + { + text: { + type: "plain_text", + text: "French" + }, + value: "french" + } + ] + } + }, + { + block_id: 'objective_block', + type: 'input', + label: { + type: 'plain_text', + text: 'Objective' + }, + element: { + action_id: 'objective', + type: 'multi_static_select', + options: [ + { + text: { + type: "plain_text", + text: "New Members" + }, + value: "new_members" + }, + { + text: { + type: "plain_text", + text: "Cart Conversion" + }, + value: "cart_conv" + } + ] + } + }, + { + block_id: 'goal_block', + type: 'input', + label: { + type: 'plain_text', + text: 'Goal' + }, + element: { + action_id: 'goal', + type: 'number_input', + is_decimal_allowed: true + } + }, + { + block_id: 'budget_block', + type: 'input', + label: { + type: 'plain_text', + text: 'Budget' + }, + element: { + action_id: 'budget', + type: 'number_input', + is_decimal_allowed: true + } + }, + { + block_id: 'date_block', + type: 'input', + label: { + type: 'plain_text', + text: 'Due Date' + }, + element: { + action_id: 'date', + type: 'datepicker', + placeholder: { + type: 'plain_text', + text: 'Select a date' + } + } } ] }) diff --git a/src/ticket.js b/src/ticket.js index 067e9ea..2daa405 100644 --- a/src/ticket.js +++ b/src/ticket.js @@ -1,33 +1,40 @@ const debug = require('debug')('slash-command-template:ticket'); const api = require('./api'); const payloads = require('./payloads'); +const config = require('./dbConfig'); /* - * Send ticket creation confirmation via + * Send project creation confirmation via * chat.postMessage to the user who created it */ const sendConfirmation = async (ticket) => { // open a DM channel for that user - let channel = await api.callAPIMethod('im.open', { - user: ticket.userId + let channel = await api.callAPIMethod('conversations.open', { + users: ticket.userId }) let message = payloads.confirmation({ channel_id: channel.channel.id, - title: ticket.title, - description: ticket.description, - urgency: ticket.urgency + bu: ticket.bu, + name: ticket.name, + type: ticket.type }); let result = await api.callAPIMethod('chat.postMessage', message) debug('sendConfirmation: %o', result); }; -// Create helpdesk ticket. Call users.find to get the user's email address +// Create project. Call users.find to get the user's email address // from their user ID const create = async (userId, view) => { let values = view.state.values; + // DEBUG + console.log('VALUES OUTPUT'); + console.log('---- start commiting to heroku pg ----'); + console.log(JSON.stringify(values)); + console.log('---- end commiting to heroku pg ----'); + let result = await api.callAPIMethod('users.info', { user: userId }); @@ -35,9 +42,9 @@ const create = async (userId, view) => { await sendConfirmation({ userId, userEmail: result.user.profile.email, - title: values.title_block.title.value, - description: values.description_block.description.value || '_empty_', - urgency: values.urgency_block.urgency.selected_option && values.urgency_block.urgency.selected_option.text.text || 'not assigned' + bu: values.bu_block.bu.selected_option && values.bu_block.bu.selected_option.text.text || 'not assigned', + name: values.name_block.name.value || '_empty_', + type: values.type_block.type.selected_option && values.type_block.type.selected_option.text.text || 'not assigned' }); };