Skip to content

Import Contacts into Salesforce Using FTP

Ballerina is an open-source programming language that supports developers to integrate their system easily with the support of connectors. In this guide, we are mainly focusing on importing CSV file having contacts into Salesforce using FTP connector.

The wso2/sfdc46 module allows you 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 insert, upsert, update, query and delete operations for CSV, JSON and XML data types which provides in Salesforce bulk API. It handles OAuth 2.0 authentication.

The wso2/ftp module provides an FTP client and an FTP server listener implementation to facilitate an FTP connection to a remote location.

You can find other integrations modules from wso2-ballerina Github organization.

What you'll build

This application listens to a remote FTP location and when the CSV file appears (this CSV file contains contacts that should be added to salesforce) it will fetch the CSV file content and insert all the contacts in the CSV file into Salesforce using salesforceBulkClient as a single batch. Then it will get the insertion result using salesforceBulkClient and if the operation is successful, a success message is logged.

import contacts to sfdc using ftp

Before you begin

  • Download and install Ballerina Integrator for your operating system

    Note: This installs Ballerina language version 1.0.1, a compiler plugin to help mitigate errors, and snippet .jar files for custom auto-completion.

  • Install Oracle JDK 1.8.*
  • Install VS Code

    Tip: For a better development experience, use VS Code (which is the recommended editor for Ballerina Integrator).

  • Install the Ballerina Integrator Extension from the VS Code marketplace

Get the code

You can download the ZIP file and extract the contents to get the project code.

Download ZIP


A Ballerina project needs to be created for the integration use case explained above. Please follow the steps given below to create the project and modules. You can learn about the Ballerina project and modules in this guide.

1. Create a new project.

$ ballerina new import-contacts-into-salesforce-using-ftp

2. Create a module.

$ ballerina add salesforce_ftp_integration

The project structure is created as indicated below.

    ├── Ballerina.toml
    └── src
        └── salesforce_ftp_integration
            ├── main.bal
            ├── resources
            └── tests
                └── resources

3. Set up credentials for accessing Salesforce

  • 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
  • Note: 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, see the Salesforce documentation.

4. Set up remote FTP server

Set up remote FTP server and obtain the following credentials:

  • FTP Host
  • FTP Port
  • FTP Username
  • FTP Password
  • Path in the FTP server to add CSV files

Add the src/salesforce_ftp_integration/resources/contacts.csv file to the FTP path you mentioned above.

5. Add project configurations file

Add the project configuration file by creating a ballerina.conf file under the root path of the project structure. This file should have following configurations. Add the obtained Salesforce configurations and FTP configurations to the file.

SF_BASE_URL="<Salesforce base url (eg:>"
SF_ACCESS_TOKEN="<Salesforce access token>"
SF_CLIENT_ID="<Salesforce client ID>"
SF_CLIENT_SECRET="<Salesforce client secret>"
SF_REFRESH_URL="<Salesforce refresh url (eg:>"
SF_REFRESH_TOKEN="<Salesforce refresh token>"
SF_NO_OF_RETRIES=<No of retries for getting inserion results (eg: 10)>
FTP_HOST="<FTP host IP (eg:>"
FTP_PORT=<FTP host port (eg: 21)>
FTP_USERNAME="<FTP username>"
FTP_PASSWORD="<FTP password>"
FTP_PATH="<Path in the FTP server you added conatats.csv (eg: /home/ftp-user/sfdc)>"
FTP_POLLING_INTERVAL=<FTP listner polling interval (eg: 600000)>

6. Write the integration

Open the project with VS Code. The integration implementation is written in the src/salesforce_ftp_integration/main.bal file.

import ballerina/config;
import ballerina/io;
import ballerina/log;
import wso2/ftp;
import wso2/sfdc46;

// Salesforce configuration.
sfdc46:SalesforceConfiguration sfConfig = {
    baseUrl: config:getAsString("SF_BASE_URL"),
    clientConfig: {
        accessToken: config:getAsString("SF_ACCESS_TOKEN"),
        refreshConfig: {
            clientId: config:getAsString("SF_CLIENT_ID"),
            clientSecret: config:getAsString("SF_CLIENT_SECRET"),
            refreshToken: config:getAsString("SF_REFRESH_TOKEN"),
            refreshUrl: config:getAsString("SF_REFRESH_URL")

// FTP listener configuration.
listener ftp:Listener remoteServer = new ({
    protocol: ftp:FTP,
    host: config:getAsString("FTP_HOST"),
    secureSocket: {
        basicAuth: {
            username: config:getAsString("FTP_USERNAME"),
            password: config:getAsString("FTP_PASSWORD")
    port: config:getAsInt("FTP_PORT"),
    path: config:getAsString("FTP_PATH"),
    pollingInterval: config:getAsInt("FTP_POLLING_INTERVAL"),
    fileNamePattern: "(.*).csv"

// FTP client configuration.
ftp:ClientEndpointConfig ftpConfig = {
    protocol: ftp:FTP,
    host: config:getAsString("FTP_HOST"),
    port: config:getAsInt("FTP_PORT"),
    secureSocket: {
        basicAuth: {
            username: config:getAsString("FTP_USERNAME"),
            password: config:getAsString("FTP_PASSWORD")

// Create FTP client.
ftp:Client ftpClient = new (ftpConfig);
// Create salesforce client.
sfdc46:Client salesforceClient = new (sfConfig);
// Create salesforce bulk client.
sfdc46:SalesforceBulkClient sfBulkClient = salesforceClient->createSalesforceBulkClient();

service ftpServerConnector on remoteServer {
    resource function fileResource(ftp:WatchEvent m) returns error? {
        // Create CSV insert operator.
        sfdc46:CsvInsertOperator csvInserter = check sfBulkClient->createCsvInsertOperator("Contact");

        foreach ftp:FileInfo file in m.addedFiles {
            log:printInfo("CSV file added to the FTP location: " + file.path);
            io:ReadableByteChannel rbc = check ftpClient->get(file.path);
            // Import csv contacts to Salesforce.
            sfdc46:BatchInfo batch = check csvInserter->insert(<@untainted> rbc);
            // Getting the results of the import.
            sfdc46:Result[] batchResult = check csvInserter->getResult(, config:getAsInt("SF_NO_OF_RETRIES"));
            // Check whether all batch results are successful.
            if (checkBatchResults(batchResult)) {
                log:printInfo("Imported contacts successfully!");
            } else {
                log:printError("Errors in imported contacts!");

// Check whether batch results are successful or not.
function checkBatchResults(sfdc46:Result[] results) returns boolean {
    foreach sfdc46:Result res in results {
        if (!res.success) {
            log:printError("Failed result, res=" + res.toString(), err = ());
            return false;
    return true;

function closeReadableByteChannel(io:ReadableByteChannel rbc) {
    error? close = rbc.close();
    if (close is error) {
        log:printError("Error occurred while closing Readable Byte Channel.", err = close);

Here the ftpServerConnector service is running on remoteServer, which listens to the configured FTP server location. When a CSV file is added to the FTP server, the file content will be retrieved and inserted into the Salesforce using sfBulkClient.


First let’s build the module. Navigate to the project root directory and execute the following command.

$ ballerina build salesforce_ftp_integration

This creates the executables. Now run the salesforce_ftp_integration.jar file created in the above step.

$ java -jar target/bin/salesforce_ftp_integration.jar

You will see the following log after successfully importing contacts to Salesforce.

2019-09-26 19:14:09,916 INFO  [wso2/salesforce_ftp_integration] - CSV file added to the FTP location: /home/ftp-user/sfdc/contacts.csv
2019-09-26 19:14:13,855 INFO  [wso2/salesforce_ftp_integration] - Imported contacts successfully!