-
Notifications
You must be signed in to change notification settings - Fork 465
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
feat(integrations): add support for salesforce cdp #3363
Merged
khaliqgant
merged 13 commits into
master
from
kelvinwari/ext-218-add-support-for-salesforce-cdp
Feb 11, 2025
Merged
Changes from 10 commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
1f5616c
feat(integrations): add support for salesforce cdp
hassan254-prog 4048b23
fix validation
hassan254-prog c854758
Merge branch 'master' into kelvinwari/ext-218-add-support-for-salesfo…
hassan254-prog 059e747
Merge branch 'master' into kelvinwari/ext-218-add-support-for-salesfo…
bodinsamuel a4f5c86
rm
bodinsamuel de395c9
Merge branch 'master' into kelvinwari/ext-218-add-support-for-salesfo…
hassan254-prog 23357dd
Merge branch 'master' into kelvinwari/ext-218-add-support-for-salesfo…
hassan254-prog b732439
make two_step dynamic
hassan254-prog f4d8e11
fix failing tests
hassan254-prog 1db8f93
Merge branch 'master' into kelvinwari/ext-218-add-support-for-salesfo…
hassan254-prog 0d35259
rename fn
hassan254-prog c9f4258
Merge branch 'master' into kelvinwari/ext-218-add-support-for-salesfo…
hassan254-prog 8b0e349
fix merge conflict error
hassan254-prog File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
--- | ||
title: Salesforce (Data Cloud) | ||
sidebarTitle: Salesforce (Data Cloud) | ||
provider: salesforce-cdp | ||
--- | ||
|
||
import Overview from "/snippets/overview.mdx"; | ||
import PreBuiltTooling from "/snippets/generated/salesforce-cdp/PreBuiltTooling.mdx"; | ||
|
||
import PreBuiltUseCases from "/snippets/generated/salesforce-cdp/PreBuiltUseCases.mdx" | ||
|
||
<Overview /> | ||
<PreBuiltTooling /> | ||
<PreBuiltUseCases /> | ||
|
||
## Access requirements | ||
| Pre-Requisites | Status | Comment| | ||
| - | - | - | | ||
| Paid dev account | ❓ | | | ||
| Paid test account | ✅ | Requires an active Salesforce Data Cloud subscription. | | ||
| Partnership | ❓ | | | ||
| App review | ❓ | | | ||
| Security audit | ❓ | | | ||
|
||
|
||
## Setup guide | ||
|
||
_No setup guide yet._ | ||
|
||
<Tip>Need help getting started? Get help in the [community](https://nango.dev/slack).</Tip> | ||
|
||
<Note>Contribute improvements to the setup guide by [editing this page](https://github.com/nangohq/nango/tree/master/docs-v2/integrations/all/salesforce.mdx)</Note> | ||
|
||
|
||
## Useful links | ||
- [Salesforce Data Cloud OAuth documentation](https://developer.salesforce.com/docs/marketing/marketing-cloud-growth/guide/mc-connect-apis-data-cloud.html) | ||
- [Web API docs (their REST API)](https://developer.salesforce.com/docs/marketing/marketing-cloud-growth/references/mc-summary/mc-summary.html) | ||
|
||
<Note>Contribute useful links by [editing this page](https://github.com/nangohq/nango/tree/master/docs-v2/integrations/all/salesforce-cdp.mdx)</Note> | ||
|
||
## Connection Configuration in Nango | ||
|
||
- Salesforce (Data Cloud) uses a different API base URL, called the `instance_url`, for each customer. | ||
|
||
- Nango automatically retrieves the `instance_url` (e.g. `https://yourInstance.salesforce.com/`) from Salesforce and stores it in the [Connection config](/guides/api-authorization/authorize-in-your-app-default-ui#apis-requiring-connection-specific-configuration-for-authorization) for you. | ||
|
||
- If you use the Nango Proxy, it is automatically using the correct API base URL. But, if needed, you can retrieve the `instance_url` with the [backend SDK](/reference/sdks/node#get-a-connection-with-credentials) or [Connections API](/reference/api/connection/get). | ||
|
||
## API gotchas | ||
|
||
<Note>Contribute API gotchas by [editing this page](https://github.com/nangohq/nango/tree/master/docs-v2/integrations/all/salesforce-cdp.mdx)</Note> | ||
|
||
## Going further | ||
|
||
<Card title="Connect to Salesforce (Data Cloud)" icon="link" href="/integrations/all/salesforce-cdp/connect" horizontal> | ||
Guide to connect to Salesforce (Data Cloud) using Connect UI | ||
</Card> | ||
|
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
--- | ||
title: Salesforce (Data Cloud) - How do I link my account? | ||
sidebarTitle: Salesforce (Data Cloud) | ||
--- | ||
|
||
# Overview | ||
|
||
To authenticate with Salesforce (Data Cloud), you need: | ||
1. **Encoded JWT** - A unique string that enables client applications to access Salesforce (Data Cloud) resources without requiring users to provide their credentials. | ||
|
||
This guide will walk you through generating your encoded JWT within Salesforce. | ||
|
||
### Prerequisites: | ||
|
||
- You must have a Salesforce account with an active Data Cloud subscription. | ||
|
||
### Instructions: | ||
|
||
#### Step 1: Generating your Encoded JWT | ||
- Interacting with the Data Cloud API requires a signed digital certificate. You can use a private key and certificate issued by a certification authority. Alternatively, you can use OpenSSL to create a key and a self-signed digital certificate. Here's how to create a self-signed certificate with OpenSSL. | ||
1. Run the following command to generate a 2048-bit RSA private key: | ||
|
||
``` | ||
openssl genrsa 2048 > host.key && chmod 400 host.key | ||
``` | ||
2. Use the private key to sign a certificate. Enter details about the certificate, or press Enter at each prompt to accept the default value: | ||
``` | ||
openssl req -new -x509 -nodes -sha256 -days 365 -key host.key -out host.crt | ||
``` | ||
- Now that you have created the above signed certificate, you will now need to create an app in Salesforce and upload the above signed certificate. | ||
3. Login to your salesforce account and In the Setup, in the Quick Find box, enter apps, and then select **App Manager**. | ||
<img src="/integrations/all/salesforce-cdp/app_manager.png" /> | ||
4. Click **New Connected App**. | ||
5. For Connected App Name, enter an app name and your email address. | ||
6. Select **Enable OAuth Settings**. | ||
7. For **Callback URL**, enter `http://localhost:1717/OauthRedirect`. | ||
8. Select Use **digital signatures**, and then click **Browse**. | ||
9. Select your above self-signed certificate **(host.crt)**. | ||
10. Add the OAuth scopes that are necessary for your use case. For example, if your use case requires you to ingest content, add the **Manage Data Cloud Ingestion API data (cdp_ingest_api)** scope. | ||
11. Click **Save**. | ||
<img src="/integrations/all/salesforce-cdp/creating_app.png" /> | ||
12. Click **Manage Consumer Details**. | ||
<img src="/integrations/all/salesforce-cdp/consumer_keys.png" /> | ||
13. Copy the **Consumer Key** value. This value is also referred to as the **client ID**. You will use the client ID value when you are generaying your encoded (JWT) in the step below. | ||
8. Now that your certificate is registered with Salesforce, you need to generate an encoded JWT. You can use the code from the following script to generate your encoded JWT offline. | ||
``` | ||
import { readFileSync } from 'fs'; | ||
import jwt from 'jsonwebtoken'; | ||
import readlineSync from 'readline-sync'; | ||
|
||
const getUserInput = () => { | ||
const clientId = readlineSync.question('Please enter your Salesforce client ID: '); | ||
const username = readlineSync.question('Please enter your Salesforce username: '); | ||
return { clientId, username }; | ||
}; | ||
|
||
const readPrivateKey = (path) => { | ||
try { | ||
return readFileSync(path, 'utf8'); | ||
} catch (error) { | ||
console.error(`Error reading private key from ${path}:`, error); | ||
throw error; | ||
} | ||
}; | ||
|
||
const createJwtClaims = (clientId, username) => { | ||
const currentTime = Math.floor(Date.now() / 1000); | ||
const expiry = currentTime + (10 * 365 * 24 * 60 * 60); | ||
|
||
return { | ||
iss: clientId, | ||
sub: username, | ||
aud: 'https://#.salesforce.com', | ||
exp: expiry, | ||
}; | ||
}; | ||
|
||
const generateJwtToken = (claims, privateKey) => { | ||
try { | ||
return jwt.sign(claims, privateKey, { algorithm: 'RS256' }) | ||
} catch (error) { | ||
console.error('Error signing assertion:', error); | ||
throw error; | ||
} | ||
}; | ||
|
||
const generateJwtAssertion = () => { | ||
const { clientId, username } = getUserInput(); | ||
const privateKeyPath = 'host.key'; | ||
|
||
const privateKey = readPrivateKey(privateKeyPath); | ||
|
||
const claims = createJwtClaims(clientId, username); | ||
|
||
const token = generateJwtToken(claims, privateKey); | ||
|
||
console.log('Generated Salesforce assertion:', token); | ||
}; | ||
|
||
generateJwtAssertion(); | ||
|
||
|
||
``` | ||
- Run the script above in the same directory where your certificates were generated. It will prompt you for your **Client ID** obtained when creating a connected app and your **Username**, used when signing in to Salesforce. An encoded JWT will then be generated. | ||
|
||
**Note**: The generated **Encoded JWT** is valid for ten years. After this period, you will need to regenerate your encoded JWT and reauthenticate. | ||
|
||
#### Step 2: Enter credentials in the Connect UI | ||
|
||
Once you have your **Encoded JWT**: | ||
1. Open the form where you need to authenticate with Salesforce (Data Cloud). | ||
2. Enter your **Encoded JWT** in the designated field. | ||
3. Submit the form, and you should be successfully authenticated. | ||
|
||
<img src="/integrations/all/salesforce-cdp/form.png" style={{maxWidth: "450px" }}/> | ||
|
||
You are now connected to Salesforce (Data Cloud). | ||
|
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
40 changes: 40 additions & 0 deletions
40
docs-v2/snippets/generated/salesforce-cdp/PreBuiltTooling.mdx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
## Pre-built tooling | ||
<AccordionGroup> | ||
<Accordion title="✅ Authorization"> | ||
| Tools | Status | | ||
| - | - | | ||
| Pre-built authorization (Two Step) | ✅ | | ||
| Pre-built authorization UI | ✅ | | ||
| Custom authorization UI | ✅ | | ||
| End-user authorization guide | ✅ | | ||
| Expired credentials detection | ✅ | | ||
</Accordion> | ||
<Accordion title="✅ Read & write data"> | ||
| Tools | Status | | ||
| - | - | | ||
| Pre-built integrations | 🚫 (time to contribute: <48h) | | ||
| API unification | ✅ | | ||
| 2-way sync | ✅ | | ||
| Webhooks from Nango on data modifications | ✅ | | ||
| Real-time webhooks from 3rd-party API | 🚫 (time to contribute: <48h) | | ||
| Proxy requests | ✅ | | ||
</Accordion> | ||
<Accordion title="✅ Observability & data quality"> | ||
| Tools | Status | | ||
| - | - | | ||
| HTTP request logging | ✅ | | ||
| End-to-type type safety | ✅ | | ||
| Data runtime validation | ✅ | | ||
| OpenTelemetry export | ✅ | | ||
| Slack alerts on errors | ✅ | | ||
| Integration status API | ✅ | | ||
</Accordion> | ||
<Accordion title="✅ Customization"> | ||
| Tools | Status | | ||
| - | - | | ||
| Create or customize use-cases | ✅ | | ||
| Pre-configured pagination | 🚫 (time to contribute: <48h) | | ||
| Pre-configured rate-limit handling | 🚫 (time to contribute: <48h) | | ||
| Per-customer configurations | ✅ | | ||
</Accordion> | ||
</AccordionGroup> |
5 changes: 5 additions & 0 deletions
5
docs-v2/snippets/generated/salesforce-cdp/PreBuiltUseCases.mdx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
## Pre-built integrations | ||
|
||
_No pre-built integration yet (time to contribute: <48h)_ | ||
|
||
<Tip>Not seeing the integration you need? [Build your own](https://docs.nango.dev/guides/custom-integration-builder/overview) independently.</Tip> |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
step1 is what in this context?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
step1 refers to the response from the initial request made before any additional steps, if provided. In subsequent steps, parameters are accessed dynamically using
step{request_number}
.