Module sfdc
ballerinax/sfdc
Connects to Salesforce from Ballerina.
Module Overview
The Salesforce connector allows users to perform CRUD operations for SObjects, query using SOQL, search using SOSL, and describe SObjects and organizational data through the Salesforce REST API. Also, it supports adding bulk data jobs and batches of types JSON, XML, and CSV via the Salesforce Bulk API. Apart from these functionalities Ballerina Salesforce Connector includes a listener module to capture events. This connector follows OAuth 2.0 authentication for secure access.
Compatibility
Version | |
---|---|
Ballerina Language | swan-lake-Beta3 |
Salesforce API | v48.0 |
Salesforce Bulk API | v1 |
Supported Operations
REST API Operations
REST API provides a powerful, convenient, and simple Web services API for interacting with Salesforce Lightning Platform providing access to all the Salesforce functionalities through REST resources and HTTP methods. Ballerina Salesforce Connector utilizes the REST API for Salesforce Object (SObject) operations and for searching and querying data. At the same time, the connector provides users to get SObject details and organizational data using the REST API.
SObject Operations
The ballerinax/sfdc
module contains operations related to standard and customized SObjects such as Account, Contact,
Opportunity, Lead etc. It facilitates users to create SObjects and get, update and delete records by SObject Id.
SOQL & SOSL Operations
The ballerinax/sfdc
module contains operations, which query using Salesforce Object Query Language (SOQL) and search
using Salesforce Object Search Language (SOSL). This allows complex operations using SObjects relationships.
Bulk API Operations
Salesforce Bulk API is a specialized asynchronous RESTful API for loading and querying bulk of data at once. The
ballerinax/sfdc
module supports bulk data operations for CSV, JSON, and XML data types.
Event Listener
The Salesforce Streaming API publishes change events, which represent changes to Salesforce records. Changes include creation of a new record, updates to an existing record, deletion of a record, and undeletion of a record.
The ballerinax/sfdc
module includes a Listener that would capture events on SObjects defined in a Salesforce
instance..
Prerequisites
-
Salesforce Organization
You can simply setup the Salesforce Developer Edition Organization for testing purposes through the following link developer.salesforce.com/signup.
-
Verify API Enabled permission in your Salesforce Organization
-
Download and install Ballerina.
-
Install java and set up environment
Quickstart(s)
Step 1: Import Ballerina Salesforce module
First, import the ballerinax/sfdc
module into the Ballerina project.
import ballerinax/sfdc;
Instantiate the connector by giving authentication details in the HTTP client config, which has built-in support for OAuth 2.0 to authenticate and authorize requests. The Salesforce connector can be instantiated in the HTTP client config using the access token or using the client ID, client secret, and refresh token.
Step 2: Obtain Tokens for authentication
- Visit Salesforce and create a Salesforce Account.
- Create a connected app and obtain the following credentials:
- Base URL (Endpoint)
- Access Token
- Client ID
- Client Secret
- Refresh Token
- Refresh Token URL
- When you are setting up the connected app, select the following scopes under Selected OAuth Scopes:
- Access and manage your data (api)
- Perform requests on your behalf at any time (refresh_token, offline_access)
- Provide access to your data via the Web (web)
- Provide the client ID and client secret to obtain the refresh token and access token. For more information on obtaining OAuth2 credentials, go to Salesforce documentation.
Step 3: Create the Salesforce client
The Ballerina Salesforce connector has allowed users to create the client using the direct token configuration and as well as bearer token configuration.
Users are recommended to use direct-token config when initializing the Salesforce client for continuous access by
providing the Salesfoce account's domain URL as the baseURL
and the client id
, client secret
, refresh token
obtained in the step two and https://login.salesforce.com/services/oauth2/token
as refreshUrl
in general scenarios.
// Create Salesforce client configuration by reading from config file. sfdc:SalesforceConfiguration sfConfig = { baseUrl: <"EP_URL">, clientConfig: { clientId: <"CLIENT_ID">, clientSecret: <"CLIENT_SECRET">, refreshToken: <"REFRESH_TOKEN">, refreshUrl: <"REFRESH_URL"> } }; sfdc:Client baseClient = new (sfConfig);
If the user already owns a valid access token he can initialize the client using bearer-token configuration providing the access token as a bearer token for quick API calls.
sfdc:SalesforceConfiguration sfConfig = { baseUrl: <"EP_URL">, clientConfig: { token: <"ACCESS_TOKEN"> } }; sfdc:Client baseClient = new (sfConfig);
This access token will expire in 7200 seconds in general scenarios and the expiration time of the access token can be different from organization to organization. In such cases users have to get the new access token and update the configuration.
If you want to add your own key store to define the secureSocketConfig
, change the Salesforce configuration as
mentioned below.
// Create Salesforce client configuration by reading from config file. sfdc:SalesforceConfiguration sfConfig = { baseUrl: <"EP_URL">, clientConfig: { clientId: <"CLIENT_ID">, clientSecret: <"CLIENT_SECRET">, refreshToken: <"REFRESH_TOKEN">, refreshUrl: <"REFRESH_URL"> }, secureSocketConfig: { trustStore: { path: <"TRUSTSTORE_PATH"">, password: <"TRUSTSTORE_PASSWORD"> } } }; sfdc:Client baseClient = new (sfConfig);
Step 4: Implement Operations
SObject Operations
As described earlier Ballerina Salesforce connector facilitates users to perform CRUD operations on SObject through remote method invocations.
Create Record
The createRecord
remote function of the baseclient can be used to create SObject records for a given SObject type.
Users need to pass SObject name and the SObject record in json format to the createRecord
function and it will return
newly created record Id as a string at the success and will return an error at the failure.
json accountRecord = { Name: "John Keells Holdings", BillingCity: "Colombo 3" }; string|sfdc:Error recordId = baseClient->createRecord("Account", accountRecord);
Get Record
The getRecord
remote function of the baseclient can be used to get SObject record by SObject Id. Users need to pass
the path to the SObject including the SObject Id to the getRecord
function and it will return the record in json at
the success and will return an error at the failure.
string testRecordId = "001xa000003DIlo"; string path = "/services/data/v48.0/sobjects/Account/" + testRecordId; json|Error response = baseClient->getRecord(path);
Update Record
The updateRecord
remote function of the baseclient can be used to update SObject records for a given SObject type.
Users need to pass SObject name, SObject Id and the SObject record in json format to the updateRecord’ function and it
will return true
at the success and will return an error at the failure.
json account = { Name: "WSO2 Inc", BillingCity: "Jaffna", Phone: "+94110000000" }; sfdc:Error? isSuccess = baseClient->updateRecord("Account", testRecordId, account);
Delete Record
The Ballerina Salesforce connector facilitates users to delete SObject records by the SObject Id. Users need to pass SObject Name and the SObject record id as parameters and the function will return true at successful completion.
string testRecordId = "001xa000003DIlo"; sfdc:Error? isDeleted = baseClient->deleteRecord("Account", testRecordId);
Convenient CRUD Operations for Common SObjects
Apart from the common CRUD operations that can be used with any SObject, the Ballerina Salesforce Connector provides customized CRUD operations for pre-identified, most commonly used SObjects. They are Account, Lead, Contact, Opportunity and Product.
Following are the sample codes for Account’s CRUD operations and the other above mentioned SObjects follow the same implementation and only the Id should be changed according to the SObject type.
Create Account
createAccount
remote function accepts an account record in json as an argument and returns Id of the account created
at success.
json accountRecord = { Name: "John Keells Holdings", BillingCity: "Colombo 3" }; string|sfdc:Error accountId = baseClient->createAccount(accountRecord);
Get Account by Id
User needs to pass the Id of the account and the names of the fields needed parameters for the getAccountById
remote
function. Function will return the record in json format at success.
string accountId = "001xa000003DIlo"; json|sfdc:Error account = baseClient->getAccountById(accountId, Name, BillingCity);
Update Account
updateAccount
remote function accepts account id and the account record needed to update in json as arguments and
returns true at success.
string accountId = "001xa000003DIlo"; json account = { Name: "WSO2 Inc", BillingCity: "Jaffna", Phone: "+94110000000" }; sfdc:Error? isSuccess = baseClient->updateRecord(accountId, account);
Delete Account
User needs to pass the Id of the account he needs to delete for the deleteAccount
remote function. Function will
return true at success.
string accountId = "001xa000003DIlo"; sfdc:Error? isDeleted = baseClient->deleteAccount(accountId);
Query Operations
The getQueryResult
remote function executes a SOQL query that returns all the results in a single response or if it
exceeds the maximum record limit, it returns part of the results and an identifier that can be used to retrieve the
remaining results.
string sampleQuery = "SELECT name FROM Account"; SoqlResult|Error res = baseClient->getQueryResult(sampleQuery);
The response from getQueryResult
is either a SoqlResult
record with total size, execution status, resulting records,
and URL to get the next record set (if query execution was successful) or Error (if the query execution was unsuccessful).
if (response is sfdc:SoqlResult) { io:println("TotalSize: ", response.totalSize.toString()); io:println("Done: ", response.done.toString()); io:println("Records: ", response.records.toString()); } else { io:println("Error: ", response.message()); }
If response has exceeded the maximum record limit, response will contain a key named ‘nextRecordsUrl’ and then the user
can call getNextQueryResult
remote function to get the next record set.
sfdc:SoqlResult|sfdc:Error resp = baseClient->getNextQueryResult(<@untainted>nextRecordsUrl);
Search Operations
The searchSOSLString
remote function allows users to search using a string and returns all the occurrences of the
string back to the user. SOSL searches are faster and can return more relevant results.
string searchString = "FIND {WSO2 Inc}"; sfdc:SoslResult|Error res = baseClient->searchSOSLString(searchString);
Operations to get SObject Metadata
Ballerina Salesforce Connector facilitates users to retrieve SObject related information and metadata through Salesforce REST API. Following are the remote functions available for retrieving SObject metadata.
Remote Function | Description |
describeAvailableObjects | Lists the available objects and their metadata for your organization and available to the logged-in user |
getSObjectBasicInfo | Returns metadata of the specified SObject |
describeSObject | Returns metadata at all levels for the specified object including the fields, URLs, and child relationships |
sObjectPlatformAction | Query for actions displayed in the UI, given a user, a context, device format, and a record ID |
Operations to get Organizational Data
Apart from the main SObject related functions Ballerina Salesforce Connector facilitates users to get information about their organization. Following are the remote functions available for retrieving organizational data.
Remote Function | Description |
getAvailableApiVersions | Use the Versions resource to list summary information about each REST API version currently available, including the version, label, and a link to each version's root |
getResourcesByApiVersion | Use the Resources by Version resource to list the resources available for the specified API version. This provides the name and URI of each additional resource. Users need to provide API Version as a parameter to the function. |
getOrganizationLimits | Use the Limits resource to list your org limits. |
Bulk Operations
Using the createJob
remote function of the base client, we can create any type of job and of the data type JSON, XML
and CSV. createJob
remote function has four parameters.
- Operation - INSERT, UPDATE, DELETE, UPSERT or QUERY
- SObject type - Account, Contact, Opportunity etc.
- Content Type - JSON, XML or CSV
- ExternalIdFieldName (optional) - Field name of the external ID incase of an Upsert operation
Step by step implementation of an insert
bulk operation has described below. Follow the same process for other
operation types too.
error|sfdc:BulkJob insertJob = baseClient->createJob("insert", "Contact", "JSON");
Using the created job object, we can add a batch to it, get information about the batch and get all the batches of the job.
json contacts = [ { description: "Created_from_Ballerina_Sf_Bulk_API", FirstName: "Morne", LastName: "Morkel", Title: "Professor Grade 03", Phone: "0442226670", Email: "morne89@gmail.com" } ];
//Add json content. error|sfdc:BatchInfo batch = baseClient->addBatch(insertJob, contacts);
//Get batch info. error|sfdc:BatchInfo batchInfo = baseClient->getBatchInfo(insertJob, batch.id);
//Get all batches. error|sfdc:BatchInfo[] batchInfoList = baseClient->getAllBatches(insertJob);
//Get the batch request. var batchRequest = baseClient->getBatchRequest(insertJob, batchId);
//Get the batch result. error|sfdc:Result[] batchResult = baseClient->getBatchResult(insertJob, batchId);
The getJobInfo
remote function retrieves all details of an existing job.
error|sfdc:JobInfo jobInfo = baseClient->getJobInfo(insertJob);
The closeJob
and the abortJob
remote functions close and abort the bulk job respectively. When a job is closed, no
more batches can be added. When a job is aborted, no more records are processed. If changes to data have already been
committed, they aren’t rolled back.
error|sfdc:JobInfo closedJob = baseClient->closeJob(insertJob);
Event Listener
The Listener which can be used to capture events defined in a Salesforce instance is configured as below.
sfdc:ListenerConfiguration listenerConfig = { username: config:getAsString("SF_USERNAME"), password: config:getAsString("SF_PASSWORD") }; listener sfdc:Listener eventListener = new (listenerConfig);
In the above configuration, the password should be the concatenation of the user's Salesforce password and his secret key.
Now, a service has to be defined on the ‘eventListener’ like the following.
@sfdc:ServiceConfig { channelName:"/data/ChangeEvents" } service quoteUpdate on eventListener { resource function onUpdate (sfdc:EventData quoteUpdate) { json quote = op.changedData.get("Status"); if (quote is json) { io:println("Quote Status : ", quote); } } }
The above service is listening to events in the Salesforce and we can capture any data that comes with it.
Samples
Please find the samples for above mentioned use cases through following links.
Samples for Salesforce REST API use cases
These samples demonstrate the employment of Ballerina Salesforce Connector in Salesforce REST API related operations. The samples can be further divided as following
- Samples that can be used with any SObject's CRUD operations
- Samples for convenient access of Account, Contact, Product, Opportunity and Target SObjects's CRUD operations
- Samples for SOSL and SOQL related operations
- Samples for retrieving Organization and SObject metadata
Samples for Salesforce Bulk API use cases
These samples demonstrate the employment of Ballerina Salesforce Connector in Salesforce BULK API related operations. Examples for bulk insert, bulk insert through files, bulk update, bulk upsert and bulk delete using json, csv or xml data sets are given here.
Samples for Event Listener
This sample demonstrates on capturing events using the Event Listener of Ballerina Salesforce Connector. As mentioned above to listen to a certin event users need to select Objects for Change Notifications in the user interface in his/her Salesforce instance.
Building from the Source
Setting up the prerequisites
-
Download and install Java SE Development Kit (JDK) version 11 (from one of the following locations). Oracle, OpenJDK
Note: Set the JAVA_HOME environment variable to the path name of the directory into which you installed JDK.
-
Download and install Ballerina SL Beta3.
-
Install Gradle
Building the Source
Execute the commands below to build from the source after installing the Ballerina SL Beta3 version.
Build the project:
gradle build
To build the library:
bal build ./sfdc
To build the module without the tests:
bal build --skip-tests ./sfdc
Contribution to Ballerina
As an open source project, Ballerina welcomes contributions from the community.
For more information, go to the contribution guidelines.
Code of Conduct
All the contributors are encouraged to read the Ballerina Code of Conduct.
Useful Links
- Discuss the code changes of the Ballerina project in ballerina-dev@googlegroups.com.
- Chat live with us via our Slack channel.
- Post all technical questions on Stack Overflow with the #ballerina tag.
References
Trailhead Salesforce Documentation - https://trailhead.salesforce.com/en/content/learn/modules/api_basics/api_basics_overview
Salesforce REST API Documentation - https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest