This article will guide you through configuring integration between SalesForce and DropBox, how to avoid user interaction to grant access to DropBox and also how to keep SalesForce notified about changes in DropBox.
There are some situations when you think it would be good to take files from DropBox, parse it in SalesForce and make some operations according to parsed data within SalesForce. Even more, it would be good if SalesForce could take required action right after the file has been changed or uploaded to DropBox.
Suppose we have DropBox account for integration and SalesForce application.
SalesForce application will use DropBox API for integration. To use API, all requests need to be authenticated. For this purpose, DropBox uses OAuth, but it requires user interaction to grant access to the DropBox account.
Our solution will be for backend integration and uses only one DropBox account. So user interaction can be omitted.
Call DropBox API without user interaction
1 - Create DropBox API app in App Console
2 - Generate an access token. Go to DropBox app settings and click "Generate access token"
3 - In SalesForce setup configure remote sites for DropBox to be able to send request to API from Apex
4 - Now you can call DropBox API from Apex without user interaction
String url='https://api.dropboxapi.com/1/account/info';
HttpRequest request = new HttpRequest();
request.setEndpoint(url);
request.setMethod('GET');
request.setHeader('Authorization', 'Bearer ' + '');
Http http = new Http();
HTTPResponse res = http.send(request);
System.debug(res.getBody());
SalesForce and DropBox real time integration
In the previous section, DropBox App was created and appropriate configurations in SalesForce were made. At this point, SalesForce can call DropBox API. Let's make SalesForce receive notifications from DropBox when files are changed.
DropBox can send notifications to web app when some files are changed. This feature is called Webhooks.
To use DropBox Webhooks with SalesForce follow these steps:
1 - Create Apex REST Service which will be used by DropBox App to notify SalesForce about changes.
DropBox sends URL verification after Webhook URL is registered in the app. When our services are called for verification, we need to return a value of "challenge" parameter. To achieve it, place following lines of code in HttpGet method:
String challenge = RestContext.request.params.get('challenge');
if(String.isNotBlank(challenge)){
RestContext.response.addHeader('Content-Type', 'text/plain');
RestContext.response.responseBody = Blob.valueOf(challenge);
}
Now we need to create POST method in our service to make it possible to process notifications from DropBox
DropBox notification's JSON example from Dropbox Developer Docs about Webhooks:
{
"delta": {
"users": [
12345678,
23456789,
...
]
}
}
As you can see notifications contain only user IDs - this means that we need to get all changes manually by calling /delta. I will not go into details about DropBox /delta method because this is outside of article’s scope and can be read in the link provided.
Here is a complete sample Apex class for service:
@RestResource(urlMapping='/DropBoxPoint/*')
global class DropBoxPoint {@HttpGet global static void DropBoxVerification() {
String challenge = RestContext.request.params.get('challenge');
if(String.isNotBlank(challenge)){
RestContext.response.addHeader('Content-Type', 'text/plain');
RestContext.response.responseBody = Blob.valueOf(challenge);
}
}@HttpPost global static void DropBoxNotification() {
String DropBoxSignature = RestContext.request.headers.get('X-Dropbox-Signature');
Blob DropBoxNotification = RestContext.request.requestBody;if(String.IsNotBlank(DropBoxSignature) && ValidateSignature(DropBoxSignature, DropBoxNotification)){
//get changes via DropBox API /delta method
//and perform actions on SalesForce
}
else{
System.debug('Signature is not valid');
RestContext.response.statuscode = 404;
}
}private static Boolean ValidateSignature(String signature, Blob value){
String generatedSign = EncodingUtil.convertToHex(Crypto.generateMac('HmacSHA256', value, Blob.valueOf('DropBox App secret')));
return signature.equalsIgnoreCase(generatedSign);
}
}
2 - By default created REST service requires authorization, but verification and notifications from DropBox are sent without authorization information. So REST services must be accessible without authorization. To make an anonymous access to Apex REST service, follow the next steps:
2.1 - Create a public web site in Salesforce - Setup -> Develop -> Sites
2.2 - Register a domain before creating a site
2.3 - Create a site after domain registration creates a site
Under "Active Site Home Page", we can place some dummy Visualforce page because it will not be used by real users.
2.4 - Remember to activate site by pressing "Activate" button
2.5 - Now make Apex REST service class accessible. Press "Public Access Settings" button
2.6 - Press "Edit" button under "Enabled Apex Class Access" section
2.7 - Select appropriate Apex class
2.8 - Site is created and listed in Setup->Develop->Sites
2.9 - Now our service is accessible by URL
https://-developer-edition.eu5.force.com/services/apexrest/
and can be tested by entering URL in browser or with software like cURL
https://-developer-edition.eu5.force.com/services/apexrest/ ?challenge=Challenge_Test
The result will be "Challenge_Test". Now URL can be verified by DropBox.
3 - Register a WebHook URL in DropBox's App Console
After "Add" button is clicked, URL will be verified and added to DropBox app.
In future, if the user will make some changes, DropBox will notify SalesForce immediately and required actions can be performed on SalesForce side.
OK, we are done!
This approach can be used when you need to keep in control all integration process without installing any third party solutions from SalesForce AppExchange. In addition, there is no need to write scheduled Apex classes because SalesForce will be notified by DropBox about changes and can take necessary actions immediately.
About the author: Igor Cvetkov is an experienced software developer previously working with custom solutions based on Microsoft technology stack. In the past year, he has switched to SalesForce development where he applies his past experience to the more complex SalesForce and Apex configuration. |