From 5237fa651266b13a25eb54edc4af3f214178a162 Mon Sep 17 00:00:00 2001 From: Erik Yewell Date: Mon, 20 Sep 2021 20:57:21 -0700 Subject: [PATCH 1/6] updated to 2021 documentation --- Procfile | 1 + README.md | 47 ++- app.json | 26 -- modules/account.js | 11 +- modules/actions.js | 0 modules/case.js | 8 +- modules/contact.js | 8 +- modules/force.js | 3 +- modules/opportunity.js | 9 +- modules/slack-salesforce-auth.js | 1 + modules/whoami.js | 9 +- package-lock.json | 703 +++++++++++++++++++++++++++++++ package.json | 8 +- server.js | 1 - www/index.html | 1 + 15 files changed, 746 insertions(+), 90 deletions(-) create mode 100644 Procfile mode change 100644 => 100755 modules/account.js mode change 100644 => 100755 modules/actions.js mode change 100644 => 100755 modules/case.js mode change 100644 => 100755 modules/contact.js mode change 100644 => 100755 modules/force.js mode change 100644 => 100755 modules/opportunity.js mode change 100644 => 100755 modules/slack-salesforce-auth.js mode change 100644 => 100755 modules/whoami.js create mode 100644 package-lock.json mode change 100644 => 100755 server.js create mode 100644 www/index.html diff --git a/Procfile b/Procfile new file mode 100644 index 0000000..063b78f --- /dev/null +++ b/Procfile @@ -0,0 +1 @@ +web: npm start diff --git a/README.md b/README.md index d4717b5..139e831 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ A simple Node.js application that acts as a Slash Command message broker between Watch [this video](https://youtu.be/xB-1SsUoBHk) to see the application in action. -Read [this blog post](http://coenraets.org/blog/2016/01/slack-salesforce-integration-part-2/) for more details. +Read [this blog post](https://medium.com/@ccoenraets/slack-and-salesforce-integration-part-2-a29584c85274) for more details. Follow the instructions below to deploy your own instance of the application: @@ -27,7 +27,8 @@ If you haven't already done so, follow the steps below to create a Salesforce co ### Step 2: Deploy the Slash Commands 1. Make sure you are logged in to the [Heroku Dashboard](https://dashboard.heroku.com/) -1. Click the button below to deploy the Slash Commands on Heroku: +1.1 If you don't have a heroku account, you can sign up. You will be asked for a credit card, but not charged for just hobby development. +1. Click the button below to deploy this Slash Commands service on Heroku: [![Deploy](https://www.herokucdn.com/deploy/button.png)](https://heroku.com/deploy) @@ -37,36 +38,44 @@ If you haven't already done so, follow the steps below to create a Salesforce co - For **SF_CLIENT_SECRET**, enter the Consumer Secret of your Salesforce Connected App - For **SF_USER_NAME**, enter the the username of your Salesforce integration user - For **SF_PASSWORD**, enter the the username of your Salesforce integration user - - Leave **SLACK_ACCOUNT_TOKEN** blank for now. - - Leave **SLACK_CONTACT_TOKEN** blank for now. - - Leave **SLACK_OPPORTUNITY_TOKEN** blank for now. - - Leave **SLACK_CASE_TOKEN** blank for now. - - Leave **SLACK_WHOAMI_TOKEN** blank for now. 1. Once your app is deployed, go back to the Connected App in Salesforce, and change the OAuth callback URL: Use the URL of your actuall Heroku app, followd by /oauthcallback. For example: https://mynewapp.herokuapp.com/oauthcallback ### Step 3: Create the Slash Commands in Slack -1. In a browser, go to the custom integration page for your Slack team. For example ```https://YOUR_TEAM_NAME.slack.com/apps/manage/custom-integration```. Replace ```YOUR_TEAM_NAME``` with your actual team name. +1. In a browser, go to the customization page for your Slack workspace. For example ```https://YOUR_TEAM_NAME.slack.com/customize/```. Replace ```YOUR_TEAM_NAME``` with your actual team name. Click the "hanburger" menu icon in the upper left, and open the Configure Apps menu. In the upper right, click on "Build". +1. click on **Create New App**, and choose 'from scratch' -1. Click **Slash Commands**, and click **Add Configuration** +1. choose a name 'SlackMySalesforce', and choose a workspace. click **Create App**. -1. In the **Choose a Command** input field, type **/pipeline** and click **Add Slash Command Integration** +1. On the Basic Information page for your app, open the **Add features and functionality** area. -1. In the **Integration Settings** section: +1. Click **Slash Commands**, and click **Create New Command** + +1. In the **Command** input field, type **/pipeline** and fill in the rest of the fields: - Command: /pipeline - URL: the URL of the app you deployed on Heroku followed by /pipeline. For example: ```https://your-heroku-app.herokuapp.com/pipeline``` - - Method: POST - - Copy the token, open another browser tab, login to the Heroku Dashboard, and set the Heroku **SLACK_OPPORTUNITY_TOKEN** config variable to the value of that token (**Setting>Reveal Config Vars**) - - Customize Name: Salesforce Opportunities + - Description + - Add usage guidance text (check the preview of the Autocomplete Entry at the bottom) - Click **Save Integration**. + Click **Save**. -1. Repeat these steps to create another Slash command called **/account**, calling ```https://your-heroku-app.herokuapp.com/account```. In the Heroku dashboard, set the **SLACK_ACCOUNT_TOKEN** config var to the value of the token that was generated in Slack. +1. Repeat these steps to create another Slash command called **/account**, calling ```https://your-heroku-app.herokuapp.com/account```. + +1. Repeat these steps to create another Slash command called **/contact**, calling ```https://your-heroku-app.herokuapp.com/contact```. + +1. Repeat these steps to create another Slash command called **/case**, calling ```https://your-heroku-app.herokuapp.com/case```. + +1. Repeat these steps to create another Slash command called **/whoami**, calling ```https://your-heroku-app.herokuapp.com/whoami```. -1. Repeat these steps to create another Slash command called **/contact**, calling ```https://your-heroku-app.herokuapp.com/contact```. In the Heroku dashboard, set the **SLACK_CONTACT_TOKEN** config var to the value of the token that was generated in Slack. +1. Back on the **Basic Information** page for the app, click on **Install your App**. You will have to do this each time you change your commands -1. Repeat these steps to create another Slash command called **/case**, calling ```https://your-heroku-app.herokuapp.com/case```. In the Heroku dashboard, set the **SLACK_CASE_TOKEN** config var to the value of the token that was generated in Slack. +1. Go back to slack, and try one of the /commands from above . The first time you may be asked to authenticate. Once complete, you should be off and running -1. Repeat these steps to create another Slash command called **/whoami**, calling ```https://your-heroku-app.herokuapp.com/whoami```. In the Heroku dashboard, set the **SLACK_WHOAMI_TOKEN** config var to the value of the token that was generated in Slack. +Troubleshooting: +1. Don't forget to change the callback in the Connected App in your salesforce org. +1. You will not see anything at the home URL for your heroku app, when viewed from the browser. It will be a blank page +1. You will not be able to test your heroku app from your browser for the /account and other commands, since these only work for POST operations. you can do some limited testing using cURL: 'curl -X POST -H 'Content-type: application/json' --data '{"text":"Tycoo"}' http://127.0.0.1:5000/' . However, some slack vars like the user id will not be available. +1. Check your heroku logs in realtime from a terminal window with 'heroku logs --tail' +1. Don't be afraid to use console.log in your code to check variables, which you will see in the heroku logs. \ No newline at end of file diff --git a/app.json b/app.json index a2bb5ed..5916a1b 100644 --- a/app.json +++ b/app.json @@ -21,32 +21,6 @@ "SF_LOGIN_URL": { "description": "Salesforce login URL", "value":"https://login.salesforce.com" - }, - "SLACK_ACCOUNT_TOKEN": { - "description": "Slack token for the account slash command", - "value":"", - "required":false - }, - "SLACK_CONTACT_TOKEN": { - "description": "Slack token for the contact slash command", - "value":"", - "required":false - }, - "SLACK_OPPORTUNITY_TOKEN": { - "description": "Slack token for the pipeline slash command", - "value":"", - "required":false - - }, - "SLACK_CASE_TOKEN": { - "description": "Slack token for the case slash command", - "value":"", - "required":false - }, - "SLACK_WHOAMI_TOKEN": { - "description": "Slack token for the whoami slash command", - "value":"", - "required":false } } } diff --git a/modules/account.js b/modules/account.js old mode 100644 new mode 100755 index b909fc8..c4662fc --- a/modules/account.js +++ b/modules/account.js @@ -1,17 +1,10 @@ "use strict"; let auth = require("./slack-salesforce-auth"), - force = require("./force"), - ACCOUNT_TOKEN = process.env.SLACK_ACCOUNT_TOKEN; + force = require("./force"); exports.execute = (req, res) => { - - if (req.body.token != ACCOUNT_TOKEN) { - console.log("Invalid token"); - res.send("Invalid token"); - return; - } - + let slackUserId = req.body.user_id, oauthObj = auth.getOAuthObject(slackUserId), q = "SELECT Id, Name, Phone, BillingAddress FROM Account WHERE Name LIKE '%" + req.body.text + "%' LIMIT 5"; diff --git a/modules/actions.js b/modules/actions.js old mode 100644 new mode 100755 diff --git a/modules/case.js b/modules/case.js old mode 100644 new mode 100755 index 75d3bf2..dfb5d76 --- a/modules/case.js +++ b/modules/case.js @@ -1,16 +1,10 @@ "use strict"; let auth = require("./slack-salesforce-auth"), - force = require("./force"), - CASE_TOKEN = process.env.SLACK_CASE_TOKEN; + force = require("./force"); exports.execute = (req, res) => { - if (req.body.token != CASE_TOKEN) { - res.send("Invalid token"); - return; - } - let slackUserId = req.body.user_id, oauthObj = auth.getOAuthObject(slackUserId), params = req.body.text.split(":"), diff --git a/modules/contact.js b/modules/contact.js old mode 100644 new mode 100755 index bf2f8d3..6123965 --- a/modules/contact.js +++ b/modules/contact.js @@ -1,16 +1,10 @@ "use strict"; let auth = require("./slack-salesforce-auth"), - force = require("./force"), - CONTACT_TOKEN = process.env.SLACK_CONTACT_TOKEN; + force = require("./force"); exports.execute = (req, res) => { - if (req.body.token != CONTACT_TOKEN) { - res.send("Invalid token"); - return; - } - let slackUserId = req.body.user_id, oauthObj = auth.getOAuthObject(slackUserId), q = "SELECT Id, Name, Phone, MobilePhone, Email FROM Contact WHERE Name LIKE '%" + req.body.text + "%' LIMIT 5"; diff --git a/modules/force.js b/modules/force.js old mode 100644 new mode 100755 index 1241e82..2c5fec3 --- a/modules/force.js +++ b/modules/force.js @@ -1,7 +1,8 @@ "use strict"; let request = require("request"), - API_VERSION = 'v35.0'; + //API_VERSION = 'v35.0'; + API_VERSION = 'v52.0'; let getUserId = (oauth) => (typeof(oauth) !== 'undefined') ? oauth.id.split('/').pop() : undefined; diff --git a/modules/opportunity.js b/modules/opportunity.js old mode 100644 new mode 100755 index 4235402..fd0b945 --- a/modules/opportunity.js +++ b/modules/opportunity.js @@ -1,17 +1,10 @@ "use strict"; let auth = require("./slack-salesforce-auth"), - force = require("./force"), - - OPPORTUNITY_TOKEN = process.env.SLACK_OPPORTUNITY_TOKEN; + force = require("./force"); exports.execute = (req, res) => { - if (req.body.token != OPPORTUNITY_TOKEN) { - res.send("Invalid token"); - return; - } - let slackUserId = req.body.user_id, oauthObj = auth.getOAuthObject(slackUserId), limit = req.body.text, diff --git a/modules/slack-salesforce-auth.js b/modules/slack-salesforce-auth.js old mode 100644 new mode 100755 index 2cec83a..27fc013 --- a/modules/slack-salesforce-auth.js +++ b/modules/slack-salesforce-auth.js @@ -34,6 +34,7 @@ exports.loginLink = (req, res) => { }; exports.oauthLogin = (req, res) => { + console.log("oauthLogin.req" + req); res.redirect(`${SF_LOGIN_URL}/services/oauth2/authorize?response_type=code&client_id=${SF_CLIENT_ID}&redirect_uri=https://${req.hostname}/oauthcallback&state=${req.params.slackUserId}`); }; diff --git a/modules/whoami.js b/modules/whoami.js old mode 100644 new mode 100755 index 722de72..7704fdf --- a/modules/whoami.js +++ b/modules/whoami.js @@ -1,17 +1,10 @@ "use strict"; let auth = require("./slack-salesforce-auth"), - force = require("./force"), - WHOAMI_TOKEN = process.env.SLACK_WHOAMI_TOKEN; + force = require("./force"); exports.execute = (req, res) => { - if (req.body.token != WHOAMI_TOKEN) { - console.log("Invalid token"); - res.send("Invalid token"); - return; - } - let slackUserId = req.body.user_id, oauthObj = auth.getOAuthObject(slackUserId); diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..c297f42 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,703 @@ +{ + "name": "slackforce", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "accepts": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "requires": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + } + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" + }, + "aws4": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", + "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==" + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "requires": { + "bytes": "3.1.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" + } + }, + "bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "content-disposition": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", + "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", + "requires": { + "safe-buffer": "5.1.2" + } + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" + }, + "cookie": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", + "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "requires": { + "assert-plus": "^1.0.0" + } + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" + }, + "express": { + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", + "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", + "requires": { + "accepts": "~1.3.7", + "array-flatten": "1.1.1", + "body-parser": "1.19.0", + "content-disposition": "0.5.3", + "content-type": "~1.0.4", + "cookie": "0.4.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.1.2", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.5", + "qs": "6.7.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.1.2", + "send": "0.17.1", + "serve-static": "1.14.1", + "setprototypeof": "1.1.1", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "dependencies": { + "body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "requires": { + "bytes": "3.1.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" + } + } + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, + "finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + } + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" + }, + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "requires": { + "assert-plus": "^1.0.0" + } + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" + }, + "har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "requires": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + } + }, + "http-errors": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", + "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + } + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" + }, + "mime-db": { + "version": "1.49.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.49.0.tgz", + "integrity": "sha512-CIc8j9URtOVApSFCQIF+VBkX1RwXp/oMMOrqdyXSBXq5RWNEsRfyj1kiRnQgmNXmHxPoFIxOroKA3zcU9P+nAA==" + }, + "mime-types": { + "version": "2.1.32", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.32.tgz", + "integrity": "sha512-hJGaVS4G4c9TSMYh2n6SQAGrC4RnfU+daP8G7cSCmaqNjiOoUY0VHCMS42pxnQmVF1GWwFhbHWn3RIxCqTmZ9A==", + "requires": { + "mime-db": "1.49.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "negotiator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "requires": { + "ee-first": "1.1.1" + } + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + }, + "proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "requires": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + } + }, + "psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + }, + "qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" + }, + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" + }, + "raw-body": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", + "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", + "requires": { + "bytes": "3.1.0", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + } + }, + "request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "dependencies": { + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" + } + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "send": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", + "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", + "requires": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.7.2", + "mime": "1.6.0", + "ms": "2.1.1", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "dependencies": { + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + } + } + }, + "serve-static": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", + "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.1" + } + }, + "setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" + }, + "sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" + }, + "toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" + }, + "tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" + }, + "type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "requires": { + "punycode": "^2.1.0" + } + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" + }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + } + } +} diff --git a/package.json b/package.json index bf16ff7..96a515f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "slackforce", - "version": "1.0.0", + "version": "1.0.1", "description": "", "main": "server.js", "scripts": { @@ -9,8 +9,8 @@ "author": "Christophe Coenraets (http://coenraets.org/)", "license": "ISC", "dependencies": { - "body-parser": "^1.14.2", - "express": "^4.13.3", - "request": "^2.72.0" + "body-parser": "^1.19.0", + "express": "^4.17.1", + "request": "^2.88.2" } } diff --git a/server.js b/server.js old mode 100644 new mode 100755 index c3a58fe..7b9c228 --- a/server.js +++ b/server.js @@ -11,7 +11,6 @@ let express = require('express'), actions = require('./modules/actions'), app = express(); - app.enable('trust proxy'); app.set('port', process.env.PORT || 5000); diff --git a/www/index.html b/www/index.html new file mode 100644 index 0000000..6c70bcf --- /dev/null +++ b/www/index.html @@ -0,0 +1 @@ + \ No newline at end of file From 3ba4fb96b4d4a84870621631cc2081a8d919ba3b Mon Sep 17 00:00:00 2001 From: Erik Yewell Date: Mon, 20 Sep 2021 21:01:45 -0700 Subject: [PATCH 2/6] updated readme --- README.md | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 139e831..fd17ab2 100644 --- a/README.md +++ b/README.md @@ -2,24 +2,22 @@ A simple Node.js application that acts as a Slash Command message broker between Slack and Salesforce. -Watch [this video](https://youtu.be/xB-1SsUoBHk) to see the application in action. - -Read [this blog post](https://medium.com/@ccoenraets/slack-and-salesforce-integration-part-2-a29584c85274) for more details. +Watch [this video](https://youtu.be/xB-1SsUoBHk) to see the application in action. Read [this blog post](https://medium.com/@ccoenraets/slack-and-salesforce-integration-part-2-a29584c85274) for more details. Follow the instructions below to deploy your own instance of the application: ### Step 1: Create a Connected App -If you haven't already done so, follow the steps below to create a Salesforce connected app: +A **Connected App** is a secure API endpoint on a salesforce org. In this case, it will enable an oAuth connection specifically for this slack app, complete with client ID and client secret. If you haven't already done so, follow the steps below to create a Salesforce connected app: -1. In Salesforce Setup, type **Apps** in the quick find box, and click the **Apps** link +1. In Salesforce Setup, type **App Manager** in the quick find box, and click the **App Manager** link -1. In the **Connected Apps** section, click **New**, and define the Connected App as follows: +1. Click the **New Connected App** button on the far right, and define the Connected App as follows: - Connected App Name: MyConnectedApp (or any name you want) - API Name: MyConnectedApp - Contact Email: enter your email address - - Enabled OAuth Settings: Checked + - Enable OAuth Settings: Checked - Callback URL: https://myapp.herokuapp.com/oauthcallback (You'll change this later) - Selected OAuth Scopes: Full Access (full) - Click **Save** From ddd9b6318ea8378109269df06c4e13c469cabc4d Mon Sep 17 00:00:00 2001 From: Erik Yewell Date: Mon, 20 Sep 2021 21:03:00 -0700 Subject: [PATCH 3/6] updated readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index fd17ab2..624bd63 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ A **Connected App** is a secure API endpoint on a salesforce org. In this case, ### Step 2: Deploy the Slash Commands 1. Make sure you are logged in to the [Heroku Dashboard](https://dashboard.heroku.com/) -1.1 If you don't have a heroku account, you can sign up. You will be asked for a credit card, but not charged for just hobby development. +2. If you don't have a heroku account, you can sign up. You will be asked for a credit card, but not charged for just hobby development. 1. Click the button below to deploy this Slash Commands service on Heroku: [![Deploy](https://www.herokucdn.com/deploy/button.png)](https://heroku.com/deploy) From 9e7ce9183c818454b4c41eb9d5e015a73d9b9c2b Mon Sep 17 00:00:00 2001 From: Erik Yewell Date: Mon, 20 Sep 2021 21:08:34 -0700 Subject: [PATCH 4/6] readme changes --- README.md | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 624bd63..d6bb79c 100644 --- a/README.md +++ b/README.md @@ -14,23 +14,23 @@ A **Connected App** is a secure API endpoint on a salesforce org. In this case, 1. Click the **New Connected App** button on the far right, and define the Connected App as follows: - - Connected App Name: MyConnectedApp (or any name you want) - - API Name: MyConnectedApp + - Connected App Name: SlackMySalesforce (or any name you want) + - API Name: SlackMySalesforce - Contact Email: enter your email address - Enable OAuth Settings: Checked - Callback URL: https://myapp.herokuapp.com/oauthcallback (You'll change this later) - Selected OAuth Scopes: Full Access (full) - Click **Save** -### Step 2: Deploy the Slash Commands +### Step 2: Deploy this Slash Commands repo right to Heroku + +1. Make sure you are logged in to the [Heroku Dashboard](https://dashboard.heroku.com/). This will eventually be where you can see a list of all your heroku apps. If you don't have a heroku account, you can sign up. You will be asked for a credit card, but not charged for just hobby development. -1. Make sure you are logged in to the [Heroku Dashboard](https://dashboard.heroku.com/) -2. If you don't have a heroku account, you can sign up. You will be asked for a credit card, but not charged for just hobby development. 1. Click the button below to deploy this Slash Commands service on Heroku: [![Deploy](https://www.herokucdn.com/deploy/button.png)](https://heroku.com/deploy) -1. Fill in the config variables as described. +1. Fill in the config variables as described. If you need to get to these later, these can be found by clicking on your App Name in the heroku dashboard, and then clicking on the subtab Settings, then the "Reveal Config Vars" button. Click the pencil to edit each one. - For **SF_CLIENT_ID**, enter the Consumer Key of your Salesforce Connected App - For **SF_CLIENT_SECRET**, enter the Consumer Secret of your Salesforce Connected App @@ -41,10 +41,11 @@ A **Connected App** is a secure API endpoint on a salesforce org. In this case, ### Step 3: Create the Slash Commands in Slack -1. In a browser, go to the customization page for your Slack workspace. For example ```https://YOUR_TEAM_NAME.slack.com/customize/```. Replace ```YOUR_TEAM_NAME``` with your actual team name. Click the "hanburger" menu icon in the upper left, and open the Configure Apps menu. In the upper right, click on "Build". -1. click on **Create New App**, and choose 'from scratch' +1. In a browser, go to the customization page for your Slack workspace. For example ```https://YOUR_TEAM_NAME.slack.com/customize/```. Replace ```YOUR_TEAM_NAME``` with your actual team/workspace name. Click the "hanburger" menu icon in the upper left, and open the Configure Apps menu. In the upper right, click on "Build". + +1. click on **Create New App**, and choose 'from scratch'. -1. choose a name 'SlackMySalesforce', and choose a workspace. click **Create App**. +1. choose a name: 'SlackMySalesforce', and choose your workspace. Click **Create App**. 1. On the Basic Information page for your app, open the **Add features and functionality** area. @@ -69,7 +70,7 @@ A **Connected App** is a secure API endpoint on a salesforce org. In this case, 1. Back on the **Basic Information** page for the app, click on **Install your App**. You will have to do this each time you change your commands -1. Go back to slack, and try one of the /commands from above . The first time you may be asked to authenticate. Once complete, you should be off and running +1. Go back to slack, and try one of the /commands from above. The first time you may be asked to authenticate. Once complete, you should be off and running. Troubleshooting: 1. Don't forget to change the callback in the Connected App in your salesforce org. From ec2a83709ef7e8fa80765b0c7717f6b53c1c671a Mon Sep 17 00:00:00 2001 From: Erik Yewell Date: Mon, 20 Sep 2021 21:13:06 -0700 Subject: [PATCH 5/6] readme update --- README.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index d6bb79c..44aa840 100644 --- a/README.md +++ b/README.md @@ -39,13 +39,13 @@ A **Connected App** is a secure API endpoint on a salesforce org. In this case, 1. Once your app is deployed, go back to the Connected App in Salesforce, and change the OAuth callback URL: Use the URL of your actuall Heroku app, followd by /oauthcallback. For example: https://mynewapp.herokuapp.com/oauthcallback -### Step 3: Create the Slash Commands in Slack +### Step 3: Create the Slack App & Enable Slack Commands 1. In a browser, go to the customization page for your Slack workspace. For example ```https://YOUR_TEAM_NAME.slack.com/customize/```. Replace ```YOUR_TEAM_NAME``` with your actual team/workspace name. Click the "hanburger" menu icon in the upper left, and open the Configure Apps menu. In the upper right, click on "Build". -1. click on **Create New App**, and choose 'from scratch'. +1. Click on **Create New App**, and choose 'from scratch'. -1. choose a name: 'SlackMySalesforce', and choose your workspace. Click **Create App**. +1. Choose a name: 'SlackMySalesforce', and choose your workspace. Click **Create App**. 1. On the Basic Information page for your app, open the **Add features and functionality** area. @@ -73,8 +73,8 @@ A **Connected App** is a secure API endpoint on a salesforce org. In this case, 1. Go back to slack, and try one of the /commands from above. The first time you may be asked to authenticate. Once complete, you should be off and running. Troubleshooting: -1. Don't forget to change the callback in the Connected App in your salesforce org. -1. You will not see anything at the home URL for your heroku app, when viewed from the browser. It will be a blank page -1. You will not be able to test your heroku app from your browser for the /account and other commands, since these only work for POST operations. you can do some limited testing using cURL: 'curl -X POST -H 'Content-type: application/json' --data '{"text":"Tycoo"}' http://127.0.0.1:5000/' . However, some slack vars like the user id will not be available. -1. Check your heroku logs in realtime from a terminal window with 'heroku logs --tail' -1. Don't be afraid to use console.log in your code to check variables, which you will see in the heroku logs. \ No newline at end of file +1. After step 2.4, don't forget to update the callback in the Connected App in your salesforce org. +1. You will not see anything at the home URL for your heroku app, when viewed from the browser. It will be a blank page. That is normal. +1. You will not be able to test your heroku app from your browser for the /account and other commands, since these only work for POST operations. You CAN do some limited testing using cURL: 'curl -X POST -H 'Content-type: application/json' --data '{"text":"Tycoo"}' http://127.0.0.1:5000/' . However, some slack vars like the user id will not be available. +1. Check your heroku logs in realtime from a terminal window with 'heroku logs --tail' command +1. Don't be afraid to use console.log() in your code to check variables, which you will see in the heroku logs. \ No newline at end of file From 3020d883ae192722053d7964c481b7256dad988a Mon Sep 17 00:00:00 2001 From: Erik Yewell Date: Mon, 20 Sep 2021 21:14:31 -0700 Subject: [PATCH 6/6] readme updates --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 44aa840..705560d 100644 --- a/README.md +++ b/README.md @@ -68,11 +68,13 @@ A **Connected App** is a secure API endpoint on a salesforce org. In this case, 1. Repeat these steps to create another Slash command called **/whoami**, calling ```https://your-heroku-app.herokuapp.com/whoami```. +### Step 4: Install and Launch your commands! + 1. Back on the **Basic Information** page for the app, click on **Install your App**. You will have to do this each time you change your commands 1. Go back to slack, and try one of the /commands from above. The first time you may be asked to authenticate. Once complete, you should be off and running. -Troubleshooting: +### Troubleshooting: 1. After step 2.4, don't forget to update the callback in the Connected App in your salesforce org. 1. You will not see anything at the home URL for your heroku app, when viewed from the browser. It will be a blank page. That is normal. 1. You will not be able to test your heroku app from your browser for the /account and other commands, since these only work for POST operations. You CAN do some limited testing using cURL: 'curl -X POST -H 'Content-type: application/json' --data '{"text":"Tycoo"}' http://127.0.0.1:5000/' . However, some slack vars like the user id will not be available.