Salesforce is a CRM product that hosts the application and data online for customers. It provides an API that allows 3rd party applications to connect and download/upload data for a user. Verivo provides a plug-in which allows this connection from our configuration.
Plug-in Deployment and Preparation
Verivo provides a plug-in that is currently designed to work with SalesForce 9 API. Please consult with Development if there is a requirement to connect to a different version of SalesForce API.
- Download the PluginExclusions.xml, Plugins.Salesforce9.dll and PluginsSalesforce9.XmlSerializers.dll from Verivo.
- Place these files in the Plugins folder of both AppStudio and the AppServer (bin-> plugins).
- Create a folder named 'SFCache' under the bin\plugin folder of the Verivo AppServer.
- Ensure that this new folder has the same user permissions as other folders in the Verivo AppServer.
Plugin Exclusion File
As you develop against the Salesforce plug-in, the PluginExclusions.xml file can be updated. You will need this updated file in both the AppStudio and AppServer locations to be able to develop and test against. When you are looking to migrate your changes to another environment you will need to move this file along with the configuration export. For additional details on the PluginExclusions.xml file see the Configuration section of this document.
Sales Force Cache Directory
The Salesforce plug-in will automatically create a new directory in the Verivo AppStudio and Verivo AppServer's base directory called SFCache. This directory contains two XML cache files that have the description of all available SalesForce objects and their fields. The purpose of the cache files are to expedite the plug-in's ability to access the data object fields either through AppStudio or through a screen request from the device.
The cache files will be created on the Verivo AppServer during the very first user login and on Verivo AppStudio once the datasource has been created and refreshed. Note that this process is data intensive and will take time during both these scenarios.
Once the cache files are created you will not have to recreate them unless new entities are created in SalesForce that the configuration needs access to. In this case the plug-in can be configured to periodically refresh these files. The cache directory will need to have the appropriate Read/Write permissions granted to the service user in order for this process to run successfully.
Note that you can remove this directory from the AppServer and AppStudio. However this will cause a significant performance impact on the device and in AppStudio.
Salesforce Security Mechanisms: Whitelisting
Salesforce.com will pre-populate a list of trusted computer IP addresses for your company once, based on an analysis of the last four months of your organization's login data. Users with an address within one of these ranges will not be required to activate their computers or use a security token, and may use their user password instead of a security token to log in to the API or a desktop client such as Connect for Outlook, Connect Offline, Connect for Office, Connect for Lotus Notes, or the Data Loader.
User’s outside of this IP range, will need to add their computer’s IP address to the list of acceptable IP addresses, or will be required to append the Security Token to their password (see below for more details on the Security Token).
To add an IP address to the list of Trusted IP Addresses, log into Salesforce via the desktop web browser with an administrator-level account, click on ‘Setup’, expand the ‘Security Controls’ node under ‘Administration Setup’, and click on ‘Network Access’.
Salesforce Security Mechanisms: The Security Token
Tokens are generated via the desktop web browser and automatically emailed to the user upon request. To request the security token, the user will need to log into Salesforce via the desktop web browser and go to Setup -> My Personal Information -> Reset Security Token. The Security Token feature only applies to accessing Salesforce data via the API by an unrecognized IP address. The user will be required to enter a new password on the mobile device that will be a combination of a user’s password and a user’s token. For example, if your password is "MyPassword" and your security token is "XXXXXX", you would enter "MyPasswordXXXXXX" into the password field.
Salesforce Security Mechanisms: Account Lockouts
Account lockouts typically last for 30 minutes, but can be unlocked by an administrator. Account Lockouts may or may not be configured in every Salesforce environment, so please confer with a System Administrator.
Data Source Connection
The Salesforce plug-in has the following connection parameters:
Username - The Salesforce Username the application will use to log into Salesforce.
Password - The Salesforce Username password the application will use to log into Salesforce.
URL - The Salesforce Environment API URL that the application will connect to, for example http://test.salesforce.com/services/Soap/u/9.0
Timeout - The number in milliseconds that the application will wait for a successful response.
Batch Size - The size of the Batch Download limit.
Cache Object - Checkbox to indicate if the application should cache objects.
Proxy Settings Tab
Proxy URL - URL of the proxy service required.
Proxy Username - Username to log into the proxy service with.
Proxy Password - Password for the Username to log into the proxy service with.
Time Zone and Formats Tab
Base Offset - The timezone setting that the Database will reside in. This affects timezone handling within the application.
Daylight Savings - Checkbox to indicate if the Database adheres to Daylight Savings conventions.
Date Format - Dropdown to indicate what Date Format the Database uses.
Time Format - Dropdown to indicate what Time Format the Database uses.
Time Stamp Format - Dropdown to indicate what Time Stamp Format the Database uses.
The Salesforce plug-in naturally discovers and self-describes the entities and fields available in the environment. In addition the self-description process will also allow the user access to the relational entity details. For example if you have an Account object in Salesforce you will be able to see in AppStudio the Account object fields and the fields of any entities Accounts are associated to.
If Accounts have the following fields:
And Accounts are related to Owners who have the following fields:
The Account entity within AppStudio would make available the following fields:
Access to these relational fields on the entity allow you show this data without having to do an explicit JOIN instruction between the Entity and the Relational Entity.
There is a self imposed limitation within the plug-in where you will only have access to three degrees of relations in an entity. This prevents overly complex data queries in the configuration and ensures that the performance is not impacted. In the example above if you are accessing the Owner.OwnerName field you are going through Account -> Owner -> OwnerName. OwnerName is the third degree of the relationship and the plug-in will not describe any further relationship details.
Plugin Exclusion File
While the degrees of reference exposed by the Salesforce plug-in provides a versatile means for accessing Salesforce data, it can cause an enormous amount of fields to be returned in a single object depending on the complexity of the Sales Force CRM environment. This can cause performance issues in both the Verivo AppServer and AppStudio as the plug-in attempts to describe all the available fields.
To alleviate this issue you can use the Plugin Exclusion File (PluginExclusions.xml) to exclude certain elements from the self description process. Fields that you should look to exclude are any non-essential fields/relational entities or fields/relational entities that will never be used in the app. Once you have identified these items you need to add the following line to the Plug Exclusion File:
To exclude a specific field:
<ExclusionRule entity="[Entity]">[Entity Field]</ExclusionRule>
To exclude all references to a relational entity:
<ExclusionRule entity="[Entity]">[Entity].[Relational Entity].*</ExclusionRule>
For example if you need to exclude the Name field from the User Role relational object on the Account entity you would add this:
If you want to exclude all fields from the UserRole relational object you would add this:
Sales Force requires its own specific ID's to be created and used within their environment. In order to adhere to these requirements the following configuration is needed if you need to add/edit data against Sales Force:
- The entity's Primary Key needs to be mapped for Download Only against the Salesforce object Primary Key.
- The entity's Entity Primary Key needs to be mapped for Bi-Directional Data Flow against the Sales Force object Primary Key. ----This is necessary for editing records.
- The Upload Key Rule needs to be set to 'Enterprise systems does not expose primary keys on insert' ----Located in Application Properties under the Server Tab under the Data Connector section.
- The attribute 'Follow relations on upload' needs to be enabled. ------Located in Application Properties under the Server Tab under the Data Connector section.
Every table in Salesforce.com has a primary key called Id. This can be a little confusing, given that our Salesforce plug-in will expose several degrees of reference, and thus there can be multiple ID fields appearing in your Source Object or data mapping.
Note: this confusion can be avoided by renaming the mapped field in AppStudio
The first three characters in an ID will tell you what kind of item it is:
o 00T… = Task
o 001… = Account
o 003… = Contact
o 005… = User
o 006… = Opportunity
Once the 15-character ID passes through the Salesforce API, three additional characters are appended to the end in order to denote that this record has been called via the API.
You can take any Salesforce ID and append it to the end of the Salesforce URL to directly navigate to that particular record. Example: If my Account ID was ‘00100000003A02gACC’, then the location of this record in Salesforce would be:
https://[Sales Force Environment URL]/00100000003A02gACC
Either the 15-character ID or 18-character ID can be pasted into the URL in this manner.
Using Verivo Macros
Another configuration component in Verivo software is the macro. A macro is typically replaced with an actual value by the Verivo AppServer or client application at run-time. An example of this would be the Verivo AppServer replacing the macro #CURRENT_DATE# in a data query with the actual current date.
Note: Due to Salesforce’s handling and formatting of certain fields, primarily date and time fields, not all of the Verivo macros can be used in WHERE Clauses and Filters. If you are uncertain as to whether a particular macro is working, you can copy the query that is executed against the Salesforce plug-in and execute said query in the Apex Explorer. Please see the reference on Date Literals found at the end of this documentation for additional details regarding Salesforce date/time formatting.
Another useful macro is the #USERID# macro, which allows the server to substitute the macro for the User’s login ID, or if specified, another set of credentials configured at the data source level. This particularly macro is useful when narrowing result sets to a particular owner. For example:
WHERE OwnerId = ‘#USERID#’
In order to use the commonly used Verivo macro, #USERID#, effectively in a Verivo environment, it is strongly recommended that you populate users’ Salesforce data source parameters (found on the Users section in AppStudio). Downloading the list of users directly from Salesforce will provide you with an automatic ability to pre-populate these user-data-source parameters.
Screen Narrow Selection/Join Instruction Operators
The following operators are supported by the Salesforce Plugin:
Using Relational Entities
While the Salesforce plug-in exposes objects and requests similar to a SQL based data source, it is different in the fact that you cannot perform JOIN instructions. Instead you must use the relational objects exposed for each entity and a specific configuration scheme to be able to navigate from one related entity to another.
As mentioned earlier, relational objects are exposed through the plug-in on the entity itself. If you map these fields and configure them on a screen the plug-in will build out a query that will bring back records from that entity and for each record it will bring back all related object records. If you add in a Narrow Selection instruction to limit the result set to a specific record on the base entity you can create a relational screen without having to use a JOIN instruction.
You must keep in mind when you are laying out the screen navigation that you can only navigate the user "down" the relational tier one time in this manner. Once the user is on this relational screen, if you need to navigate to another screen based on a record the user selects on the relational object you must navigate back "up" the relational tier and use the relational entity's base entity.
Example: We need to provide a workflow where the user can see all Accounts, then see all Contacts related to an Account, and then see all Deals related to one of those Contacts. We have an Account entity which exposes a Contact relationship and a Contact entity which exposes a Deal relationship.
We would first create the Accounts screen using fields from the Account entity. Then we would create the Account Contact screen using fields from the Account.Contact relational entity with a Narrow Selection instruction on the Account ID field. Lastly the Contact Deal screen would use fields from the Contact.Deal relational entity with a Narrow selection on the Contact ID field.
From the Account screen we would navigate "down" the relational tier to see the Account Contact data. However because we need to see Contact related data we need to navigate "up" and use fields from the Contact entity.
Using Tasks & Events
- Tasks typically do not have a start time or duration, only a due date. If a calendar entity is present, Events should be on the calendar, as they typically have a duration, unlike Tasks.
- The Contact association will always be found in the ‘Who’ control (e.g. WhoId, WhoName). All other associations are dropped into the ‘What’ bucket (e.g. WhatId, WhatName, WhatType). The field ‘WhatType’ will inform you what type of record it is (Account, Opportunity, Campaign, Lead, etc).
- Events can be either durational (start time and duration) or all day events (no start time or duration).
- In previous direct access versions, Tasks and Events could NOT be on the same entity due to our limitation of uploading to two different source objects. This was possible in batched mode.
All Day Events
Please note: There are two date fields for Events, depending on whether the event is an all day event or not; ActivityDate and ActivityDateTime. If the event is all day, the AllDayEvent flag will be set and ‘ActivityDateTime’ field will be NULL (ActivityDate will be populated). If the event does not last all day, ActivityDateTime will have the date and time of the Event and ActivityDate will be NULL.
The following error message will be displayed if the ‘IsAllDayEvent’ flag is set by the user during an Add Event, and the upload mappings for Activity Date are not configured correctly. Salesforce imposes a rule that if the IsAllDayEvent is set, the ActivityDate field and not the ActivityDateTime field must be populated.
Error while upload data. ERROR - Salesforce Upload: REQUIRED_FIELD_MISSING required fields are missing. [ActivityDate]
To avoid this error, try using the following upload mappings for the Event entity:
- ActivityDtm needs to be mapped to the Event's ActivityDateTime field for Bi-Directional Dataflow.
- ActivityDtm needs to be mapped to the Event's ActivityDate field for Upload only.
Salesforce Apex Explorer
The Salesforce Apex Explorer is a powerful GUI based querying tool that will provide you the ability to directly query your Salesforce objects. This is a valuable tool when working with a Salesforce backend, and it is highly recommended that you install this application prior to working with or troubleshooting your Salesforce data requests.
The Sales Force plug-in will return back for each request the exact query it is using to populate the screen. You can use this information and the Apex Explorer to investigate syntax and data issues.
Apex Explorer can be found by simply searching for it in a browsers search engine and installing it as it is a public tool.
Sales Force API Documentation
If there are further questions on the limits of the Sales Force API or other general questions, Salesforce’s online documentation can be found at the following location:
Common Error Scenarios
Description: You don't see a field available in the Source Object under the Entity Definition
Solution: Verify that this field is valid and available in Salesforce then delete the SFCache folder in your AppStudio directory and the contents of the SFCache folder on your AppServer. This forces AppStudio and the AppServer to get the latest object definitions from Salesforce.
Description: ERROR - Salesforce Upload: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY OptyAccountIdUpdate: execution of BeforeInsert caused by: System.QueryException: List has no rows for assignment to SObject Trigger.OptyAccountIdUpdate: line 7, column 27
Solution: Not all required fields are being sent in the upload from the application. Verify through the Salesforce Web which fields are required for this upload
Description: ERROR - Salesforce Upload: FIELD_CUSTOM_VALIDATION_EXCEPTION The valid Probability % values are: 0%, 25%, 50%, 75% and 100% Please enter one of these values.
Solution: Encountering field level data validation from the Salesforce side. Adjust the input from the application as necessary