Monday, 28 April 2014

How to access Salesforce web services

Recently I had to create a web service in Salesforce and expose data to external application.
The first part with creating of web service on Salesforce is quite easy because SF does a good job of converting APEX classes into a web services and this information is explained very well in original SF documentaion. So, it is required to create an APEX class with "webService" keywords and download WSDL file wich can be used for proxy generation.
Here is an example: http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_web_services_methods.htm

The tricky part of it is that you need to call this service from, say, C#, and this information is spread among different posts, forum topics etc.

Here is the combined and simplified C# example:


using System;
using System.IO;
using System.Net;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Text;

namespace WSTest
{
    [DataContract]
    internal class AuthToken
    {
        [DataMember]
        internal string id;
        [DataMember]
        internal string issued_at;
        [DataMember]
        internal string instance_url;
        [DataMember]
        internal string signature;
        [DataMember]
        internal string access_token;
    }

    class Program
    {
        private static AuthToken SalesforceAutenticate(string userName, string password)
        {
            // Sandbox URI, for production environment it should be "https://login.salesforce.com/services/oauth2/token"
            const string URI = "https://test.salesforce.com/services/oauth2/token";

            // how to obtained security token: https://success.salesforce.com/answers?id=90630000000glADAAY
            const string securityToken = "1234567890";

            // how to obtain consumer key + secret: http://feedback.uservoice.com/knowledgebase/articles/235661-get-your-key-and-secret-from-salesforce
            const string consumerKey = "XXXXXXXXXXX.YYYYYYYYYYYYYYYYYYYYYYY";
            const string consumerSecret = "0987654321";

            WebRequest req = WebRequest.Create(URI);
            req.Proxy = GetProxy();

            req.ContentType = "application/x-www-form-urlencoded";
            req.Method = "POST";

            String parameters = String.Format("grant_type=password&client_id={0}&client_secret={1}&username={2}&password={3}{4}",
                    consumerKey, consumerSecret, userName, password, securityToken);

            byte[] bytes = Encoding.ASCII.GetBytes(parameters);
            req.ContentLength = bytes.Length;
            Stream os = req.GetRequestStream();
            os.Write(bytes, 0, bytes.Length);
            os.Close();

            WebResponse resp = req.GetResponse();
            if (resp == null)
                return null;

            // parse JSON response
            DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(AuthToken));
            AuthToken token = (AuthToken)ser.ReadObject(resp.GetResponseStream());

            return token;
        }

        static void Main(string[] args)
        {
            var authToken = SalesforceAutenticate("my@email.dev", "mypassword");

            MyWebServiceService client = new MyWebServiceService();
            client.Proxy = GetProxy();
            client.SessionHeaderValue = new SessionHeader();
            client.SessionHeaderValue.sessionId = authToken.access_token;

            Console.WriteLine(client.SampleMethod("123456"));
        }

        private static IWebProxy GetProxy()
        {
            IWebProxy proxy = new WebProxy("server:port");
            proxy.Credentials = new NetworkCredential("ADname", "ADpassword");
            return proxy;
        }
    }
}

Wednesday, 23 April 2014

Auto-updatable chatter feed in Salesforce

Let’s consider the process of implementation of auto-updatable chatter feed. Even if it looks quite easy this task has two aspects:
1) Auto-updatable controls
2) Creation of custom controllers

In general case auto-refresh of Salesforce visual element can be implemented using this code snippet:

<apex:actionPoller action="{!updateMethod}" reRender="controlToUpdate" interval="15"/>

where:
“updateMethod” is a method of page controller
“controlToUpdate” - id of a component to update
“15” - update interval in seconds

Unfortunately, only custom controllers can have an update method, all standard controllers cannot be extended using ordinary inheritance. So this task may look quite tricky.

Let’s have a look on an example of Account controller. It can be extended using this approach:

public with sharing class Account_Controller {

   public Account_Controller (ApexPages.StandardController stdController) {
       
this.account = (Account)stdController.getRecord();
   
}

   
public Account account { get; private set; }

   
public PageReference updatePage() {
       
return null;
   
}
}

So, it can aggregate the standard controller and extend it with custom functionality.

And in this case the page for the view may look like this:

<apex:page standardController="Account" extensions="Account_Controller">
   
<apex:form >
      
<apex:actionPoller action="{!updatePage}" reRender="chatter" interval="15"/>
   
</apex:form>
   
<chatter:feed id="chatter" entityId="{!account.id}" showpublisher="True"></chatter:feed>
</apex:page>

And now we can see that two tasks are solved: standard controller is extended through adaptor pattern and the view can incorporate an auto-updatable control.