|
1 | | -# node-js-getting-started |
| 1 | +# Heroku Integration - Salesforce API Access (Node.js) |
2 | 2 |
|
3 | | -A barebones Node.js app using [Express](https://expressjs.com/). |
| 3 | +> **Important**: For use with the Heroku Integration and Heroku Eventing pilots only |
4 | 4 |
|
5 | | -This application supports the tutorials for both the [Cedar and Fir generations](https://devcenter.heroku.com/articles/generations) of the Heroku platform. You can check them out here: |
| 5 | +## Architecture Overview |
6 | 6 |
|
7 | | -* [Getting Started on Heroku with Node.js](https://devcenter.heroku.com/articles/getting-started-with-nodejs) |
8 | | -* [Getting Started on Heroku Fir with Node.js](https://devcenter.heroku.com/articles/getting-started-with-nodejs-fir) |
| 7 | +This sample application showcases how to extend a Heroku web application by integrating it with Salesforce APIs, enabling seamless data exchange and automation across multiple connected Salesforce orgs. It also includes a demonstration of the Salesforce Bulk API, which is optimized for handling large data volumes efficiently. |
9 | 8 |
|
10 | | -## Running Locally |
| 9 | +<img src="images/index.png" width="50%" alt="Index"> |
11 | 10 |
|
12 | | -Make sure you have [Node.js](http://nodejs.org/) and the [Heroku CLI](https://cli.heroku.com/) installed. |
| 11 | +## Requirements |
13 | 12 |
|
14 | | -```sh |
15 | | -$ git clone https://github.com/heroku/node-js-getting-started.git # or clone your own fork |
16 | | -$ cd node-js-getting-started |
17 | | -$ npm install |
18 | | -$ npm start |
| 13 | +* Heroku login |
| 14 | +* Heroku AppLink Pilot enabled |
| 15 | +* Heroku CLI installed |
| 16 | +* Heroku AppLink Pilot CLI plugin is installed |
| 17 | +* Salesforce CLI installed |
| 18 | +* Login information for one or more Scratch, Development or Sandbox orgs |
| 19 | +- Watch the [Introduction to the Heroku AppLink Pilot for Developers](https://www.youtube.com/watch?v=T5kOGNuTCLE) video |
| 20 | + |
| 21 | +## Local Development and Testing |
| 22 | + |
| 23 | +You do not need to deploy your application but you do need to configure it with Heroku. |
| 24 | + |
| 25 | +```bash |
| 26 | +heroku create |
| 27 | +heroku addons:create heroku-integration |
| 28 | +heroku salesforce:connect my-org --store-as-run-as-user |
| 29 | +heroku config:set CONNECTION_NAMES=my-org |
| 30 | +heroku config --shell > .env |
| 31 | +npm install |
| 32 | +npm start |
19 | 33 | ``` |
20 | 34 |
|
21 | | -Your app should now be running on [localhost:5006](http://localhost:5006/). |
| 35 | +Navigate to `http://localhost:5006` to observe a list of accounts from the connected org. |
22 | 36 |
|
23 | | -## Deploying to Heroku |
| 37 | +### Multiple Org Connections |
24 | 38 |
|
25 | | -Using resources for this example app counts towards your usage. [Delete your app](https://devcenter.heroku.com/articles/heroku-cli-commands#heroku-apps-destroy) and [database](https://devcenter.heroku.com/articles/heroku-postgresql#removing-the-add-on) as soon as you are done experimenting to control costs. |
| 39 | +To access multiple Salesforce orgs, repeat the `salesforce:connect` command above with different org logins and connection names, then update the `CONNECTION_NAMES` environment variable within the `.env` file with a comma delimiated list of connection names (example shown below). The sample code will automatically query for `Account` in each org and display the results. |
26 | 40 |
|
27 | | -### Deploy on [Cedar][cedar] |
| 41 | +``` |
| 42 | +CONNECTION_NAMES=my-org,my-org-sales-a |
| 43 | +``` |
28 | 44 |
|
29 | | -By default, apps use Eco dynos on [Cedar][cedar] if you are subscribed to Eco. Otherwise, it defaults to Basic dynos. The |
30 | | -Eco dynos plan is shared across all Eco dynos in your account and is recommended if you plan on deploying many small apps |
31 | | -to Heroku. Learn more about our low-cost plans [here](https://blog.heroku.com/new-low-cost-plans). |
| 45 | +### Bulk API Demo |
32 | 46 |
|
33 | | -Eligible students can apply for platform credits through our new [Heroku for GitHub Students program](https://blog.heroku.com/github-student-developer-program). |
| 47 | +This sample includes a demonstration of using the Salesforce Bulk API using connections formed with the Heroku Integration add-on. To see this in action obtain an org that is empty or that you are using for testing purposes only. Repeat the `salesforce:connect` command above using the connection name `empty-org` and then update the `CONNECTION_NAMES` environment variable within `.env` with a comma delimiated list of connection names (example shown above). |
| 48 | + |
| 49 | +When you visit the `/bulk-demo` endpoint, the application will check for existing bulk-loaded records. If none are found, it will start an asynchronous bulk load process. You will see output in the console similar to this: |
34 | 50 |
|
35 | 51 | ``` |
36 | | -$ heroku create |
37 | | -$ git push heroku main |
38 | | -$ heroku open |
| 52 | +Starting Bulk API process for 'empty-org' |
| 53 | +Bulk job status: { |
| 54 | + id: '750xx00000GtITrXXX', |
| 55 | + state: 'Queued', |
| 56 | + numberRecordsProcessed: 0, |
| 57 | + numberRecordsFailed: 0 |
| 58 | +} |
| 59 | +Bulk job status: { |
| 60 | + id: '750xx00000GtITrXXX', |
| 61 | + state: 'InProgress', |
| 62 | + numberRecordsProcessed: 500, |
| 63 | + numberRecordsFailed: 0 |
| 64 | +} |
| 65 | +Bulk job status: { |
| 66 | + id: '750xx00000GtITrXXX', |
| 67 | + state: 'JobComplete', |
| 68 | + numberRecordsProcessed: 1000, |
| 69 | + numberRecordsFailed: 0 |
| 70 | +} |
| 71 | +Job completed successfully. Processed 1000 records |
39 | 72 | ``` |
40 | 73 |
|
41 | | -### Deploy on [Fir][fir] |
| 74 | +Once the processing has completed, refresh the home page to observe the records that have been bulk loaded. Note that to avoid duplicate inserts, the sample code checks if prior bulk inserts have been run before starting a new job. |
42 | 75 |
|
43 | | -By default, apps on [Fir][fir] use 1X-Classic dynos. To create an app on [Fir][fir] you'll need to |
44 | | -[create a private space](https://devcenter.heroku.com/articles/working-with-private-spaces#create-a-private-space) |
45 | | -first. |
| 76 | +To reset the Bulk API demo and remove the test records, run the following command using the Salesforce CLI (assuming `empty-org` is also a known `sf` CLI authorized org alias): |
46 | 77 |
|
| 78 | +```bash |
| 79 | +echo "delete [SELECT Id FROM Account WHERE Name LIKE 'Bulk Account%'];" | sf apex run -o empty-org |
47 | 80 | ``` |
48 | | -$ heroku spaces:create <space-name> --team <team-name> --generation fir |
49 | | -$ heroku create --space <space-name> |
50 | | -$ git push heroku main |
51 | | -$ heroku open |
| 81 | + |
| 82 | +## Deploy to Heroku |
| 83 | + |
| 84 | +```bash |
| 85 | +heroku create |
| 86 | +heroku addons:create heroku-integration |
| 87 | +heroku salesforce:connect my-org --store-as-run-as-user |
| 88 | +heroku config:set CONNECTION_NAMES=my-org |
| 89 | +git push heroku main |
| 90 | +heroku open |
52 | 91 | ``` |
53 | 92 |
|
54 | | -## Documentation |
| 93 | +To access multiple Salesforce orgs, repeat the `salesforce:connect` command above with different org logins and connection names, then update the `CONNECTION_NAMES` with a comma delimiated list of connection names. The sample code will automatically query for `Account` in each org and display the results. |
| 94 | + |
| 95 | +## Technical Information |
55 | 96 |
|
56 | | -For more information about using Node.js on Heroku, see these Dev Center articles: |
| 97 | +* Salesforce APIs are always accessed in the context of the authenticated user defined at the time of connection through the `--store-as-run-as-user` CLI parameter. This means that only the objects and fields the user has access to can be accessed by the code. |
| 98 | +* This is a Node.js Express application, using EJS to render browser content. Other client libraries and frameworks can be used of course. |
| 99 | +* The application uses the `@heroku/salesforce-sdk-nodejs` package to handle Salesforce connections, authentication, and API interactions including SOQL queries and Bulk API operations. |
| 100 | +* The sample uses a custom environment variable `CONNECTION_NAMES` to enumerate the org connections to be used by the application. However this could easily be hardcoded in your own library code, or obtained from a configuration service or other preferred means of your choice. |
| 101 | +* The Bulk API demo intentionally showcases real-world duplicate handling scenarios. Some records may fail to insert due to Salesforce duplicate detection rules, which demonstrates proper error handling in bulk operations. Users can either accept this as a learning opportunity about integration resilience or temporarily disable duplicate rules in their Salesforce org for testing purposes. Successfully inserted records will still be visible on the main page, regardless of any duplicate-related failures. |
57 | 102 |
|
58 | | -- [Getting Started on Heroku with Node.js](https://devcenter.heroku.com/articles/getting-started-with-nodejs) |
59 | | -- [Getting Started on Heroku Fir with Node.js](https://devcenter.heroku.com/articles/getting-started-with-nodejs-fir) |
60 | | -- [Heroku Node.js Support](https://devcenter.heroku.com/articles/nodejs-support) |
61 | | -- [Node.js on Heroku](https://devcenter.heroku.com/categories/nodejs) |
62 | | -- [Best Practices for Node.js Development](https://devcenter.heroku.com/articles/node-best-practices) |
63 | | -- [Using WebSockets on Heroku with Node.js](https://devcenter.heroku.com/articles/node-websockets) |
| 103 | +## Other Samples |
64 | 104 |
|
65 | | -[cedar]: https://devcenter.heroku.com/articles/generations#cedar |
66 | | -[fir]: https://devcenter.heroku.com/articles/generations#fir |
| 105 | +| Sample | What it covers? | |
| 106 | +|--------|----------------| |
| 107 | +| [Salesforce API Access - Node.js](https://github.com/heroku-examples/heroku-integration-pattern-api-access-nodejs) | This sample application showcases how to extend a Heroku web application by integrating it with Salesforce APIs, enabling seamless data exchange and automation across multiple connected Salesforce orgs. It also includes a demonstration of the Salesforce Bulk API, which is optimized for handling large data volumes efficiently. | |
| 108 | +| [Extending Apex, Flow and Agentforce - Node.js](https://github.com/heroku-examples/heroku-integration-pattern-org-action-nodejs) | This sample demonstrates importing a Heroku application into an org to enable Apex, Flow, and Agentforce to call out to Heroku. For Apex, both synchronous and asynchronous invocation are demonstrated, along with securely elevating Salesforce permissions for processing that requires additional object or field access. | |
| 109 | +| [Scaling Batch Jobs with Heroku - Node.js](https://github.com/heroku-examples/heroku-integration-pattern-org-job-nodejs) | This sample seamlessly delegates the processing of large amounts of data with significant compute requirements to Heroku Worker processes. | |
| 110 | +| [Using Eventing to drive Automation and Communication](https://github.com/heroku-examples/heroku-integration-pattern-eventing-nodejs) | This sample extends the batch job sample by adding the ability to use eventing to start the work and notify users once it completes using Custom Notifications. These notifications are sent to the user's desktop or mobile device running Salesforce Mobile. Flow is used in this sample to demonstrate how processing can be handed off to low-code tools such as Flow. | |
0 commit comments