Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 16 additions & 3 deletions app.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ app.get('/', (_, res, next) => {
axios.get('https://api.github.com/zen').then(({ data }) => res.send(data)).catch(next)
})

if (process.env.DEPLOYED) {
app.use(verifySlack)
}
// if (process.env.DEPLOYED) {
// app.use(verifySlack)
// }

// secondary prefix for backward compat
Object.entries(modules).forEach(([uri, { route }]) => {
Expand Down Expand Up @@ -187,6 +187,19 @@ app.use('/interactive', (req, res) => {
return res.sendStatus(200)
}
}

// asana authorization modal
if (callback_id === 'asana-authorizer') {
const payload = { type, values }
const { worker } = modules['journal']

worker(payload).catch(console.error)

if (type === 'view_submission') {
return res.status(200).json({ 'response_action': 'clear' })
}
return res.sendStatus(200)
}
})

// catch-all error handler
Expand Down
33 changes: 33 additions & 0 deletions modules/asana-test/client.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
const axios = require('axios')
const qs = require('querystring')


const { client_id, client_secret } = process.env

module.exports.tokenExchange = ({ code, grant_type = 'authorization_code' }) => {
return axios.post(
'https://app.asana.com/-/oauth_token',
qs.stringify({
code,
grant_type,
client_id,
client_secret,
redirect_uri: 'urn:ietf:wg:oauth:2.0:oob',
}),
{
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
},
)
.then(({ data = {} }) => data)
.catch((e) => console.error(`Failed to fetch asana access token: ${e}`))
}

module.exports.getAuthorizeUrl = () => {
const url = [
'https://app.asana.com/-/oauth_authorize',
`?client_id=${client_id}`,
'&redirect_uri=urn:ietf:wg:oauth:2.0:oob',
'&response_type=code',
].join('')
return url
}
2 changes: 2 additions & 0 deletions modules/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const slack = require('./slack')
const notes = require('./notes')
const bday = require('./bday')
const release = require('./release')
const journal = require('./journal')


module.exports = {
Expand All @@ -21,4 +22,5 @@ module.exports = {
notes,
bday,
release,
journal
}
99 changes: 99 additions & 0 deletions modules/journal.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
const axios = require('axios')
const { WebClient } = require('@slack/web-api')

const { getAuthorizeUrl, tokenExchange } = require('./asana-test/client')
const { createJournal } = require('./asana-test/dev-journal.js')


const { SLACK_OAUTH } = process.env
const web = new WebClient(SLACK_OAUTH)
const COMMANDS = ['last workday', 'description', 'init']

const url = getAuthorizeUrl()
let response_url
const worker = async ({ command, response_url: r, trigger_id, type, values }) => {
if (command === 'init') {
if (r) response_url = r
return web.views.open({
trigger_id,
view: {
type: 'modal',
callback_id: 'asana-authorizer',
title: {
type: 'plain_text',
text: 'Connect to Asana'
},
blocks: [
{
type: 'section',
block_id: 'asana-token-exchange',
text: {
type: 'mrkdwn',
text: 'Submit token in the field below.',
},
accessory: {
type: 'button',
style: 'primary',
text: {
type: 'plain_text',
text: 'Get Token',
},
action_id: 'asana-authorize-url',
url,
}
},
{
type: 'input',
block_id: 'asana-auth-token',
label: {
type: 'plain_text',
text: 'Token',
},
element: {
type: 'plain_text_input',
action_id: 'token-text-input',
placeholder: {
type: 'plain_text',
text: 'Enter your token here...'
},
},
},
],
submit: {
type: 'plain_text',
text: 'Send',
},
}
})
}

if (type === 'view_submission') {
const { 'asana-auth-token': { 'token-text-input': { value: code } } } = values
const asanaCreds = await tokenExchange({ code })
await createJournal(asanaCreds)
return axios.post(response_url, {
response_type: 'ephemeral',
text: 'Successfully connected.'
})
}
}

const route = (req, res) => {
const { text = '', response_url, trigger_id } = req.body
if (text !== '' && !COMMANDS.includes(text)) {
return res.status(200).json({
response_type: 'ephemeral',
text: `"${text}" not supported.`
})
}

const payload = { command: text, response_url, trigger_id }
worker(payload).catch(console.error)
return res.status(200).json({
response_type: 'ephemeral',
text: 'Got it! Connecting with Asana now...'
})
}

module.exports = { worker, route }

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"@eqworks/avail-bot": "^1.0.7",
"@eqworks/release": "^3.1.0",
"@slack/web-api": "^5.7.0",
"asana": "^0.18.5",
"axios": "^0.18.0",
"body-parser": "^1.18.3",
"express": "^4.16.3",
Expand All @@ -24,7 +25,7 @@
"tsscmp": "^1.0.6"
},
"engines": {
"node": "12.x"
"node": "14.x"
},
"repository": {
"url": "https://glitch.com/edit/#!/welcome-project"
Expand Down
20 changes: 18 additions & 2 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -477,6 +477,17 @@ asana@^0.17.3:
readline "^1.3.0"
request "^2.88.0"

asana@^0.18.5:
version "0.18.5"
resolved "https://registry.npmjs.org/asana/-/asana-0.18.5.tgz#9683e15e7344b56d4ca54b9c2926bbccd09b6fc0"
integrity sha512-goV903J5mkC+Km53MODyxXY/EiUjvevaH1UUzI198zuJn/sGFzScNBMFC7Ild1fJg7POXbD0GgVCN9sBsrzUGg==
dependencies:
bluebird "^3.7.2"
browser-request "^0.3.2"
lodash "^4.17.20"
readline "^1.3.0"
request "^2.88.2"

asn1@~0.2.3:
version "0.2.4"
resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136"
Expand Down Expand Up @@ -657,6 +668,11 @@ bluebird@^2.3.0:
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-2.11.0.tgz#534b9033c022c9579c56ba3b3e5a5caafbb650e1"
integrity sha1-U0uQM8AiyVecVro7Plpcqvu2UOE=

bluebird@^3.7.2:
version "3.7.2"
resolved "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f"
integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==

body-parser@1.19.0, body-parser@^1.18.3:
version "1.19.0"
resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a"
Expand Down Expand Up @@ -2746,7 +2762,7 @@ lodash@^4.17.11, lodash@^4.17.14:
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548"
integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==

lodash@^4.17.19:
lodash@^4.17.19, lodash@^4.17.20:
version "4.17.20"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52"
integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==
Expand Down Expand Up @@ -3694,7 +3710,7 @@ request-promise-native@^1.0.7:
stealthy-require "^1.1.1"
tough-cookie "^2.3.3"

request@^2.88.0:
request@^2.88.0, request@^2.88.2:
version "2.88.2"
resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3"
integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==
Expand Down