The Original FileMaker Community
Free Templates - Demo Apps - Video Tutorials -Samples - Help - 46000 Member Forum

The Leading Filemaker Developer Tools

Password protection and security…

FileMaker Salesforce Integration – FileMaker Today


With the explosive growth of Salesforce, some businesses using FileMaker are looking to integrate with and/or move some of their existing business processes to Salesforce.


While this has been possible for a long time, it has never been an easy process, involving third party servers and plugins.


Having a FileMaker only solution would mean a clean, debuggable, much less fragile connection to Salesforce.


How?


The team here at Soliant was hoping that the improved “insert from URL” script step would prove to be able to communicate with Salesforce – Alas, the lack of ability to set headers (despite being able to post) means that this script step is not able to be used for communication with Salesforce.


Another option that was explored was using FileMaker –> AppleScript –> Curl –> FileMaker. While this worked, you can imagine it’s stability. Not great.


However, FileMaker recently announced an improvement to their WebViewer component that now finally allows pure FileMaker communication with Salesforce, Via Oauth (well, all the code lives in FileMaker, anyway). Now we are talking!


JavaScript that is loaded as part of a webpage can now communicate with FileMaker via the FMP URL syntax. This has been extensively written up in the popular blog post by one of my fellow developers at Soliant: http://www.soliantconsulting.com/blog/2014/04/getting-started-javascript…. This blog relies extensively on Mike’s work. Thanks Mike!


Essentially, we can now open a OAuth Useragent Login webviewer and retrieve the token and refresh_url provided by Salesforce. From here, we can make requests to Salesforce of virtually any kind, assuming permissions are set up right. We can query a custom Rest-Based Class or hit Salesforce’s built-in Rest API that exists for every object.


 


I will now explore implementation details in:


The Nitty Gritty


Salesforce:


To start with, it’s probably a good idea to read up on OAuth, specifically the User-Agent flow described about half-way down this page: https://developer.salesforce.com/page/Digging_Deeper_into_OAuth_2.0_on_F…


Second, you need to ensure you have created a free Developer Salesforce Org. If you haven’t, head over to http://salesforce.com to get one. 


Now, once you are in and setup, go to “Setup->Create->Apps”. At the bottom of the page, hit “New Connected App”. Enter the name, API name and email address. These are not super important.


In OAuth Settings, set up the app as shown in the picture below (here is the URL for reference – https://login.salesforce.com/services/oauth2/success):



Once you have saved this, you’ll be taken to the detail page of the connected app. Copy the consumer key, the consumer secret and the callback URL and keep them for later reference.


 


FileMaker: (please refer to the supplied FileMaker file)


To implement User-Agent OAuth flow, first we open a webpage in FileMaker. The URL should be something like this:

url_org & "/services/oauth2/authorize?response_type=code&client_id="& client_id &"&redirect_uri=" & uri_redirect&"&display=touch&scope=full refresh_token"


Where client_id, uri_redirect are fields on the current record.


This will open up a screen where the user is able to authenticate to Salesforce – use your previously generated developer credentials to gain access:



This page redirects to the redirect_uri previously specified and we are able to scrape the token from there using something like this:

Let (  [result = GetLayoutObjectAttribute ( "login_webviewer" ; "source" ); 
         start = Position ( result ; "access_token" ; 1 ; 1 ) + 13; 
         end = Position ( result ; "&" ; start ; 1 )]; 
         Middle(result;start;end-start)   )


Don’t forget to URLdecode this data – Salesforce sends a ‘!’ as part of the token that appears as ‘%25’ – leaving the token like this will cause strange errors! Look at the FileMaker file for examples on how to scrape the refresh token also.


Talking to Salesforce!


Now we are able to make requests to Salesforce at will, assuming we include the correct header information. This is where JavaScript comes in handy: using a “Set Webviewer” step, we can set a data URL with our entire web page that we want to load, and the JavaScript that we want to run (in this case on the onload event). Despite using Safari as rendering technology, FileMaker does not worry about CORS, which is a big relief – if it had, we would have been back to square one. This makes sense, as the FileMaker environment is much more locked down than a standard webpage is.


Here is our webpage (with embedded JavaScript):

"data:text/html," & "<html><body>

<p>
Running REST based SOQL query...<br />
</p>

<script>

var documentLoaded = setInterval(function () {
    if(document.readyState === "complete") {
        performQuery();
        clearInterval(documentLoaded);
    }
}, 100);

function performQuery() {

    var query = "" & Requests::url_org & "/services/data/v32.0/query/?q=" & UrlEncode(Requests::soql_query) & "";
    var request = new XMLHttpRequest();
    request.open("GET", query, true);

    request.setRequestHeader("Authorization", "Bearer  " & token & "");
    request.setRequestHeader("Content-Type", "text/plain");

    request.onload = function() {
      if (request.status >= 200 && request.status < 400) {
        var resp = request.responseText;
          sendResults(request);
      } else {
            sendResults(request);
      }
    };
    request.onerror = function() {
       sendResults(request);
    };
    try {
         request.send();
    }
    catch (e){
         sendResults(e);
      }
}
function sendResults(results){
       var stringResults = JSON.stringify(results);
    var testUrl = "fmp://$/SF_Oauth2?script=handle_raw_results&param=" + stringResults;
    window.location = testUrl ;
    return false;
}
</script>
</body></html>"


I’ll explain what it does.


First, it defines an onload function, which runs as soon as the page has rendered. This runs the SOQL query on Salesforce that we want. This can be any valid SOQL query (actually, I need to check if there are any limits to SOQL queries run via the REST api – but for now, any basic query will run here).


Next it parses the result and hands it off to FileMaker via the FMP URL syntax using the new ‘$’ (currently open file) syntax. Note that the data is run through JSON.stringify.


Implementation Details and Gotchas:


UrlEncode: In performQuery() it uses a custom UrlEncode function written by Jeremiah Small (another Soliant developer). Get it here http://www.briandunning.com/cf/165. This is because the built in UrlEncode function that FileMaker provides does not handle single quotes properly.


Data URL Construction: When constructing the webpage to load in the Webviewer, you are doing the entire load using a “data” url. FileMaker will treat your entire webpage as a single string, so you need to build up the webpage as such. For exampe, to add a filemaker function while creating the string, you would do something like this: 

"data:text/html," & "<html><body><p>
Running State Query...<br /></p>" & 
NativeFilemakerFunctionHere() & "<script>.... "


Comments: Do not use line comments here unless you are going to explicitly break each line. This will cause your script to not work (and like all errors in this script you will get no notification of the error)


Debugging: For testing, it’s often a good idea to recreate the page as a normal html page and run it on your local webserver – then you can inspect the file and find Javascript Errors.


That’s it!! You now have your data in FileMaker. 


Extra for Experts


To use a custom Rest Class in Apex, create a class in Salesforce “Setup->Develop->Apex Classes->New”. Name it something like “AccountController” eg:

@RestResource(urlMapping='/Accounts/*')
global with sharing class RESTAccountController {

@HttpGet
  global static List getAccountsbyState(){
    //Get Company Name from URI
    String CompanyBillingState = RestContext.request.params.get('companyState');    
    List company = [ Select ID, Name, Website from Account where BillingState =: CompanyBillingState];
    return company;
  }
}


In the security settings for the class, make sure that every Salesforce profile can access the class. Then save and go back to FileMaker. Here you will follow much the same process as before, but you’ll be calling a different url in FileMaker – something like this: 

This website uses cookies to improve your experience. We'll assume you're ok with this, but you can opt-out if you wish. Accept Read More

Privacy & Cookies Policy