Simon Fell > Its just code > Salesforce.com

Tuesday, January 12, 2016

2016 is the year you find out how well you understand all the integrations & API usage you have against the salesforce API. There are 2 changes being made in 2016 that will impact a lot of integrations & API clients.

API retirement for www.salesforce.com

www.salesforce.com hosted the original API login service, many years ago a dedicated login service was hosted at login.salesforce.com. Starting in 2016 the login service running at www.salesforce.com is going to be disabled..

Disablement of TLS 1.0

Support for TLS 1.0 is being disabled, this will affect many HTTPS client libraries, especially those that are not upto date, or don't get their TLS/SSL support directly from the host OS.

Impact for Beatbox

Beatbox is a python library i wrote for accessing the salesforce.com API. If you have integrations built using Beatbox you need to carefully review your python environment in order not to be impacted. Support for TLS 1.1 & TLS 1.2 requires python 2.7.9 (or later) and OpenSSL 1.0.1 (or later). If you're running on older versions that this, when TLS 1.0 is disabled, your integration will stop working!. Note that if you're on OS X, the bundled version of OpenSSL is 0.9.8 and needs to be upgraded to continue to work. There is more info in the readme about this. Beatbox was updated in 2010 to start using login.salesforce.com instead of www.salesforce.com for logins, so if you're beatbox version is older than that, you'll need to update to a new version (or update your usage to explicitly set serverUrl before calling login)

Impact for ZKSforce

ZKSforce is a library for iOS & OSX to call the salesforce API. It gets its HTTPS support via the cocoa NSURLRequest class, which is part of the OS. All recent versions of iOS & OS X have support for TLS 1.2 and you shouldn't have any issues related to the TLS 1.0 disablement. However ZKSforce by default sends login requests to www.salesforce.com unless you have a version from Sept 2015 or later. You can either upgrade to the latest version of ZKSforce or explicitly set the auth server before calling login, e.g.
[client setLoginProtocolAndHost:@"https://login.salesforce.com"]

Tuesday, December 3, 2013

There's a big update to zkSforce available, it now supports the entire v29 Partner API, all the new calls, soap headers etc. Also there are aysnc/blocks versions available of all the API calls, so you can safely make soap calls on a background thread and not block the UI.

The update is mostly driven from a new tool I wrote which generates code from the WSDL, so as new WSDLs get released keeping zkSforce unto date will be easier. (note you don't need to use this tool, just add zkSforce to your project as usual and off you go). This move to generated code means there are a number of minor changes from previous versions that you might need to address if you update to the latest version, check the read me for all the details.

If you try it out, let me know how you get on.

Tuesday, May 21, 2013

Fork me on GitHub

I've been tinkering with Python for a while, but have wanted to try my hand at something more complex that hello world with it, I ended up building Beatbox, a simple to use, minimal dependency library for accessing the Salesforce.com API. (Given the pace of the branding train at Salesforce, I've decided to stop trying to put force or sforce in any of my sforce API tools).

Rather than some thick data binding layer, most of the stuff you pass into the library is dictionaries, and most of the data you get back is in the form of a xmltramp representation of the relevant result part of the soap response (xmltramp rocks BTW) It includes all the usual sforce perf recommendations, HTTP/1.1 persistent connections, gzip compression on request/responses, batch operations, the main parts of the 20.0 API is currently supported. The login redirect and sessionId header handling is all done for you under the covers, there's still a few loose ends mainly around handling base64, and timezones on datetimes, but other than that you're good to go.

demo.py in the download has samples of calling all the methods, for example to login and then call describeGlobal and print out all the types available is simply

sf = beatbox._tPartnerNS
svc = beatbox.Client()
svc.login(username, password)
dg = svc.describeGlobal()
for t in dg[sf.sobjects:]:
	print str(t[sf.name]) + " \t " + str(t[sf.label])
making a call to query and printing the results,
sf = beatbox._tPartnerNS
svc = beatbox.Client()
svc.login(username, password)
qr = svc.query("select Id, Name from Account")
print "query size = " + str(qr[sf.size])
for rec in qr[sf.records:]:
    print str(rec[2]) + " : " + str(rec[3])
creating a new account
sf = beatbox._tPartnerNS
svc = beatbox.Client()
svc.login(username, password)
a = { 'type': 'Account',
    'Name': 'New Account',
    'Website': 'http://www.pocketsoap.com/' }
sr = svc.create(a)
if str(sr[sf.success]) == 'true':
    print "id " + str(sr[sf.id])
Updating your chatter status
sf = beatbox._tPartnerNS
svc = beatbox.Client()
loginResult = svc.login(username, password)
user = { 'type' : 'User',
		 'id'   : str(loginResult[sf.userId]),
		 'currentStatus' : newStatus }
r = svc.update(user)
if (str(r[sf.success]) == 'false'):
	print "error updating status:" + str(r[sf.errors][sf.statusCode]) + ":" + str(rr[sf.errors][sf.message])
else:
	print "success!"

The download includes a copy of xmltramp (the only dependency) that has a minor bug fix in it, the beatbox.py library itself and the samples, demo.py, export.py and soql2atom.py.

Beatbox is available on Github.

Thursday, October 25, 2012

SF3 was one of the first OSX/Salesforce tools I wrote, made possible by an API in OSX called Sync Services. With the release of OSX 10.8 (aka Mountain Lion) Apple officially deprecated the Sync Services API (and its future was in doubt for a quite a while prior to that). With this news the future for SF3 is that it doesn't have any future, there is no new API that replaces the functionality of Sync Services. There are APIs to talk to both Address Book and iCal, but without the sync engine piece an app that wanted to sync data between those apps and a 3rd party is going to have to build the entire sync/match/change log functionality itself, a big job. Its possible that exposing the salesforce data using CalDav and CardDav might make it usable from OSX, but I haven't had time to investigate that in any detail.

Friday, March 2, 2012

For quite a while now you've been able to make HTTP requests from Apex to other services, this was aimed at integrations for structured data, xml or json, and so would deal with strings. This made life easier if you were actually doing xml or json, but makes life difficult to impossible if you were trying to deal with binary data. In the recent Spring release this is fixed, and you can now work with binary data (blobs in apex) directly in the http request or response. Here's an example of making a HTTP GET request for an image PNG file, and saving it to the document object in salesforce

HttpRequest r = new HttpRequest();
r.setMethod('GET');
r.setEndpoint('http://www.pocketsoap.com/osx/soqlx/soqlxicon.png');
Http http = new Http();
HttpResponse res = http.send(r);
blob image = res.getBodyAsBlob();

Document d = new Document();
d.name = 'logo.png';
d.body = image;
d.folderId = UserInfo.getUserId();
insert d;
system.debug(d.id);

(Yes, this may well be my one blog post for this year)

Friday, February 18, 2011

Hudson is a popular continuous integration build server, I've been working on a plugin for it that will post build notifications to chatter. The plugin is configurable, so that it can post updates to its own wall, to a specific group (perhaps the project team that owns the build), or to a specific data record (perhaps you have a custom object that represents a build).

You can grab the source and a prebuilt plugin binary from the projects home page on github.

Monday, June 7, 2010

ZKSforce is the Cocoa library i wrote to make it easier to access the Salesforce.com API from Cocoa / Objective-C. I just posted a new version that uses the Salesforce.com v19 API, and has switched out its use of NSXML & NSCalendarDate with libxml & NSDate and so is now compatible with both OSX and iPhone based projects. (iPhone OS 3.2 and up should be good).

Monday, June 7, 2010

The Applescript Connector for Salesforce.com allows you to write applescript that can interact with the salesforce.com API, login, create, update & delete data, run queries, retrieve your scherma's metadata all from Applescript. Now you can more easily integrate Salesforce.com with your OSX desktop and applications.

Friday, May 14, 2010

A friend recently turned me onto Instaviz, a great iPhone / iPad diagraming tool based on graphviz. Graphviz lets you define your diagram as a set of nodes and connections, and it will perform the layout for you. I have something of an interest in being able to visualize your Salesforce.com schema, and some lines of python code later, i had something that would generate a graphviz description of your schema, starting from a primary object, and with the option to go 1 or more levels deep from there. Here's an example for Opportunity, just 1 level deep. (click for full size version)

And here's the generated oppty.gv file that produces that graph. If you have Instaviz or one of the desktop viewers for graphviz, you can open the .gv file directly in those apps. (and/or you can use the commandline tools to generate a png or other formats).

Here's the actual python code, it uses beatbox to call the describeSObject API to discover the schema for your login. You run it as

python gv.py someuser@sample.org mypassword Opportunity > oppty.gv

Here's an even larger model that's 5 levels deep from Account - png rendering (ouch its 6MB), gv (33k)

Wednesday, April 21, 2010

The API allows you to create new entries for Salesforce content by creating new ContentVersion records, you'll at a minimum need to fill out the VersionData which is the actual binary data for the file, and the pathOnClient, which is used to derive the file type, and its title. This will automatically create a new content record and put it in your personal workspace. For a twist here's an example in VisualForce rather than a SOAP based client (the Web Services API & Apex both share the same data model, so everything transfers over).

Here's the controller, called contentController, this just has a Blob property and a go method to create the actual ContentVersion row

public class contentController {

    public blob file { get; set; }
    
    public PageReference go() {
        ContentVersion v = new ContentVersion();
        v.versionData = file;
        v.title = 'from VF';
        v.pathOnClient ='/foo.txt';
        insert v;
        return new PageReference('/' + v.id);
    }
}
And for the VisualForce page, i just used the apex:inputFile to bind to it, nothing pretty, but it'll get you going. You'll probably want to do something more interesting with the title and pathOnClient properties.

<apex:form controller="contentController">
<apex:inputFile value="{!file}" />

<apex:commandbutton action="{!go}" value="go"/>
</apex:form>
</apex:page>
One variation is to have your controller expose a ContentVersion object directly, e.g.
public class contentController {

    public contentController() {
        file = new ContentVersion();
    }
    
    public ContentVersion file { get; set; }
    
    public PageReference go() {
        insert file;
        return new PageReference('/' + file.id);
    }
}	
And have the page bind directly to its properties.
<apex:page controller="contentController">
<apex:form >
<apex:inputFile value="{!file.versionData}" fileName="{!file.pathOnClient}" />
<apex:commandbutton action="{!go}" value="go"/>
</apex:form>
</apex:page>

If you want to experiment with the Content APi, you'll need to have signed up for a developer edition org recently (or go sign up a new one), and turn on the content license for the admin user.

Thursday, February 25, 2010

I updated the Quicksilver plugin for Salesforce.com to support Chatter, you can easily post status updates, URLs & Files to Chatter now from Quicksilver.

There's a minor revision to Trapdoor that adds Google Chrome to the list of available browsers.

SoqlX was updated to support the Salesforce.com v18 API, so that you can do aggregate queries etc, it also now tries much harder to preserve the field ordering in the table from the query.

Sunday, November 22, 2009

I updated the OSX build of the data loader to v17, so now you can access v17 specific objects (like content) and use the new bulk api. And I also updated the TextMate Plugin for apex to v17 as well.

Saturday, July 4, 2009

I built an up to date (api v16) OSX version of the data loader, and feel free to vote for the idea to make it official.

Saturday, April 18, 2009

I released an updated SoqlX a couple of weeks back, it has a number of tweaks, exposing relationship names to make building SOQL-R queries easier, and the filtering object/field list I discussed earlier. And I just posted an updated version of SFFS, the file extension information is now bundled into the filenames for those files that don't have it in the name directly (depending on how your documents got into salesforce to start with, they might have the extension separate to the name). Follow me on twitter to find out these things as they happen.

Friday, March 13, 2009

Following on from the filtered object/field list discussion, seems like showing all the fields and highlighting the matching ones seems like the best bet (but filtering the list of objects based on the object name, or the object having a field matching the filter), expect to find this in the next release of SoqlX.