> ## Documentation Index
> Fetch the complete documentation index at: https://docs.refold.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Build Salesforce Integration

In this guide, we will walk through the essential steps required to build a Salesforce integration using the Refold platform. This process involves three major steps i.e. User Authentication with Salesforce, Creating Workflows and Using workflows for users.

## Authenticating with Salesforce integration

To get started, first you need to enable the Salesforce integration in your account and also setup some basic processes.

<Steps>
  <Step title="Enable the Salesforce App">
    ### Step 1: Enable the Salesforce App

    After setting up your account, the next step is to enable the Salesforce app in your Refold account.

    <Note>Apps cannot be enabled using the API. You will need to enable the app through the UI.</Note>

    To enable the Salesforce app:

    Navigate to `Apps` in Refold and search for **Salesforce** and enable the app by clicking on the `Go Live` button in the top right corner.

    <img height="200" src="https://mintcdn.com/cobalt-55/C3P12YsraPVmMY5N/images/Examples/salesforce/enable_salesforce.png?fit=max&auto=format&n=C3P12YsraPVmMY5N&q=85&s=d1879a6368284e9cde411e8c6cf53927" alt="Enable Salesforce App" data-path="images/Examples/salesforce/enable_salesforce.png" />

    Now, go to `Settings` and provide the **Client ID** and **Client Secret** of your Salesforce OAuth app and click on `Save`.

    <Tip>
      Follow the steps given [here](https://docs.gocobalt.io/resources/integration-providers/salesforce) to get your credentials.
    </Tip>

    Once the app is enabled, you can proceed to create and manage workflows and linked accounts associated with Salesforce.
  </Step>

  <Step title="Create a Linked Account">
    ### Step 2: Create a Linked Account

    A Linked Account in Refold represents the end-users or customers who will use the integration through the platform. Each Linked Account requires a unique linked\_account\_id, which typically corresponds to an ID from your internal data model (e.g., a user or account ID).

    <Tip>
      Learn more about Linked Accounts [here](/build/basics/linked_account).
    </Tip>

    To upsert (create or update) a Linked Account, use the following API call:

    <CodeGroup>
      ```bash cURL theme={null}
      curl --request PUT \
        --url https://api.gocobalt.io/api/v2/public/linked-account \
        --header 'Content-Type: application/json' \
        --header 'x-api-key: <api-key>' \
        --data '{
        "linked_account_id": "<string>",
        "name": "<string>"'
      ```
    </CodeGroup>

    | Param               | Required  | Type   | Description                |
    | ------------------- | --------- | ------ | -------------------------- |
    | linked\_account\_id | Mandatory | String | Unique customer identifier |
    | name                | Optional  | String | Name of the customer       |

    You can check the Linked Accounts in your Refold account by navigating to the **Linked Accounts** section in the side menu.

    Once the Linked Account is successfully created or updated, it will be ready for authentication in the next step.
  </Step>

  <Step title="Generate Session Token for your Linked Account">
    ### Step 3: Generate Token

    After creating a Linked Account, the next step is to generate a session token. Session tokens help protect your Refold API key and manage end-customer tokens more securely.

    To create a session token, use the following API call:

    <CodeGroup>
      ```JavaScript cURL theme={null}
          curl --request POST \
        --url https://api.gocobalt.io/api/v2/public/session-token \
        --header 'Content-Type: application/json' \
        --header 'x-api-key: <api-key>' \
        --data '{
        "linked_account_id": "<string>"
      }'
      ```
    </CodeGroup>

    This session token will be included in subsequent requests to Refold APIs to authenticate and authorize the actions.
  </Step>

  <Step title="Open Hosted Portal Auth Flow">
    ### Step 4: Open Hosted Portal Auth Flow

    Next, you will need to generate a Hosted URL that your users will use to authenticate with Salesforce. Refold securely stores the credentials and handles API calls on behalf of your users.

    Use the following API call to generate the Hosted URL:

    <CodeGroup>
      ```JavaScript cURL theme={null}
      curl --request POST \
        --url https://api.gocobalt.io/api/v2/public/connect-url \
        --header 'Content-Type: application/json' \
        --header 'x-api-key: <api-key>' \
        --data '{
        "color": "<string>",
        "bgColor": "<string>",
        "name": "<string>"
      }'
      ```
    </CodeGroup>

    The response will return a Hosted URL that your users can visit to authenticate and connect their Salesforce accounts.
    <Info> Hosted Portal is a no-code solution provided by Refold that removes the need to build your own UI for handling integration authentication and configuration. </Info>
  </Step>

  <Step title="Authenticate Using Hosted Portal">
    ### Step 5: Perform OAuth Authentication

    Visit the Hosted URL provided in the API response. The Hosted Portal will display all the integrations you have enabled, including Salesforce.

    To authenticate:

    * Navigate to the Salesforce integration in the portal.
    * Click Connect to begin the authentication process and allow consent to permissions requested.
    * After completing the flow, you will be redirected back to the Hosted Portal with a confirmation that the account is successfully connected.
  </Step>
</Steps>

<Check>
  You have successfully authenticated with Salesforce integration.

  The next step is to create workflows for your use-case.
</Check>

## Creating Workflows in Salesforce

There are 3 major categories of workflows that you can create in any integration.

<CardGroup cols={2}>
  <Card title="Data Import from Salesforce" icon="download">
    Sync data from Salesforce to your system.
  </Card>

  <Card title="Push Data to Salesforce" icon="upload">
    Create data on Salesforce from your system.
  </Card>

  <Card title="2-way sync between Salesforce and you" icon="arrows-left-right-to-line">
    Keep the data between Salesforce and your system in sync.
  </Card>
</CardGroup>

Let's look at a sample workflow for each case.

#### Data Import from Salesforce

Consider a use-case where you want to sync all the opportunities present in Salesforce to your system.

In the Salesforce integration, go to `Workflows` and create a new workflow by clicking on `+Add Workflow` button and name it as `Sync Opportunities`.

<Accordion title="Data Import from Salesforce">
  Follow the steps given to build the workflow:

  <Steps>
    <Step title="Add Trigger in Start Node">
      All workflows start with a trigger, which determines when the workflow will run and how data is passed into the workflow.
      For this workflow we will use the Event Based trigger.

      <Tip>
        Learn more about the triggers and its types [here](https://docs.gocobalt.io/build/workflow/triggering_workflow).
      </Tip>

      Click on the `Start Node`, select your native app option and click on `+ Create New Event`.

      <img height="200" src="https://mintcdn.com/cobalt-55/C3P12YsraPVmMY5N/images/Examples/salesforce/event_salesforce.png?fit=max&auto=format&n=C3P12YsraPVmMY5N&q=85&s=92e259917a13a5ce7d1f7a08e075b681" alt="Event for workflow" data-path="images/Examples/salesforce/event_salesforce.png" />

      Give a name to your event and keep the payload as an empty object.
    </Step>

    <Step title="Add Salesforce Node">
      Now to fetch all the opportunities present in your user's account, we need to call Salesforce API.

      Click on `Nodes` option in the top right and drag the Salesforce Node from **Native Apps** section to the workflow builder. Connect this node with Start Node.

      <img height="200" src="https://mintcdn.com/cobalt-55/C3P12YsraPVmMY5N/images/Examples/salesforce/action_salesforce.png?fit=max&auto=format&n=C3P12YsraPVmMY5N&q=85&s=754d7de08157a1d1224f2da26b475a48" alt="Choose Node" data-path="images/Examples/salesforce/action_salesforce.png" />
    </Step>

    <Step title="Fetch Opportunities from Salesforce using Action">
      Click on the Salesforce Node and select `Get Entity with SOQL` action.

      <img height="200" src="https://mintcdn.com/cobalt-55/h1VL7v_8HaANGLZ5/images/Examples/salesforce/soql_salesforce.png?fit=max&auto=format&n=h1VL7v_8HaANGLZ5&q=85&s=ca5cf031f4b31f9e86ad964a4830167c" alt="SOQL Action for workflow" data-path="images/Examples/salesforce/soql_salesforce.png" />

      Add the following under `SOQL query` field and click on `Save`.

      ```
      SELECT Id,Amount,AccountId, CloseDate,ContactId,Description,ExpectedRevenue,LeadSource, Name, OwnerId, Probability,StageName,Type FROM Opportunity
      ```

      <Info>
        You can provide any additonal fields that you want to fetch about opportunities from Salesforce by adding it to this query.
      </Info>
    </Step>

    <Step title="Add Custom Code node">
      We have fetched all the opportunities, but you might require to structure it as a payload which your platform can receive. Let's do this using **Custom Code** node.

      Drag the Custom Code from the Utility Nodes section onto the workflow builder and connect it with Salesforce node.
    </Step>

    <Step title="Mapping Opportunity fields">
      Click on `+ Map Fields` under Input Parameters, add key name as `deals` and in value we will provide the response received through Salesforce node which will be restructured.

      In `Value`, select **Nodes** tab under Insert Variable and click on `+` of the Salesforce Node.

      <img height="200" src="https://mintcdn.com/cobalt-55/C3P12YsraPVmMY5N/images/Examples/salesforce/map_salesforce.png?fit=max&auto=format&n=C3P12YsraPVmMY5N&q=85&s=c790dbf9166b578236247f6d745ba22c" alt="Mapping API Response for workflow" data-path="images/Examples/salesforce/map_salesforce.png" />

      You can now do mapping using JavaScript code. Try the sample code provided below:

      ```
      function yourFunction(params) {
      const res = params.deals.map(ele=>{
            const output =  {
                id: ele.Id,
                title: ele.Name,
                description: ele.Description || 'Description not available',
                close_date: ele.CloseDate,
                amount: ele.Amount,
                expected_revenue: ele.ExpectedRevenue,
                status: ele.StageName

            }
            return output
        })
        return {"result": res || [] }
      }
      ```
    </Step>

    <Step title="API Proxy in Workflow">
      You have successfully fetched all opportunities and structured the payload. Now to receive it in your server, you need to configure an API Proxy.

      In Refold Dashboard, navigate to `Developer` > `API Proxies` and click on `New Action`. Configure an API endpoint, where you want to receive the response.

      If you want to test, go to [webhook.site](https://webhook.site/) and copy `Your unique URL` and configure this as a POST Request and `Save`.

      <img height="200" src="https://mintcdn.com/cobalt-55/h1VL7v_8HaANGLZ5/images/Examples/salesforce/proxy_salesforce.png?fit=max&auto=format&n=h1VL7v_8HaANGLZ5&q=85&s=a685febbf54d4054ef47f807f3ab4bfe" alt="Configuring API Proxy workflow" data-path="images/Examples/salesforce/proxy_salesforce.png" />

      <Tip>Learn more about API Proxies [here](https://docs.gocobalt.io/build/basics/proxies).</Tip>
    </Step>

    <Step title="Use API Proxy in Workflow">
      From Native Apps nodes, add your org's Node and connect it with Custom Code.

      Click on the node and select the API Proxy that you created from the Actions. Add the response from Custom Code node in data field and click on `Save`.

      <Note>
        Ensure that you add a field in the API Proxy where you can pass the JSON data and then added it to the API Call body as well in the POST request.
      </Note>

      <img height="200" src="https://mintcdn.com/cobalt-55/h1VL7v_8HaANGLZ5/images/Examples/salesforce/proxy_workflow.png?fit=max&auto=format&n=h1VL7v_8HaANGLZ5&q=85&s=c8179720627effe0c68a46384aa15918" alt="Configuring API Proxy in the workflow" data-path="images/Examples/salesforce/proxy_workflow.png" />
    </Step>
  </Steps>

  <Check>
    Hurray!!

    You have successfully created a Salesforce workflow to sync all the opportunities to your system.
  </Check>
</Accordion>

#### Push Data to Salesforce

Consider a use-case where you want to create a contact present in your system to Salesforce.

This workflow will be fired when you send an Event with the payload of the contact to be added.

In the Salesforce integration, go to `Workflows` and create a new workflow by clicking on `+Add Workflow` button and name it as `Create New Contact`.

<Accordion title="Push Data to Salesforce">
  Follow the steps given to build the workflow:

  <Steps>
    <Step title="Add Trigger in Start Node">
      All workflows start with a trigger, which determines when the workflow will run and how data is passed into the workflow.
      For this workflow we will use the Event Based trigger.

      <Tip>
        Learn more about the triggers and its types [here](https://docs.gocobalt.io/build/workflow/triggering_workflow).
      </Tip>

      Click on the `Start Node`, select your native app option and click on `+ Create New Event`.

      <img height="200" src="https://mintcdn.com/cobalt-55/C3P12YsraPVmMY5N/images/Examples/salesforce/event_salesforce_add.png?fit=max&auto=format&n=C3P12YsraPVmMY5N&q=85&s=e9bc9cf0ad229b19ee6518b8d29cee85" alt="Event for workflow" data-path="images/Examples/salesforce/event_salesforce_add.png" />

      Give a name to your event and provide all the data related to the contact in the payload.
    </Step>

    <Step title="Add Salesforce Node">
      Now to create a new contact in Salesforce, we need to call Salesforce API.

      Click on `Nodes` option in the top right and drag the Salesforce Node from **Native Apps** section to the workflow builder. Connect this node with Start Node.
    </Step>

    <Step title="Add Action in node">
      Click on Salesforce Node and add the `Create Contact` action.
      To provide the data in all the fields from your Event payload, just click on a field and from the **Event** tab under Insert Variable, select the fields from the body that you sent as payload.

      <img height="200" src="https://mintcdn.com/cobalt-55/C3P12YsraPVmMY5N/images/Examples/salesforce/create_salesforce.png?fit=max&auto=format&n=C3P12YsraPVmMY5N&q=85&s=a8b48b74b14597322168c2559b4872c6" alt="Create Contact action" data-path="images/Examples/salesforce/create_salesforce.png" />

      <Warning>
        Ensure that all the mandatory fields in the action are filled, else the Salesforce API will give error.
      </Warning>
    </Step>
  </Steps>

  <Check>
    Hurray!!

    You have successfully created a Salesforce workflow to create a new contact.
  </Check>
</Accordion>

#### 2-way sync between Salesforce and you (Webhooks)

For bi-directional sync, usually three workflows are required:

* **Workflow for Initial sync** where all the records are fetched from Salesforce.
  This is the same workflow as Data Import workflow that we created [here](/implementation/examples/build_salesforce#data-import-from-salesforce).

* **Workflow to push record** in Salesforce when a new record is created on your platform.

  We created this workflow of Push Data [here](/implementation/examples/build_salesforce#push-data-to-salesforce).

* **Workflow to update records** in your system whenever a contact gets created or updated in Salesforce.

<Accordion title="Update records workflow">
  To perform a real time update whenever a change happens in Salesforce, we will use Salesforce Webhook as a trigger for our workflow.

  Follow the steps given below to setup your workflow:

  <Steps>
    <Step title="Add Salesforce Webhook as trigger">
      In the Start Node, select **Salesforce** as the trigger and select `Contact Created` event.

      <Tip>
        Similarly, you can use the **Contact Updated** event to get notified whenever a contact is updated in Salesforce.
      </Tip>

      <img height="200" src="https://mintcdn.com/cobalt-55/h1VL7v_8HaANGLZ5/images/Examples/salesforce/trigger_salesforce.png?fit=max&auto=format&n=h1VL7v_8HaANGLZ5&q=85&s=53cf22b33e7d7b725a97827bab300e43" alt="Contact created trigger event" data-path="images/Examples/salesforce/trigger_salesforce.png" />

      By using the Contact Created trigger, you will receive data as an event payload about any new contact created in Salesforce in real time.
    </Step>

    <Step title="Send New Contact data to your system">
      Send the data that we received about the new contact to your system to perform real time sync.

      From Native Apps nodes, add your org's Node and connect it with Start Node.

      Click on the node and select the API Proxy that you created from the Actions to receive new contact info. Add the response from Event using **Insert Variables** and click on `Save`.

      <img height="200" src="https://mintcdn.com/cobalt-55/h1VL7v_8HaANGLZ5/images/Examples/salesforce/new_salesforce.png?fit=max&auto=format&n=h1VL7v_8HaANGLZ5&q=85&s=12f0dbb1954689a1246666f8ae58c47c" alt="Send Contact created data" data-path="images/Examples/salesforce/new_salesforce.png" />

      <Note>
        Ensure that you add a field in the API Proxy where you can pass the data and then added it to the API Call body as well in the POST request.
      </Note>
    </Step>
  </Steps>

  <Check>
    Hurray!

    You have successfully created a workflow which will inform you whenever a new contact is created in Salesforce.
  </Check>
</Accordion>

<Check>
  You have successfully created the workflows for your use case.

  Next step is to enable and execute those workflows for your Linked Accounts.
</Check>

## Executing the Workflows

To run these workflows for your users or Linked Accounts, you need to do the following steps:

<Steps>
  <Step title="Create Config for Linked Account">
    Config is a customization that you store for each integration of your end-customers.

    ## Create Config

    You can create config for the Linked Account through the Hosted Portal SDKs or using the APIs.

    You can use the **.config()** method or the [Create Config API](https://docs.gocobalt.io/api-reference/config/find-or-create-config) which returns the specified config or creates one if it doesn't exist for the Linked Account.

    Make a request with the  `Application Slug` and `linked_account_id` as mandatory fields for it. You can request in the following way:

    <CodeGroup>
      ```JavaScript .config() theme={null}
      cobalt.config({
        slug: "salesforce",
        config_id: "OPTIONAL_ID_FOR_THIS_CONFIG",
        labels: {}, // optional dynamic labels
      })
      ```

      ```JavaScript cURL theme={null}
      curl --request POST \
        --url https://api.gocobalt.io/api/v2/public/config \
        --header 'Content-Type: application/json' \
        --header 'linked_account_id: <linked_account_id>' \
        --header 'x-api-key: <api-key>' \
        --data '{
        "slug": "<string>",
        "config_id": "<string>",
        "labels": {}
      }'
      ```
    </CodeGroup>

    It will return information about config of the application for the Linked Account and provides you with all the published workflows and settings input for the user required to execute the workflow.

    ```JavaScript Response theme={null}
    {
    	"slug": "salesforce",
    	"config_id": "OPTIONAL_ID_FOR_THIS_CONFIG",
    	"fields": [],
    	"workflows": [
    		{
    			"id": "64d1fac58716dc5065127ffe",
    			"name": "Sync Opportunities",
    			"description": "",
    			"enabled": false,
    			"fields": []
    		}
    	],
    	"field_errors": []
    }
    ```
  </Step>

  <Step title="Enable Workflow">
    Now you need to enable the workflow for your Linked account. You can either ask the user to enable them or you can do so for them by using the [Update Config API](https://docs.gocobalt.io/api-reference/config/update-config) or **.updateconfig()** method.

    Make the following request:

    <CodeGroup>
      ```JavaScript Method theme={null}
      cobalt.updateConfig({
        slug: "salesforce",
        config_id: "OPTIONAL_ID_FOR_THIS_CONFIG",
        fields: {
          "64da0b57c9ae95561bb0a24d": "C044U7Q074J"
        },
        workflows: [
          {
            id: "64d1fac58716dc5065127ffe",
            enabled: true,
            fields: {
              "64da0b57c9ae95561bb0a24f": "C044U7Q074J"
            }

          }
        ]
      })
      ```

      ```JavaScript cURL theme={null}
      curl --request PUT \
        --url https://api.gocobalt.io/api/v2/public/config \
        --header 'Content-Type: application/json' \
        --header 'linked_account_id: <linked_account_id>' \
        --header 'x-api-key: <api-key>' \
        --data '{
        "slug": "<string>",
        "config_id": "<string>",
        "fields": {
          "64abea6d941ba774d124b19c": "<string>"
        },
        "workflows": [
          {
            "id": "<string>",
            "enabled": true,
            "fields": {
              "64abea6d941ba774d124b19c": "<string>"
            }
          }
        ]
      }'
      ```
    </CodeGroup>

    In response, you get the updated config information for the application.
  </Step>

  <Step title="Third Step">
    Once the required workflows are enabled, you need to fire event to start execution. You can use the [Trigger Event for app](https://docs.gocobalt.io/api-reference/event/trigger-event) API with the following request:

    ```JavaScript cURL theme={null}
    curl --request POST \
    --url https://api.gocobalt.io/api/v2/public/event/:slug \
    --header 'Content-Type: application/json' \
    --header 'linked_account_id: <linked_account_id>' \
    --header 'x-api-key: <api-key>' \
    --data '{
    "event": "<string>",
    "payload": {}
    }'
    ```
  </Step>

  <Step title="Check Execution Logs">
    Once the workflow execution has been fired, you can check the Logs of the workflow [here](https://app.gocobalt.io/logs).

    <Tip>
      Learn more about logs and observability [here](https://docs.gocobalt.io/maintain/logs).
    </Tip>
  </Step>
</Steps>

<Check>
  Congratulations!!

  You have successfully created a Salesforce integration and executed it for your users.
</Check>
