How To sync the SalesForce AddressBook with Asterisk PBX

SalesForce is one of the best CRM product around. Its quite flexible and have different kind of APIs. There is one that allow you to directly does query via SOAP into their Oracle DB infrascruture.

I used this feature quite a while ago to download nightly the entire CRM addressbook into the Asterisk PBX in order to have correct user detail displayed onto the agent’s phone when the user will callback my PBX customer.

Salesforce API Key

Before attempting any coding you need to obtain a salesforce api key to access their SOAP gaetway. You can obtain this by following the instruction into the online manual, you just need to log-in inside salesforce and browse the exact menù where you can generate it.

Then i created a Perl script that uses the following CPAN modules:

  • NetAddr::IP
  • XML::Simple
  • Config::General
  • Data::Dumper

 

Login into SalesForce

The first thing to do is to login inside the salesforce system via SOAP. I did this in the almost lower low-level way by creating a string and submitting it to their server using the curl command line tool.

NOTE: I didn’t used a high level Soap library because the PBX where this script is installed has a limited amount of flash disk space and i simply could not install all the files i want, i used what i’ve already got available.

The soap message to build is the following:

my $req = '<?xml version="1.0" encoding="utf-8" ?>
<env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
<env:Body>
<n1:login xmlns:n1="urn:partner.soap.sforce.com">
<n1:username>'. $conf{sf_user}. '</n1:username>
<n1:password>'. $conf{sf_pass}. $conf{sf_key}. '</n1:password>
</n1:login>
</env:Body>
</env:Envelope>';

You can notice that they require to append your secret key to the password of the user that you’ve enabled for API access.

As soon i stored this message into a temporary file in /tmp/salesforce-login.txt i issued the following command to authenticate my script:

my $cmd = 'curl "https://login.salesforce.com/services/Soap/u/17.0" -H "Content-Type: text/xml; charset=UTF-8" -H "SOAPAction: login" --cookie-jar curl-cookies.db -d @'. $tmpfile. ' 2>/tmp/salesforce.err';

If successfull the curl program will store the precious cookie in a temporary file that i will use in all the subsequents requests.

Also you need to carefully parse the response obtained by this login request since it contains two important values that you need to use into the next step:

  • server URL, because the login server is different from the DB/API server
  • sessionID, of your current session

Having $resp the variable with the text response i obtained those two data with the following code:

my $xml = new XML::Simple;
my $data = $xml->XMLin($resp);
my $sessionid = $data->{'soapenv:Body'}->{loginResponse}->{result}->{sessionId};
my $serverurl = $data->{'soapenv:Body'}->{loginResponse}->{result}->{serverUrl};

Querying the SalesForce DB

We’ve all the elements now to issue or query statements at their API/DB with the following SOAP message:

my $req = '<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:urn="urn:partner.soap.sforce.com">
<soapenv:Header>
<urn:SessionHeader>
<urn:sessionId>'. $sessionid. '</urn:sessionId>
</urn:SessionHeader>
</soapenv:Header>
<soapenv:Body>
<urn:query>
<urn:queryString>SELECT Name, Phone, Fax FROM Account order by Name</urn:queryString>
</urn:query>
</soapenv:Body>
</soapenv:Envelope>';

As you can notice i extracted only the 4 fieds from the Account table that makes sence to use on the PBX.

Stored the SOAP message in $tmpfile i issued the request via curl this way:

$cmd = 'curl "'. $serverurl. '" -H "Content-Type: text/xml; charset=UTF-8" -H \'SOAPAction: ""\' --cookie-jar curl-cookies.db -d @'. $tmpfile. ' 2>/tmp/salesforce.err';

Aftter the request you have to parse the response. You can obtain the number of records. You can obtain both this way:

$data = $xml->XMLin($resp);
my @rows = @{ $data->{'soapenv:Body'}->{queryResponse}->{result}->{records} };
foreach my $r (@rows) {
  ...
}

Obtain more data

I repeated the above procedure, just chaning the query, to obtain the “leads” from the CRM.

I changed the query into:
SELECT Company, LastName, FirstName, Phone, MobilePhone, Fax FROM Lead order by Company, LastName, FirstName

The same above for the “contacts“:
SELECT LastName, FirstName, Phone, MobilePhone, OtherPhone, HomePhone, AssistantPhone, Fax FROM Contact order by LastName, FirstName

Final step

I stored all the data into a flatfile (or a DB). Then you need an Asterisk AGI running at each incoming call that goes checking this internal DB and set the matching CallerID name the right way.

How To sync the SalesForce AddressBook with Asterisk PBX, 5.0 out of 5 based on 1 rating
GD Star Rating
loading...