---
title: "Salesforce collector"
canonical: "https://docs.devo.com/space/latest/94657195/Salesforce%20collector"
format: markdown
---
> Macro (toc)

## Overview

[Salesforce](https://www.salesforce.com/) is a customer relationship management (CRM) solution that brings companies and customers together. It's one integrated CRM platform that gives all the departments, including marketing, sales, commerce, and service. This collector provides the possibility to integrate Salesforce with the Devo Platform making it easy to query and analyze the Salesforce data, view it in the pre-configured Activeboards, or customize them to enable Enterprise IT and Cybersecurity teams to make impactful data-driven decisions.

The Devo Salesforce Collector enables customers to retrieve data from the “Salesforce Objects API“ (a.k.a. `SObjects`). The collector processes the Salesforce API responses and sends them to the Devo platform which then categorizes all data received on tables along rows and columns in your Devo domain.

> ⚠️ This collector works only with the “Enterprise”, “Performance”, “Unlimited”, “Developer”, and “[http://Database.com](http://Database.com) ” Salesforce editions. Please ensure that you have one of the listed editions.

## Data source description

Listed in the table below are the `SObject` names, their details, and how the Devo Platform treats the data. You can see that all the `SObject` events (JSON documents) fall under the `crm.salesforceobjects` technologies, except for the “event log files” processed events, which fall under the `crm.salesforce` one:

| **Product** | **Data source** | **Devo table** | **Collector service** | **Related remote endpoint** | **Description** |
| --- | --- | --- | --- | --- | --- |
| Salesforce | Account | `crm.salesforceobjects.account` | `Account` | The main endpoint is `GET https://{instance}/services/data/v{version}/{query_method}?q={query}`, where:<br>- `{instance}` is your Salesforce domain name.
- `{version}` is an internal variable that controls the API's versioning.
- `{query_method}` can be `query` or `queryAll`.
- `{query}` represents an SQL-like query that is composed in the following way:
  - `@fields` represents the list of fields to be retrieved by each Collector Service.
  - `@table` is each Collector Service.
  - `@key` should be a date field and is used for filtering and ordering.
  - `@date_filter` is internally controlled by the collector.<br>Check the “Running the data collector” sections for more information. | Represents an individual account, which is an organization or person involved with your business (such as customers, competitors, and partners). |
| Case | `crm.salesforceobjects.case` | `Case` | Represents a case, which is a customer issue or problem. |
| Content Version | `crm.salesforceobjects.contentversion` | `ContentVersion` | Represents a specific version of a document in Salesforce CRM Content or Salesforce Files. |
| Dashboard | `crm.salesforceobjects.dashboard` | `Dashboard` | Represents a dashboard, which shows data from custom reports as visual components. |
| Login History | `crm.salesforceobjects.loginhistory` | `LoginHistory` | Represents the login history for all successful and failed login attempts for organizations and enabled portals. |
| Opportunity | `crm.salesforceobjects.opportunity` | `Opportunity` | Represents an opportunity, which is a sale or pending deal. |
| Report | `crm.salesforceobjects.report` | `Report` | Represents a report, a set of data that meets certain criteria, displayed in an organized way. |
| User | `crm.salesforceobjects.users` | `User` | Represents a user in your organization. |
| Event Log Files | - `crm.salesforceobjects.eventlogfile`
- `crm.salesforce.<event_type>` if file processing is enabled | `EventLogFiles` | Represents event log files for event monitoring.<br>Possibility to set `interval` to `hourly` or `daily` (default) from the user configuration.<br>> ⚠️ **Risk of reaching rate limits**. Enabling file processing may cause a high number of requests against the API. |
| Setup Audit Trail | `crm.salesforceobjects.setupaudittrail` | `SetupAuditTrail` | Represents changes you or other admins made in your org’s Setup area for at least the last 180 days. For more information, see SetupAuditTrail in the [Object Reference for the Salesforce Platform](https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_setupaudittrail.htm). |

## External links

| **References** | **Details** | **Link** |
| --- | --- | --- |
| Salesforce `SObjects` | API guidelines and documentation for Salesforce Objects. | [Salesforce Developers](https://developer.salesforce.com/docs/atlas.en-us.sfFieldRef.meta/sfFieldRef) |
| Event types for `EventLogFiles` | List of all the possible event types that are ingested in the `crm.salesforce.<event_type>` tables.<br>> ℹ️ All `event_type`s will be in lowercase and without spaces. | [Salesforce Developers](https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_eventlogfile_supportedeventtypes.htm) |

## Vendor setup

The Salesforce Collector works over the Salesforce API. We need to enable API access and ensure its permissions in your Salesforce account to allow the collector to get the data correctly.

> ℹ️ The steps and images explained here have been done using the Lightning interface.

## Enable API access on the account

> 📝 In case you encounter any difficulties in this step, we suggest you visit the corresponding article maintained by Salesforce [Help And Training Community](https://help.salesforce.com/s/articleView?id=000331470&type=1)

### Steps

1. Go to [Login | Salesforce](https://login.salesforce.com/) and sign in with your account.
2. In the top-right corner, click and select

| **Steps** | **Snapshot** |
| --- | --- |
| Login to your Salesforce account. |  |
| Click on the gear icon (near the user icon) and select “Service Setup“. | ![image-20250616-162434.png](media://73ea336a-74a1-4f3e-9840-047d738f470e) |
| In the setup interface, go to the left tree and deploy “Users“ and select “Users“. | ![image-20250616-162523.png](media://d196383d-843b-4115-b902-c8c039846713) |
| Here, find the user you want to enable the API Access for and click on its associated user profile (its corresponding value from the **Profile** column). | ![image-20250616-162541.png](media://130c7d30-8dc4-4da4-8cf4-3476109ec731) |
| In the profile screen, click on “Edit“.<br>> 📝 Take into account that you will be modifying the user’s profile settings, so any other user that has this same profile will have the same settings applied. | ![image-20250616-162612.png](media://d5dd8f4b-e35e-4c7a-b1a8-bae80ecc357f) |
| Scroll down to “Administrative Permissions“, and search for “API Enabled“. | ![image-20250616-162654.png](media://cc9a1bd7-cf50-40dc-9955-e101a4f544bd) |
| Check it and save the changes. |  |

## Authentication

The Salesforce Collector supports both User/Password and OAuth 2 authentication methods. Choose your preferred option.

### Getting credentials (User/Password)

This method needs the `username`, `password`, and `security_token`.

Usually, everything comes together on the same email when the user is registered in a Salesforce account, but if the security token does not come in the email or you cannot find it, follow the next steps to obtain a new one:

| **Steps** | **Snapshot** |
| --- | --- |
| Login to your Salesforce account with the user that will be used to access the API. |  |
| Click on the user icon (at the top right of the screen) and select “Settings“. | ![image](media://0dba3510-88a8-4c1d-983e-a4162ea3510c) |
| In the settings left menu, find “My personal information“ and search for “Reset my security token“. | ![image](media://17a529cd-a7c0-4618-861c-e868e0d223bb) |
| On this screen, click on “Reset Security Token“ and you will receive a mail with the new security token. |  |

### Getting credentials (OAuth 2)

To enable OAuth 2 authentication we need to create a “Connected App“ and obtain the `client_id`, `client_secret`, and `redirect_uri` values to use it.

> ℹ️ OAuth 2 is implemented in two ways in this collector.
> ℹ️ 
> ℹ️ - The first one needs all parameters (`username`, `password`, `security_token`, `client_id`, `client_secret,` and `redirect_uri`) to automatically authorize the OAuth2 client to access the information.
> ℹ️ - The second one authorizes the OAuth client manually, so only needs `client_id`, `client_secret`, and the `access_token` file obtained with [this script](https://drive.google.com/file/d/1p-_rzE1mzAS5Gr83xZBU8RyHTScRz0Ix/view?usp=drive_link).

| **Steps** | **Snapshot** |
| --- | --- |
| Login to your Salesforce account. |  |
| Click on the gear icon (near the user Icon) and select “Service Setup“. | ![image](media://56e3bf32-6c9c-4525-9899-0cc52c04aa5d) |
| Type “Apps“ in the left search bar, click on “App Manager“ and create a new Connected App. | ![image](media://07e9d791-fbc1-42bf-88e6-b10d67add257) |
| Fill the mandatory fields, check the Enable “OAuth settings checkbox” and fill the new fields as shown in the sample. | ![image](media://6896abac-45f2-460c-83a4-e0be7423b2df) |
| Save the changes and write down the `client_id`(Consumer Key), `client_secret` (Consumer Secret), and `redirect_uri` (Callback URL). | ![image](media://1f2b20b7-1522-4c14-99ae-161225778b08) |

### Getting the access token file

To get the access token file, we need to execute this [script](https://drive.google.com/file/d/1p-_rzE1mzAS5Gr83xZBU8RyHTScRz0Ix/view?usp=drive_link) with the following steps:

| **Steps** |
| --- |
| Prepare your environment:<br>> ⚠️ For executing the access token file generation script, we need the following Python 3.6 (or above) dependencies installed
> ⚠️ 
> ⚠️ - click 7.1.2 (or above)
> ⚠️ - requests 2.25.1 (or above)
> ⚠️ - json (normally comes by default in the python standard library)
> ⚠️ - urllib (normally comes by default in the python standard library)
> ⚠️ - webbrowser (normally comes by default in the python standard library) |
| Execute the script with the following command:<br>```
python salesforce_access_token_generator.py --client_id <salesforce_client_id> --client_secret <salesforce_client_secret> --redirect_uri <salesforce_client_uri>
```<br>This script will open our predefined browser with a Salesforce login page. Log in to Salesforce and authorize the client in your domain. Once authorized, it will redirect to another URL like in the following image:<br>![image](media://e5e909d8-183d-4922-8151-baf32572592c) |
| Now, we need to copy the URL and paste it into the terminal where we have executed the script, which was waiting for this URL. Press ENTER and the script will finalize the token file creation.  
Once finalized the execution, we should see an `access_token.json` file in the same directory as the script. |
| Next, we need to convert the content of this file into base64 format. This can be done using an online tool such as [Base64 Encode and Decode - Online](https://www.base64encode.org/). <u>***NOTE:***</u> this is a 3rd party tool that Devo does not manage, and is provided only as an example. |
| The base64 encoded string is then used as the value of the `initial_access_token_base64` key in the collector’s user configuration. |

### Permissions

To be able to retrieve the data, we need to have some minimal permissions in the user configured for this collector. This user must be under a “Salesforce” user license and we need to provide the “standard user” profile for almost all the services/SObjects (with some exceptions) after enabling the API access.

We are now selecting from the Standard Fields [Salesforce Developers](https://developer.salesforce.com/docs/atlas.en-us.soql_sosl.meta/soql_sosl/sforce_api_calls_soql_select_fields.htm)

For each object they have there own standard Fields. These will all be selected all of the time. **Note:** If the authentactor doesn’t have permissions to view the standard or custom columns you’ll need to add Field Level Security to Visible. [Salesforce Developers](https://developer.salesforce.com/docs/atlas.en-us.securityImplGuide.meta/securityImplGuide/admin_fls.htm)

The special required permissions by `SObjects` are specified below:

- LoginHistory and User: we can use a profile inherited from “standard user“. To add the missing permissions, we just need to enable the “Manage Users“ permission in the user’s profile.

![image-20250616-163927.png](media://a1e2a517-76d6-486d-badd-6244491516c4)

> ⚠️ To understand why do we need the “Manage Users” permissions for these `SObjects`, check the Salesforce's Developer documentation (Special Access Rules section): [LoginHistory](https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_loginhistory.htm) and [User](https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_user.htm).

- EventLogFiles: we can use a profile inherited from “standard user“. To add the missing permissions, we just need to enable the “View Event Log Files“ permission in the user’s profile.

![image-20250616-164009.png](media://4c2c47f3-22ac-496f-a933-43c468320dfa)

## Devo collector features

| **Feature** | **Details** |
| --- | --- |
| Allow parallel downloading (`multipod`) | `Not allowed` |
| Running Environments | `Collector Server`, `On-Premise` |

## Minimum configuration required for basic pulling

Although this collector supports advanced configuration, the fields required to download data with basic configuration are defined below.

> 📝 This minimum configuration refers exclusively to those specific parameters of this integration. There are more required parameters related to the generic behavior of the collector. Check the detail of the parameterization for more information.

| **Setting** | **Details** |
| --- | --- |
| `<salesforce_user_if_using_user_and_password>` | Username to authenticate the service, if using the User/Password authentication mechanism. |
| `<salesforce_password_if_using_user_and_password>` | Password to authenticate the service, if using the User/Password authentication mechanism. |
| `<salesforce_security_token_if_using_user_and_password>` | Security token to authenticate the service, if using the User/Password authentication mechanism. |
| `<client_id_if_using_oauth>` | Client ID to authenticate the service, if using the OAuth 2 authentication mechanism. |
| `<client_secret_if_using_oauth>` | Client Secret to authenticate the service, if using the OAuth 2 authentication mechanism. |
| `<base_64_encoded_content_from_acess_token_file_if_using_oauth>` | The result obtained from the script described in the Getting the access token file section, if using the OAuth 2 authentication mechanism. |

> ℹ️ See the **Accepted authentication methods** section to verify what settings are required based on the desired authentication method.

## Accepted authentication methods

Depending on how did you obtain your credentials, you will have to either fill or delete the following properties on the JSON `credentials` configuration block.

| **Authentication method** | **Username** | **Password** | **Security token** | **Client ID** | **Client secret** | **Salesforce domain** | **Initial access token in Base64** |
| --- | --- | --- | --- | --- | --- | --- | --- |
| Username/Password | [REQUIRED] | [REQUIRED] | [REQUIRED] |  |  | [REQUIRED] |  |
| OAuth 2 with all the parameters (without `access_token`) | [REQUIRED] | [REQUIRED] | [REQUIRED] | [REQUIRED] | [REQUIRED] | [REQUIRED] |  |
| OAuth 2 with the `access_token` file manually generated |  |  |  | [REQUIRED] | [REQUIRED] | [REQUIRED] | [REQUIRED] |

## Run the collector

Once the data source is configured, you can either send us the required information if you want us to host and manage the collector for you (<u>Cloud collector</u>), or deploy and host the collector in your own machine using a Docker image (<u>On-premise collector</u>).

> Macro (rw-ui-tabs-macro)
> 
> > Macro (rw-tab)
> 
> We use a piece of software called Collector Server to host and manage all our available collectors.
> 
> To enable the collector for a customer:
> 
> 1. In the **Collector Server** **GUI**, access the **domain** in which you want this instance to be created
> 2. Click **Add Collector** and find **Salesforce Collector - Integrations Factory**.
> 3. In the **Version** field, select the latest value.
> 4. In the **Collector Name** field, set the value you prefer (this name must be unique inside the same Collector Server domain).
> 5. In the sending method select **Direct Send. Direct Send** configuration is optional for collectors that create `Table` events, but mandatory for those that create `Lookups`.
> 6. In the **Parameters** section, establish the **Collector Parameters** as follows below:
> 
> ### Editing the JSON configuration
> 
> ```
> {
>   "global_overrides": {
>     "debug": false
>   },
>   "inputs": {
>     "salesforce": {
>       "id": 12345,
>       "enabled": true,
>       "api_version": "62.0",
>       "credentials": {
>         "username": "<salesforce_user_if_using_user_and_password_value>",
>         "password": "<salesforce_password_if_using_user_and_password_value>",
>         "security_token": "<salesforce_security_token_if_using_user_and_password_value>",
>         "client_id": "<client_id_if_using_oauth_value>",
>         "client_secret": "<client_secret_if_using_oauth_value>",
>         "salesforce_domain": "<your_salesforce_domain_value>",
>         "initial_access_token_base64": "<base_64_encoded_content_from_acess_token_file_if_using_oauth_value>"
>       },
>       "services": {
>         "Account": {
>           "request_period_in_seconds": 600,
>           "start_time": "0000-00-00T00:00:00Z"
>         },
>         "Case": {
>           "request_period_in_seconds": 600,
>           "start_time": "0000-00-00T00:00:00Z"
>         },
>         "ContentVersion": {
>           "request_period_in_seconds": 600,
>           "start_time": "0000-00-00T00:00:00Z"
>         },
>         "Dashboard": {
>           "request_period_in_seconds": 600,
>           "start_time": "0000-00-00T00:00:00Z"
>         },
>         "EventLogFile": {
>           "request_period_in_seconds": 300,
>           "start_time": "0000-00-00T00:00:00Z",
>           "process_results": {
>             "enabled": true
>           },
>           "event_log_type": [
>             "*"
>           ]
>         },
>         "LoginHistory": {
>           "request_period_in_seconds": 600,
>           "start_time": "0000-00-00T00:00:00Z"
>         },
>         "Opportunity": {
>           "request_period_in_seconds": 600,
>           "start_time": "0000-00-00T00:00:00Z"
>         },
>         "Report": {
>           "request_period_in_seconds": 600,
>           "start_time": "0000-00-00T00:00:00Z"
>         },
>         "User": {
>           "request_period_in_seconds": 600,
>           "start_time": "0000-00-00T00:00:00Z"
>         },
>         "SetupAuditTrail": {
>           "request_period_in_seconds": 600,
>           "start_time": "0000-00-00T00:00:00Z"
>         },
>         "<custom_object> like custom_user, custom_opportunity": {
>           "start_time": "0000-00-00T00:00:00Z",
>           "key": "most of the time LastModifiedDate",
>           "fields": [
>             "must append __c to value",
>             "Id__c",
>             "LastModifiedById__c",
>             "LastModifiedDate__c",
>             "Name__c"
>           ]
>         }
>       }
>     }
>   }
> }
> 
> ```
> 
> > ℹ️ All defined service entities will be executed by the collector. If you do not want to run any of them, just remove the entity from the `services` object.
> 
> Please replace the placeholders with real world values following the description table below:
> 
> |  |  |  |  |  |
> | --- | --- | --- | --- | --- |
> | **Parameter** | **Data type** | **Type** | **Value range / Format** | **Details** |
> | `<short_unique_id>` | `int` | `Mandatory` | Minimum length: 1  
> Maximum length: 5 | Use this param to give an unique id to this input service.<br>> ⚠️ This parameter is used to build the persistence address, do not use the same value for multiple collectors. It could cause a collision. |
> | `<enabled>` | `bool` | `Mandatory` | `false` / `true` | Use this param to enable or disable the given input logic when running the collector. If the value is `true`, the input will be run. If the value is `false`, it will be ignored. |
> | `api_version` | `str` | `Mandatory` | 62.0 | This parameter allows you to update the salesforce api version whenever you want. |
> | `<salesforce_user_if_using_user_and_password_value>` | `str` | `Optional`<sup>1</sup> | Any | Username to authenticate the service.<br>> 📝 This parameter should be either filled or removed, depending on your authentication mechanism. Check the Credentials' settings section. |
> | `<salesforce_password_if_using_user_and_password_value>` | `str` | `Optional`<sup>1</sup> | Any | Password to authenticate the service.<br>> 📝 This parameter should be either filled or removed, depending on your authentication mechanism. Check the Credentials' settings section. |
> | `<salesforce_security_token_if_using_user_and_password_value>` | `str` | `Optional`<sup>1</sup> | Any | Security token to authenticate the service.<br>> 📝 This parameter should be either filled or removed, depending on your authentication mechanism. Check the Credentials' settings section. |
> | `<client_id_if_using_oauth_value>` | `str` | `Optional`<sup>1</sup> | Any | Client ID to authenticate the service.<br>> 📝 This parameter should be either filled or removed, depending on your authentication mechanism. Check the Credentials' settings section. |
> | `<client_secret_if_using_oauth_value>` | `str` | `Optional`<sup>1</sup> | Any | Client Secret to authenticate the service.<br>> 📝 This parameter should be either filled or removed, depending on your authentication mechanism. Check the Credentials' settings section. |
> | `<your_salesforce_domain_value>` | `str` | `Mandatory` | Any | The Salesforce **subdomain** name.<br>If you log in to Salesforce using devo.my.salesforce.com, then this field is `devo.my`. |
> | `<base_64_encoded_content_from_acess_token_file_if_using_oauth_value>` | `str` | `Optional`<sup>1</sup> | A valid Base 64 string | The result obtained from the script described in the Getting the access token file section.<br>> 📝 This parameter should be either filled or removed, depending on your authentication mechanism. Check the Credentials' settings section. |
> | `<request_period_in_seconds>` | `str` | `Optional` |  | The amount (in seconds) in which the service’s collection is scheduled.<br>> 📝 This parameter can be removed if not set. |
> | `<key>` | `str` | `Optional`<sup>2</sup> | A key of a timestamp value from that service<br>ie LastModifiedDate | This will be used for internal comparisons to sort the events that the service obtains. Each service has this parameter set by default (usually `LastModifiedDate` or the most similar one), but you can override it here.<br>> ℹ️ This parameter is mandatory for custom services.<br>> 📝 This parameter can be removed if not set. |
> | `<``override_tag_value``>` | `str` | `Optional` | A [Devo tag](https://docs.devo.com/confluence/ndt/latest/devo-parsers/about-devo-tags) | You can customize the destination tag of the events received. If it is not set, the default value is `crm.salesforceobjects.{sobject_name}`.<br>> 📝 This parameter can be removed if not set. |
> | `<fields>` | `Array` (of `str`) | `Optional` | Additional keys from the events received from that service **Only for custom services** | You can add additional fields that are not present by default in the predefined services by adding them to this array. It will have this structure:<br>```
> "fields": [
>   "<field_name>",
>   "<field_name>",
>   [...],
>   "<field_name>"
> ]
> ```<br>Here is an example (please note this is very dependant on the queried SObject):<br>```
> "fields": [
>   "BrowserType__c",
>   "DeviceNativeUid__c",
>   "DeviceType__c",
>   "IsVerified__c"
> ]
> ```<br>> ℹ️ This fields is ignored in custom services because the `fields` parameter is used instead.<br>> ⚠️ To know what fields can you select, visit the [Salesforce’s Standard Objects reference](https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_list.htm). Ensure that the added values are correctly written; otherwise, the collector will return an error.<br>> 📝 This parameter can be removed if not set. |
> | `<start_time_value>` | `str` | `Optional` | A date with format `YYYY-MM-DDTHH:mm:ssZ` | This will allow you to start from a specific date in case you want to ingest historic events. If not set, it will start at the current time.<br>> 📝 This parameter can be removed if not set. |
> | `<process_results_enabled_value>` | `bool` | `Optional` | false / true | This will enable that the Event Log Files services actually fetches the log files and sends their content to the `crm.salesforce.<event_type>` tables.<br>> ⚠️ **Risk of reaching rate limits, if **`true`. This parameter may cause a high number of requests, as it performs a request for each EventLogFile event to get the content in those files.
> > ⚠️ 
> > ⚠️ The older the `start_time`, the higher the risk of reaching rate limits.<br>> 📝 This parameter can be removed if not set. Remove the whole `process_results` block in such case. |
> | `<process_results_compress_value>` | `bool` | `Optional` | false / true | This will enable compression for the log files' fetching. This is usually not needed.<br>> 📝 This parameter can be removed if not set. Remove the whole `process_results` block in such case. |
> | `<custom_object>` | `str` | `Optional`<sup>2</sup> | Words, numbers and underscores. None of the predefined Collector Services, as these names are already taken.<br>**You Must use custom_object**<br>examples: custom_user, custom_opportunity | When you want to set up a custom service that pulls data from SObjects other than the ones available in the predefined services (listed in the Data Source Description section), you create a new configuration block with the following structure:<br>```
> "<custom_object> like custom_user, custom_opportunity": {
>   "start_time": "0000-00-00T00:00:00Z",
>   "key": "most of the time LastModifiedDate",
>   "fields": [
>     "must append __c to value",
>     "Id__c",
>     "LastModifiedById__c",
>     "LastModifiedDate__c",
>     "Name__c"
>   ]
> }
> ```<br>Here is an example for a sample SObject: Make sure there are no duplicates please check salesforce api docs for standard columns<br>```
> "custom_account": {
>   "sobject_name": "Account",
>   "key": "LastModifiedDate",
>   "fields": [
>     "CreatedDate__c",
>     "Id__c"
>   ]
> }
> ```<br>> 📝 This block can be removed if not set. |
> | `override_interval_value` | `str` | `Optional` | `daily` (default) or `hourly` | This value indicates if the data is collected `daily` or `hourly` in the customer’s Salesforce. If it is collected `hourly`, this must be defined in order to be able to collect all the events available. |
> | `event_log_type` | `array` | `Mandatory` | Use a `*` for all or if removed will be all.<br>any event log file object such as<br>`["apexcallout", "bulkapi", "report", ... etc]` | This allows you to filter which event log files get downloaded and sent to Devo. Thus allowing you to filter out which ones you don’t want. |
> 
> > 📝 <sup>1</sup>: Visit the **Accepted authentication methods** section for details.
> > 📝 
> > 📝 <sup>2</sup>: These parameters are optional –or ignored– for predefined services, but mandatory for custom ones.
> 
> ![10_Salesforce.png](media://b29e974e-99d2-4ef5-b235-07e70dae1032)
> 
> > Macro (rw-tab)
> 
> This data collector can be run in any machine that has the Docker service available because it should be executed as a docker container. The following sections explain how to prepare all the required setup for having the data collector running.
> 
> ### Structure
> 
> The following directory structure should be created for being used when running the collector:
> 
> ```
> <any_directory>
> └── devo-collectors/
>     └── <product_name>/
>         ├── certs/
>         │   ├── chain.crt
>         │   ├── <your_domain>.key
>         │   └── <your_domain>.crt
>         ├── state/
>         └── config/ 
>             └── config.yaml 
> ```
> 
> > ⚠️ Replace `<product_name>` with the proper value.
> 
> ### Devo credentials
> 
> In Devo, go to **Administration → Credentials → X.509 Certificates**, download the **Certificate**, **Private key** and **Chain CA** and save them in `<product_name>/certs/`. Learn more about security credentials in Devo [here](#).
> 
> ![image](media://5b02d5ec-c127-491a-b7c3-a35c9af5af55)
> 
> > ⚠️ Replace `<product_name>` with the proper value.
> 
> ### Editing the config.yaml file
> 
> ```
> globals:
>   debug: false
>   id: not_used
>   name: salesfoce_collector
>   persistence:
>     type: filesystem
>     config:
>       directory_name: state
> outputs:
>   devo_1:
>     type: devo_platform
>     config:
>       address: collector-us.devo.io
>       port: 443
>       type: SSL
>       chain: <chain_filename>
>       cert: <cert_filename>
>       key: <key_filename> 
> inputs:salesforce:
>     id: 12345
>     enabled: true
>     api_version: "62.0"
>     credentials:
>       username: <salesforce_user_if_using_user_and_password_value>
>       password: <salesforce_password_if_using_user_and_password_value>
>       security_token: <salesforce_security_token_if_using_user_and_password_value>
>       client_id: <client_id_if_using_oauth_value>
>       client_secret: <client_secret_if_using_oauth_value>
>       salesforce_domain: <your_salesforce_domain_value>
>       initial_access_token_base64: <base_64_encoded_content_from_acess_token_file_if_using_oauth_value>
>     services:
>       Account:
>         request_period_in_seconds: 600
>         start_time:  "0000-00-00T00:00:00Z"
>       Case:
>         request_period_in_seconds: 30
>         start_time:  "0000-00-00T00:00:00Z"
>       ContentVersion:
>         request_period_in_seconds:  600
>         start_time:  "0000-00-00T00:00:00Z"
>       Dashboard:
>         request_period_in_seconds:  600
>         start_time:  "0000-00-00T00:00:00Z"
>       EventLogFile:
>         request_period_in_seconds: 30
>         start_time:  "0000-00-00T00:00:00Z"
>         process_results:
>           enabled: true
>         event_log_type:
>           ["*"]
>       LoginHistory:
>         request_period_in_seconds:  600
>         start_time:  "0000-00-00T00:00:00Z"
>       Opportunity:
>         request_period_in_seconds:  600
>         start_time:  "0000-00-00T00:00:00Z"
>       Report:
>         request_period_in_seconds:  600
>         start_time:  "0000-00-00T00:00:00Z"
>       User:
>         request_period_in_seconds:  600
>         start_time:  "0000-00-00T00:00:00Z"
>       SetupAuditTrail:
>         request_period_in_seconds:  600
>         start_time:  "0000-00-00T00:00:00Z"
> #     <custom_sobject_name>: must have custom_<object name>
> #        request_period_in_seconds:  600
> #        key:  #<key_value>
> #        fields: #<fields_value>
> #        override_tag: #<tag_value>
> #        start_time:  # <start_time_value>
> ```
> 
> Replace the placeholders with your required values following the description table below:
> 
> |  |  |  |  |  |
> | --- | --- | --- | --- | --- |
> | **Parameter** | **Data Type** | **Type** | **Value Range / Format** | **Details** |
> | `<devo_address>` | `str` | `Mandatory` | `collector-us.devo.io`  
> `collector-eu.devo.io` | Use this param to identify the Devo Cloud where the events will be sent. |
> | `<chain_filename>` | `str` | `Mandatory` | Minimum length: 4  
> Maximum length: 20 | Use this param to identify the chain.cert  file downloaded from your Devo domain. Usually this file's name is: `chain.crt` |
> | `<cert_filename>` | `str` | `Mandatory` | Minimum length: 4  
> Maximum length: 20 | Use this param to identify the `file.cert` downloaded from your Devo domain. |
> | `<key_filename>` | `str` | `Mandatory` | Minimum length: 4  
> Maximum length: 20 | Use this param to identify the `file.key` downloaded from your Devo domain. |
> | `<short_unique_id>` | `int` | `Mandatory` | Minimum length: 1  
> Maximum length: 5 | Use this param to give an unique id to this input service.<br>> ⚠️ This parameter is used to build the persistence address, do not use the same value for multiple collectors. It could cause a collision. |
> | `<enabled>` | `bool` | `Mandatory` | `false` / `true` | Use this param to enable or disable the given input logic when running the collector. If the value is `true`, the input will be run. If the value is `false`, it will be ignored. |
> | `api_version` | `str` | `Mandatory` | “62.0” | This is the starting api version on version 3.0.0 but you can upgrade the value anytime Salesforce releases a new api. |
> | `<salesforce_user_if_using_user_and_password_value>` | `str` | `Optional`<sup>1</sup> | Any | Username to authenticate the service.<br>> 📝 This parameter should be either filled or removed, depending on your authentication mechanism. Check the Credentials' settings section. |
> | `<salesforce_password_if_using_user_and_password_value>` | `str` | `Optional`<sup>1</sup> | Any | Password to authenticate the service.<br>> 📝 This parameter should be either filled or removed, depending on your authentication mechanism. Check the Credentials' settings section. |
> | `<salesforce_security_token_if_using_user_and_password_value>` | `str` | `Optional`<sup>1</sup> | Any | Security token to authenticate the service.<br>> 📝 This parameter should be either filled or removed, depending on your authentication mechanism. Check the Credentials' settings section. |
> | `<client_id_if_using_oauth_value>` | `str` | `Optional`<sup>1</sup> | Any | Client ID to authenticate the service.<br>> 📝 This parameter should be either filled or removed, depending on your authentication mechanism. Check the Credentials' settings section. |
> | `<client_secret_if_using_oauth_value>` | `str` | `Optional`<sup>1</sup> | Any | Client Secret to authenticate the service.<br>> 📝 This parameter should be either filled or removed, depending on your authentication mechanism. Check the Credentials' settings section. |
> | `<your_salesforce_domain_value>` | `str` | `Optional` | Any | The Salesforce domain name.<br>> 📝 This parameter can be removed if not set. |
> | `<base_64_encoded_content_from_acess_token_file_if_using_oauth_value>` | `str` | `Optional`<sup>1</sup> | A valid Base 64 string | The result obtained from the script described in the Getting the access token file section.<br>> 📝 This parameter should be either filled or removed, depending on your authentication mechanism. Check the Credentials' settings section. |
> | `<request_period_in_seconds>` | `str` | `Optional` |  | The amount (in seconds) in which the service’s collection is scheduled.<br>> 📝 This parameter can be removed if not set. |
> | `<key>` | `str` | `Optional`<sup>2</sup> | A key of a timestamp value from that service | This will be used for internal comparisons to sort the events that the service obtains. Each service has this parameter set by default (usually `LastModifiedDate` or the most similar one), but you can override it here.<br>> ℹ️ This parameter is mandatory for custom services.<br>> 📝 This parameter can be removed if not set. |
> | `<override_tag_value>` | `str` | `Optional` | A [Devo tag](https://docs.devo.com/confluence/ndt/latest/devo-parsers/about-devo-tags) | You can customize the destination tag of the events received. If it is not set, the default value is `crm.salesforceobjects.{sobject_name}`.<br>> 📝 This parameter can be removed if not set. |
> | `<fields>` | `Array` (of `str`) | `Optional` | Additional keys from the events received from that service | You can add additional fields that are not present by default in the predefined services by adding them to this array. It will have this structure:<br>```
> fields:
>   -  <field_name__c>
>   -  <field_name__c>
>   [...]
>   -  <field_name__c>
> ```<br>Here is an example (please note this is very dependant on the queried SObject):<br>```
> custom_fields:
>   - BrowserType__c
>   - DeviceNativeUid__c
>   - DeviceType__c
>   - IsVerified__c
> ```<br>> ℹ️ This fields is ignored in custom services because the `fields` parameter is used instead.<br>> ⚠️ To know what fields can you select, visit the [Salesforce’s Standard Objects reference](https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_list.htm). Ensure that the added values are correctly written; otherwise, the collector will return an error.<br>> 📝 This parameter can be removed if not set. |
> | `<start_time_value>` | `str` | `Optional`<br>`Mandatory` for **EventLogFile** | A date with format `YYYY-MM-DDTHH:mm:ssZ` | This will allow you to start from a specific date in case you want to ingest historic events. If not set, it will start from 10 days before than current date.<br>**For EventLogFile service, set this explicitly with a value not more than 3 days old than current datetime.**<br>> 📝 This parameter can be removed if not set. |
> | `<process_results_enabled_value>` | `bool` | `Optional` | false / true | This will enable that the Event Log Files services actually fetches the log files and sends their content to the `crm.salesforce.<event_type>` tables.<br>> ⚠️ **Risk of reaching rate limits, if **`true`. This parameter may cause a high number of requests, as it performs a request for each EventLogFile event to get the content in those files.
> > ⚠️ 
> > ⚠️ The older the `start_time`, the higher the risk of reaching rate limits.<br>> 📝 This parameter can be removed if not set. Remove the whole `process_results` block in such case. |
> | `<process_results_compress_value>` | `bool` | `Optional` | false / true | This will enable compression for the log files' fetching. This is usually not needed.<br>> 📝 This parameter can be removed if not set. Remove the whole `process_results` block in such case. |
> | `<custom_service_name_value>` | `str` | `Optional`<sup>2</sup> | Words, numbers and underscores. None of the predefined Collector Services, as these names are already taken.<br>We recommend to set the service’s name as the SObject’s name. | When you want to set up a custom service that pulls data from SObjects other than the ones available in the predefined services (listed in the Data Source Description section),<br>you create a new configuration block with the following structure:<br>```
> <custom_object>:
>         sobject_name: <sobject_name_value>
>         key: <key_value>
>         fields: <fields_value>
>         tag: <tag_value> # optional 
>         start_time: <start_time_value> # optional
> ```<br>Here is an example for a sample SObject: **Make sure fields aren’t standard**<br>```
> custom_authsession:
>   sobject_name: AuthSession
>   key: LastModifiedDate
>   fields:
>     - CreatedDate__c
>     - Id__c
>     - IsCurrent__c
>     - LastModifiedDate__c
>     - LoginGeoId__c
>     - LoginHistoryId__c
>     - LoginType__c
>     - LogoutUrl__c
>     - NumSecondsValid__c
>     - ParentId__c
>     - SessionSecurityLevel__c
>     - SessionType__c
>     - SourceIp__c
>     - UserType__c
>     - UsersId__c
> ```<br>> 📝 This parameter can be removed if not set. |
> | `<sobject_name_value>` | `str` | `Optional`<sup>2</sup> | Words, numbers and underscores. | This must correspond to an existing SObject from which the API will pull data from. To know which SObjects you can choose, visit the [Salesforce’s Standard Objects reference](https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_list.htm).<br>> ℹ️ This parameter is mandatory for custom services, and ignored by predefined ones. |
> | `<fields_value>` | `Array` (of `str`) | `Optional`<sup>2</sup> | Keys from the events received from that service. | When defining a custom service, you must define which fields are going to be selected by using this parameter. It will have this structure:<br>```
> fields:
>   -  <field_name>
>   -  <field_name>
>   [...]
>   -  <field_name>
> ```<br>Here is an example (please note this is very dependant on the queried SObject):<br>```
> fields:
>   - BrowserType__c
>   - DeviceNativeUid__c
>   - DeviceType__c
>   - IsVerified__c
> ```<br>> ℹ️ This parameter is mandatory for custom services, and ignored by predefined ones.<br>> ⚠️ To know what fields can you select, visit the [Salesforce’s Standard Objects reference](https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_list.htm). Ensure that the added values are correctly written; otherwise, the collector will return an error.<br>> 📝 This parameter can be removed if not set. |
> | `override_interval_value` | `str` | `Optional` | `daily` (default) or `hourly` | This value indicates if the data is collected `daily` or `hourly` in the customer’s Salesforce. If it is collected `hourly`, this must be defined in order to be able to collect all the events available. |
> | `event_log_type` | `array` | `Mandatory` | Use a `*` for all or if removed will be all.<br>any event log file object such as<br>`["apexcallout", "bulkapi", "report", ... etc]` | This allows you to filter which event log files get downloaded and sent to Devo. Thus allowing you to filter out which ones you don’t want. |
> 
> > ℹ️ <sup>1</sup>: Visit the **Accepted authentication methods** section for details.
> > ℹ️ 
> > ℹ️ <sup>2</sup>: These parameters are optional –or ignored– for predefined services, but mandatory for custom ones.
> 
> ### Download the Docker image
> 
> The collector should be deployed as a Docker container. Download the Docker image of the collector as a .tgz file by clicking the link in the following table:
> 
> | **Collector Docker image** | **SHA-256 hash** |
> | --- | --- |
> | [collector-salesforce_collector-docker-image-3.0.0](https://drive.google.com/file/d/1Jqs6HZ13YSe1W9_wfXI3MsAGBe-5wi51/view?usp=sharing) | `90a10cf2ffd10bd6a2019f682cf6b42f346433edb1768c597e3bbdd51e36b41e` |
> 
> Use the following command to add the Docker image to the system:
> 
> ```
> gunzip -c <image_file>-<version>.tgz | docker load
> ```
> 
> > ⚠️ Once the Docker image is imported, it will show the real name of the Docker image (including version info). Replace `<image_file>` and `<version>` with a proper value.
> 
> The Docker image can be deployed on the following services:
> 
> #### Docker
> 
> Execute the following command on the root directory `<any_directory>/devo-collectors/<product_name>/`
> 
> ```
> docker run 
> --name collector-<product_name> 
> --volume $PWD/certs:/devo-collector/certs 
> --volume $PWD/config:/devo-collector/config 
> --volume $PWD/state:/devo-collector/state 
> --env CONFIG_FILE=config.yaml 
> --restart=always 
> --interactive 
> --tty 
> <image_name>:<version>
> ```
> 
> > ⚠️ Replace `<product_name>`, `<image_name>` and `<version>` with the proper values.
> 
> #### Docker Compose
> 
> The following Docker Compose file can be used to execute the Docker container. It must be created in the `<any_directory>/devo-collectors/<product_name>/` directory.
> 
> ```
> version: '3'
> services:
>   collector-<product_name>:
>     image: <image_name>:${IMAGE_VERSION:-latest}
>     container_name: collector-<product_name>
>     volumes:
>       - ./certs:/devo-collector/certs
>       - ./config:/devo-collector/config
>       - ./credentials:/devo-collector/credentials
>       - ./state:/devo-collector/state
>     environment:
>       - CONFIG_FILE=${CONFIG_FILE:-config.yaml}
> ```
> 
> To run the container using docker-compose, execute the following command from the `<any_directory>/devo-collectors/<product_name>/` directory:
> 
> ```
> IMAGE_VERSION=<version> docker-compose up -d
> ```
> 
> > ⚠️ Replace `<product_name>`, `<image_name>` and `<version>` with the proper values.

## Change log

| **Release** | **Released on** | **Release type** | **Details** | **Recommendations** |
| --- | --- | --- | --- | --- |
| `3.0.0` | 12/10/2024 | [IMPROVEMENTS]<br>[New Feature] | **Improvements**<br>- Upgraded DCSDK from `1.12.4` to `1.13.1`
- Upgraded Dockerfile base image<br>**Features**<br>- Added api version to be configurable, so users can update at anytime
- added upper and lower query parameters for requests by seconds
- added event log file filtering array, to choose non,some, or all events to download and send to Devo. | `Recommended version` |
| `2.5.0` | 7/29/2024 | [IMPROVEMENTS] | **Improvements**<br>- Upgraded DCSDK from `1.12.2` to `1.12.4`
- Upgraded APi version from `57.0` to `61.0` | `Upgrade` |
| `2.4.0` | 7/29/2024 | [IMPROVEMENTS] | **Improvements**<br>- Upgraded DCSDK from `1.11.1` to `1.12.2`
- Upgrade Base Docker Image to `1.3.0`<br>**Bug fixing**<br>- Fixed the persistence configuration for the collector | `Upgrade` |
| `2.3.0` | 4/9/2024 | [IMPROVEMENTS] | **Improvements**<br>- Added extra check for not valid message timestamps
- Added extra check for improve the controlled stop
- Changed default number for connection retries (now 7)
- Fix for Devo connection retries | `Upgrade` |
| `2.0.0` | 1/8/2024 | [IMPROVEMENTS] [NEW FEATURE] | **Improvements**<br>- Upgraded DCSDK from 1.10.0 to 1.10.2
  - Fixed error in pyproject.toml related to project scripts endpoint
  - Updated PythonSDK to version 5.0.7
  - Introduced pyproject.toml
  - Added requirements.dev.txt<br>**Features:**<br>- Changed the way Event Log Files were handled, converted them to json objects before sending to Devo. | `Upgrade` |
| `v1.7.0` | 11/10/2023 | [BUG FIXES] [IMPROVEMENTS] [NEW FEATURE] | **Improvements:**<br>1. Upgraded DCSDK from 1.9.0 to 1.10.0
  - Added input metrics
  - Modified ouutput metrics
  - Updated DevoSDK to version 5.1.6
  - Standardized exception messages for traceability
  - Added more detail in queue statistics
  - Upgrade internal dependenciesStore lookup instances into DevoSender to avoid creation of new instances for the same lookup
  - Ensure `service_config` is a dict into templates<br>**Bug fixing:**<br>- Fixed how it handles access tokens
- Fixed how custom objects are used
- Fixed which Fields it calls
- Fixed how the API test handles errors<br>**Features:**<br>- Changed how custom services are selected
- Changed the way fields are selected | `Upgrade` |
| `v1.6.0` | 7/25/2023 | [IMPROVEMENTS][BUG FIXING] | **Improvements:**<br>1. Upgraded DCSDK from 1.7.2 to 1.9.0
  1. Ensure special characters are properly sent to the platform
  2. Changed log level to some messages from info to debug
  3. Changed some wrong log messages
  4. Upgraded some internal dependencies
  5. Changed queue passed to setup instance constructor
  6. Ability to validate collector setup and exit without pulling any data
  7. Ability to store in the persistence the messages that couldn't be sent after the collector stopped
  8. Ability to send messages from the persistence when the collector starts and before the puller begins working
  9. Ensure special characters are properly sent to the platform<br>**Bug fixing:**<br>- Fixed the handling of credentials so OAuth can work again. | `Upgrade` |
| `v1.5.1` | 5/29/2023 | [IMPROVEMENTS][BUG FIXING] | **Improvements:**<br>- Added more logging when file processing is enabled for the EventLogFiles service.
- ELF processed file message sending refactored to be more efficient.<br>**Bug fixing:**<br>- Fix tag creation to allow the creation of `crm.salesforce.{event_type}` tags when processing is enabled for the EventLogFile service (broken since v1.4.0).
- Statistics are now correctly calculated. | `Upgrade` |
| `v1.5.0` | 5/23/2023 | [IMPROVEMENTS][BUG FIXING] | **Improvements:**<br>- Upgraded DC SDK from version v1.6.3 to v1.7.2.<br>**Bug fixing:**<br>- For EventLogFile, the collector is able to collect data hourly, instead of daily, which is the default option.
- Removed some columns from services Account, Case and User. These columns does not exist now in Salesforce, so they were raising errors. | `Upgrade` |
| `v1.4.0` | 3/17/2023 | [IMPROVEMENTS] | **Improvements:**<br>- Upgraded IFC SDK from version 1.4.0b to v1.6.3.
- Automated token refresh: In previous versions, the token had to be refreshed manually, now it is no longer necessary.
- Added ofuscation for credentials: The collector has been improved by adding this feature to obfuscate credentials. | `Upgrade` |
| `v1.3.0` | 11/29/2022 | [IMPROVEMENTS][BUG FIX] | **Improvements:**<br>- Upgraded IFC SDK from version 1.4.0 to v1.4.4b.
  - Added some extra checks for supporting MacOS as development environment
  - The "template" supports the controlled stop functionality
  - Some log traces now are shown less frequently
  - The default value for the logging frequency for "main" processes hsa been changed (to 120 seconds)
  - Added log traces for knowing the execution environment status (debug mode)
  - Fixes in the current puller template version
  - Docker container now exists with the proper status code
  - New controlled stopping condition when any input thread fatally fails
  - Improved log trace details when runtime exception happens
  - Refactored source code structure
  - New templates functionality functionality
- Upgrade Salesforce API version from version 48 to version 56.
- Minor improvement in refresh_token function usage<br>**Fixed bugs:**<br>- Added persistence for oauth2 token to avoid `refresh the access token manually` errors
- Upgraded used API version to mitigate minor server side common errors such as `connection reset by peer`
- Upgraded IFC SDK to apply sender thread fixes to avoid sender to terminate the thread | `Upgrade` |
| `v1.2.0` |  | [NEW FEATURES][IMPROVEMENTS] | **New features**:<br>- Custom services are now working for any kind of SObject.<br>**Improvements**<br>- Upgraded underlay IFC SDK `v1.3.0` to `v1.4.0`.
- Updated the underlying `DevoSDK` package to `v3.6.4` and dependencies, this upgrade increases the resilience of the collector when the connection with Devo or the Syslog server is lost. The collector is able to reconnect in some scenarios without running the self-kill feature.
- Support for stopping the collector when a `GRACEFULL_SHUTDOWN` system signal is received.
- Re-enabled the logging to `devo.collector.out` for Input threads.
- Improved self-kill functionality behavior.
- Added more details in log traces.
- Added log traces for knowing system memory usage. | `Upgrade` |
| `v1.1.0` | 7/15/2022 | [NEW FEATURES][IMPROVEMENTS] | **New features:**<br>- New service for `SetupAuditTrail` that represents changes made by the admins in the organization’s Setup area for at least the last 180 days.<br>**Improvements:**<br>- Upgraded underlying IFC SDK to v1.3.0.
- When an exception is raised by the Collector, the collector retries connection after 5 seconds. For consecutive exceptions, the waiting time is multiplied by 5 until hits 1800 seconds, which is the maximum waiting time allowed. No maximum retries are applied.
- When an exception is raised by the Collector pull method, the collector retries after 5 seconds. For consecutive exceptions, the waiting time is multiplied by 5 until hits 1800 seconds, which is the maximum waiting time allowed. No maximum retries are applied.
- When an exception is raised by the Collector pre-pull method, the collector retries after 30 seconds. No maximum retries are applied. | `Upgrade` |