Winter 13 developer orgs have replaced the “remote access” API feature set with a pilot program of Connected apps. Essentially Connected Apps are Remote Access v2.0 records, and provide a nicer interface with tighter and finer grained security controls via oAuth scopes.

Unfortunately, Connected Apps really is a pilot program; the documentation and interface is at best insufficient and at times woefully inadequate. Case in point: Connected Apps can be “published” and the Developer hands-on workshop workbooks from #DF12, as well as the Salesforce Touch Platform book (see page 40ish) as well as the official Connected Apps pdf imply that you must publish the Connected App. However, simply creating a Connected App record does not enable you to publish It. Indeed, after hours of research, a Stack Exchange question and a #askforce twitter plea, I stumbled upon the answer accidentally while attending todays (10/31/12) #forcewebinar on Canvas Apps. As it turns out the key to publishing connected apps in Winter13 Dev orgs is defining a namespace. Once you’ve Namespaced your org, you’ll see the publish button for Connected apps.

To namespace your development org click:

  • Setup
  • Create
  • Packages
  • Developer Options Edit
  • Namespace Prefix

Additionally, If you only need oAuth tokens/keys setup to replicate the existing “Remote Access” capabilities of Production orgs, You do not need to publish your connected app simply creating it is enough to establish oAuth connections.

Today I’m happy to announce Dobedobedo, a Ruby client gem for the do.com api. While the do.com api is not yet generally available interested parties can visit http://developer.do.com and request api oAuth keys. Once oAuth keys have been acquired use of the gem is fairly straightforward. (see below!)

The gem can be found in the usual places and the source is up at github. 

Edit: Less than a week in the wild and there’s already almost 200 developer downloads of the gem according to Rubygems.org

Usage:

Key features:

  • Objects are reflective of API results. Future field changes to the API are automatically accounted for.
  • Full CRUD to Projects
  • Full CRUD to Tasks
  • Full CRUD to Notes
  • Full CRUD to Comments
  • Full CRUD to Projects
  • Read access to Alerts
  • Read access to Workspaces
  • Read access to User
  • macRuby compatibility

Todo: i.e. Notable issues and limitations:

  • Nothing requiring the use of Client-Credential Grant type / Provisioning Scope is functional. Primarily this means you cannot create new workspaces, invite someone to a workspace, or Create a new user
  • Put/Update calls to Task resource are not fully reflective as full reflection of the object back to Do.com currently closes the task automatically.

The Name:

Awhile back, when I was first learning Ruby I came across a bit of code that I was amazed and confused by: Sinatra. As I have learned and become more experienced with Ruby I keep going back to the source of Sinatra to read and learn even more. Sinatra is a great framework and it’s original author Adam Wiggins —who appears to update his blog less than I do— have taught me much over the years. Dobedobedo is an attempted shout-out to Adam and his Sinatra framework while still maintaining a clear do.com reference.

Recently work has had me playing with Salesforce’s custom web services api. Web services are a powerful, and relatively under-used feature of salesforce that allows you to write your own soap(and now Rest) api methods. These are really handy when you need to, for instance, fetch all the accounts, cases, assets, opportunities etc. associated with a single contact. As powerful as they are, they are not without their own quirks (after all, this is Salesforce…)

The normal Salesforce soap api can accept as parameters either the standard, 15 digit, case sensitive GUID, or the 18 digit case insensitive API GUID. Unfortunately custom web servers are not so forgiving throwing apex errors when you pass in a 15 digit GUID. Our Ruby/Rails application needs to interact with this custom web service so I set out to understand how to calculate an 18 digit GUID from the 15 digit guid and implement the algorithm in Ruby. A quick google search shows the algorithm is already very well documented all over the web so I’m going to skip straight to the ruby implementation.

def convert_guid(short_guid)
    chunks = short_guid.chars.to_a
    char_map = %w{A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5}
    extension = []
    chunks.each_slice(5) { |x| y = x.reverse.map {|c| (c.match /[A-Z]/) ? 1 : 0 }.join("").to_i(2) ; extension << y}
    short_guid + (extension.map {|e| char_map.at(e)}).join("").to_s
end

And now, the walk through:

  • Standard ruby definition for a method. This is not the line of code you’re looking for.
  • We need to convert our 15 character string to an array of characters, so we’ll do that by casting the string to an array of characters
  • The algorithm depends on doing a map lookup, so we need to define the map of characters we can possibly use to add to our guid.
  • Lets fire up an array to hold the characters we’re going to append to the 15digit guid.
  • Ok here’s the meat. Take our chunks array, and for each group of 5 digits execute the following block of code:
  • We calculate Y by reversing the 5 digits of this current chunk, (eg. 12345 becomes 54321) and execute the following block of code on each digit:
  • if the current digit is a regex match for a capital A-Z, replace it with a 1, otherwise replace the character with a 0.
  • Join the 5 1′s and 0′s we just calculated back into a single string using join.
  • Cast that 5 digit binary string to a binary integer.
  • Add the binary integer to the extension array we created in line 4.
  • Take the original short_guid, and add to it the results of the lookup map function. If the the number in 5.2 were, for instance, 5 we convert that 5, to the character “F” in the map (arrays, start with 0 remember?).
  • Finally, we force a cast to string and return!

Viola! an 18 digit, case insensitive Salesforce GUID suited for use as input parameters to your custom web services.

Today was the October meeting of the RDU SFDC (developers) user group. Amber talked about permission sets (Especially useful to ISVs!) and our local salesforce developer evangelist showed off workbench. I had the honor of presenting a bit on writing and testing restful web callouts from Salesforce.com.

Web callouts are extremely useful for a number of reasons. Basically they allow you to interact with third party data sources from within the context of a salesforce trigger or class. This allows, for instance, an incoming web-to-lead form’s information to be validated and to set into motion a number of other time-consuming processes that ultimately allows our sales reps to have better data in less time to help close the deal. Attached to this post you’ll find and below you’ll find the actual code of a Salesforce Apex class, and test class illustrating how to write a testable web callout.

TL;DR

Technically, there are only five lines of code needed to make an HTTP callout from salesforce. The only needed lines are object creation for the http obj, the request obj, and the response obj; and the actual execution of the request. However using just these five lines results in code that is unable to be unit tested!
Instead, the five required lines of a web callout must be broken into a series of small, atomic methods. These methods, rather than the actual callout itself, are what must be tested.

The code:

public with sharing class DemoWebCallout {
    public class applicationException extends Exception {}
    Public static HttpRequest buildRequest(Lead l){
        HttpRequest request = new HttpRequest();
        String url = 'http://www.pinguinshow.com/';
        request.setEndpoint(url);
        request.setMethod('GET');
        return request;
    }

    public static HttpResponse makeRequest(Http h, HttpRequest request){
        HttpResponse response = h.send(request);
        return response;
    }  

    public void handleResponse(HttpResponse response){
        // For the purpose of this contrived example, we'll not do anything with the response.
        // If this were not a contrived example, you might see references to:
        // handling xml and other pointy markups languages
        // handling JSON -- if you're on Winter 12. More on that later.
    }

    @future(callout=true)
    Public static void makeWebCallout(Id id) {
        if(id == null) return;
        Lead[] l = [Select l.id From Lead l where l.id = :id limit 1];
        if(!l.isEmpty() || test.isRunningTest()) {
        Http h = new Http(); //Create a new http object
        try {
            HttpRequest request = buildRequest(l[0]); // during a test with a bad id, this will throw an exception
            HttpResponse response = makeRequest(h, request);
        } catch(Exception e){
            System.debug('Failed to execute callout! NO DONUT FOR YOU!! ' + l);
        }
      }     
    }
}

And the tests look like:

@isTest
private class TestDemoWebCallout {

    static testMethod void testRestfulCallout() {
        Lead l = new Lead();
        l.Status = 'Open';
        l.LastName = 'Owen';
        l.FirstName = 'Bob';
        l.Street = '1234 Sesame Street';
        l.City = 'Houston';
        l.Company = 'Test McTesterson and Co.';
        l.State = 'Tx';
        l.PostalCode = '27384';

        insert l;   

        Test.startTest();
        DemoWebCallout AwesomeDemo = new DemoWebCallout();
        HttpRequest testRequest = DemoWebCallout.buildRequest(l);
        System.assertEquals('GET', testRequest.getMethod());
        System.assertEquals('http://www.pinguinshow.com/', testRequest.getEndpoint());
        // working call
        DemoWebCallout.makeWebCallout(l.id);
    //failing call
    DemoWebCallout.makeWebCallout('00QC000000qnwbGMAQ'); //this id should not exist.
    Test.stopTest();
}