Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updated to match the 2021 documentation, and remove deprecated approaches #4

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
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
1 change: 1 addition & 0 deletions Procfile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
web: npm start
72 changes: 41 additions & 31 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,71 +2,81 @@

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](http://coenraets.org/blog/2016/01/slack-salesforce-integration-part-2/) 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
- Connected App Name: SlackMySalesforce (or any name you want)
- API Name: SlackMySalesforce
- 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**

### 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/)
1. Click the button below to deploy the Slash Commands on 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. 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
- 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
### 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. 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. Click on **Create New App**, and choose 'from scratch'.

1. Click **Slash Commands**, and click **Add Configuration**
1. Choose a name: 'SlackMySalesforce', and choose your 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```.

### Step 4: Install and Launch your commands!

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. 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.
26 changes: 0 additions & 26 deletions app.json
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}
}
11 changes: 2 additions & 9 deletions modules/account.js
100644 → 100755
Original file line number Diff line number Diff line change
@@ -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";
Expand Down
Empty file modified modules/actions.js
100644 → 100755
Empty file.
8 changes: 1 addition & 7 deletions modules/case.js
100644 → 100755
Original file line number Diff line number Diff line change
@@ -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(":"),
Expand Down
8 changes: 1 addition & 7 deletions modules/contact.js
100644 → 100755
Original file line number Diff line number Diff line change
@@ -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";
Expand Down
3 changes: 2 additions & 1 deletion modules/force.js
100644 → 100755
Original file line number Diff line number Diff line change
@@ -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;

Expand Down
9 changes: 1 addition & 8 deletions modules/opportunity.js
100644 → 100755
Original file line number Diff line number Diff line change
@@ -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,
Expand Down
1 change: 1 addition & 0 deletions modules/slack-salesforce-auth.js
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -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}`);
};

Expand Down
9 changes: 1 addition & 8 deletions modules/whoami.js
100644 → 100755
Original file line number Diff line number Diff line change
@@ -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);

Expand Down
Loading