Monday, April 02, 2018

Add Fault Connector in Salesforce Flow Autolaunch


Fault Connector is very useful because now we able to handle the error. We can trace who perform the transaction and what record that cause the error.

The connector is indicated with FAULT like image below.


In some occasion you might face into issue that Fault Connector is not working like below :




Here is the hack. We need to add another element after it because for unknown reason Fault Connector will not appear in the last element. So we need to create another element temporarily like below.

Tips : Use Copy and Paste button to copy from existing element so you don't have create dummy element from start.


Now we can add Fault Connector to the element that we want to.As you can see in the image below, when we drag the connector 'Fault' label appear. Now we can delete the dummy element.

That's it. Now it should works.

More about Flow can be refer to here .

Have a nice day.

Monday, March 05, 2018

Process Builder Bug to Take Note

Well, it is annoying when the process builder does not work for reason that not mentioned in documentation properly.

I decided to compile the list of nonsense difficulties that I found whilst using Process Builder

Using 15 ID in Process Builder(Big No)

I use 15 char ID in Process Builder criterita that I retrieve from Salesforce URL to fire Email Alert.The email does not get fire although Deliverabilities and other setting are correct.

To confirm, I run SOQL with 15 char ID and it returns value. So it leave me clueless why my Process Builder does not work.Oh, hello it just Process Builder but even simple Process Builder does not work!!

It took me some time until I randomly put 18 char ID and it wallaahhh it works.Seriously, is there any documentation say Process Builder only receive 18 char ID ?

Let me know if you find it.For this time being , I will avoid using ID field in Process Builder.


Action Name need to be short ...how SHORT?

You must specify a name for the action cal l.
To avoid this error , please choose Email Alert that popup from the field when you put the name.

You see this error although you already specify  action name for  email alert and wonder ... hey I already put the name!!

This is misleading error because actually it require you to put Action Name short.How short? You need to test it by yourselves.

Anyway, if you desperately need a longer name, put short name.Save then rename it Save.

Close the Process Builder and Open again ...meh

When I renaming Email Alert in separate tab, then add it in Process Builder in separate tab it will throw something
"Could not find Email Alert ..."

Although the Email Alert Name autopopulate in the field, ust close the Process Builder and try again.

It works.Well, seem restart always a solution.

Deploy active Process Builder -- it will not automatically active

Process Builder will not guaranteed to be active automatically when deployed.We need to manually activate Process Builder after we deploy it.


TO BE CONT...
Share with me if you got issue with process builder?

Thursday, February 15, 2018

Apex Webservice (You Call me)

I already write about Apex Call Out when we want to connect with external services either in REST or SOAP here .

If Apex Call Out I use 'I call you' metaphor to represent Salesforce need to contact external service, therefore we need external service info such as - url and set end point url in Remote Site Setting.

While Apex Web Service I use 'You call me' which mean we need to expose our Apex class either as SOAP or REST for external service to connect.

You call me! In order for them to you,
you need to give your phone number

Expose a class as REST Service

  1. Define class with global access modifier .
  2. Use @RestResource annotation at class level to enable it serve as webservice
    • Example : @RestResource(urlMapping='/Case/*')
  3. Define method with global static .
  4. Add an annotation to associate with Http method. Bear in mind on one method is allowed per class. It means there should be only one GET method per class.
  5. Endpoint URL that we need to share to external service will look like this: https://yourInstance.salesforce.com/services/apexrest/Case/*
AnnotationActionDetails
@HttpGetReadReads or retrieves records.
@HttpPostCreateCreates records.
@HttpDeleteDeleteDeletes records.
@HttpPutUpsertTypically used to update existing records or create records.
@HttpPatchUpdateTypically used to update fields in existing records.
Example
@RestResource(urlMapping='Cases/*')
global with sharing class MyRestResource {
    @HttpGet
    global static Case getRecord() {
        // Add your code
    }
}


Expose a class as SOAP Service

  1. Define class with global access modifier .
  2. Define your method with 'webservice static'
  3. You need to generate WSDL and send it to the external developer so they can write integration to connect wit us.
Example
global class Project {
  
   webservice String area; 
   webservice String region; 
   
   //Define an object in apex that is exposed in apex web service
   global class Plan {
      webservice String name;
      webservice Integer planNumber;
      webservice Date planningPeriod;
      webservice Id planId;
   }

   webservice static Plan createProjectPlan(Plan vPlan) {
       
       //A plan maps to the Project__c object in salesforce.com. 
       //So need to map the Plan class object to Project__c standard object
       Project__c proj = new Project__c();
       proj.Name = vPlan.name;
       proj.AccountNumber = String.valueOf(vPlan.planNumber);
       insert proj;
       
       vPlan.planId=proj.Id;
       return vPlan;
  }

Conclusion

This entry explains on custom Apex code for REST and SOAP API and it not the only way for external applications to connect with Salesforce. There a few ways to connect such as using Salesforce's REST and SOAP APIs. It has different strengths to fulfill  business requirement.

References :
Awesome Trailhead Apex Web Services
Still standing : Apex Web Services and Callouts

Friday, February 09, 2018

Apex Call out (I Call You)

Although I have done integration to external service using call out in my previous experience still I have hiccup to grab the concept.So I thought that I should sit down and learn the concept and of course  the best way is  through Salesforce Trailhead  =) .

When it comes to integrate Salesforce with external service we can categorize it into two types :
  1. Apex Call Out
  2. Apex Web Service (I wrote here)
Both can use SOAP and REST protocol which it is advisable to use REST. In case you want to know which one better , please check out this article.

I personally have come out easy way to understand the concept for both category.In my concept, we can assume SOAP and REST is different provider that use different format.

I use 'I Call You' for Apex Call Out and 'You Call Me' for Apex Webservices.

I Call You (Apex Call Out)

well, can you see..my drawing is #awesome =)

I mean Salesforce , You mean external service.
In order to enable this we need to know who we call so we can call them.
They need to let us know how to call them.

You Call Me (Apex Web Service)
The drawing become bigger for unknown reason
You mean External Service, me mean Salesforce.
In order to enable this we need to expose and give information to external service how to call us.

Apex Call Out

Apex Call Out is when we want to use external service , either we want to send or receive data.
I notice that in Trailhead it use webservice call out to define call out that use SOAP and HTTP Call out to define call out that use REST with JSON.
  • Web service callouts to SOAP web services use XML, and typically require a WSDL document for code generation.
  • HTTP callouts to services typically use REST with JSON.Read more...

Regardless what type we still need to define their number(Endpoint Address) in Remote Setting so we can call them.

Apex REST Callouts

Some common HTTP methods
HTTP MethodDescription
GETRetrieve data identified by a URL.
POSTCreate a resource or post data to the server.
DELETEDelete a resource identified by a URL.
PUTCreate or replace the resource sent in the request body.

Basic Steps to implement Apex REST Callouts
  1. Define Endpoint address in Remote Setting.Note the setting below will authorize all subfolders for the endpoint, for example in your code later it will enable you to call https://th-apex-http-callout.herokuapp.com/subfolder1 or https://th-apex-http-callout.herokuapp.com/subfolder2
  2. Make sure external service give you information how to access their data.They should provide you correct URL to retrieve animal data and what parameter they need in order to return you the data. For example, they provide you this url https://th-apex-http-callout.herokuapp.com/animals/'+id which indicate that you can append Id at the back in order for it to return animal data.Without information, you not able to call them.Usually they will provide you documentation on how you able to call their method.
  3. You can create class to get the data or you can run it using Apex Execute Anonymous in Developer Console.
    public class AnimalLocator {
    public class cls_animal {
            public Integer id;  
            public String name; 
            public String eats; 
            public String says; 
        }    
    
    public class JSONOutput{
        public cls_animal animal;
    
     }
    public static String getAnimalNameById(Integer id){
      String stranimal='';
    
     Http http = new Http();
            HttpRequest request = new HttpRequest();
            request.setEndpoint('https://th-apex-http-callout.herokuapp.com/animals/'+id);
            request.setMethod('GET');
            HttpResponse response = http.send(request);
            // If the request is successful, parse the JSON response.
            if (response.getStatusCode() == 200) {
              // Deserializes the JSON string into collections of primitive data types.
              jsonOutput results = (jsonOutput) JSON.deserialize(response.getBody(), jsonOutput.class);
               strAnimal=results.animal.name;
               System.debug(stranimal);
             }
           
    return stranimal;
    }
    
    }
    


Apex SOAP Callouts

In this case, we need to request external party to provide us WSDL so we can generate class from it.
In trailhead , the external service provide calculator.xml like below.

<?xml version='1.0' encoding='UTF-8'?><wsdl:definitions xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://calculator.services/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:ns1="http://schemas.xmlsoap.org/soap/http" name="CalculatorImplService" targetNamespace="http://calculator.services/">
  <wsdl:types>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://calculator.services/" elementFormDefault="unqualified" targetNamespace="http://calculator.services/" version="1.0">

  <xs:element name="doAdd" type="tns:doAdd"/>

  <xs:element name="doAddResponse" type="tns:doAddResponse"/>

  <xs:element name="doDivide" type="tns:doDivide"/>

  <xs:element name="doDivideResponse" type="tns:doDivideResponse"/>

  <xs:element name="doMultiply" type="tns:doMultiply"/>

  <xs:element name="doMultiplyResponse" type="tns:doMultiplyResponse"/>

  <xs:element name="doSubtract" type="tns:doSubtract"/>

  <xs:element name="doSubtractResponse" type="tns:doSubtractResponse"/>

  <xs:complexType name="doDivide">
    <xs:sequence>
      <xs:element minOccurs="0" name="arg0" type="xs:double"/>
      <xs:element minOccurs="0" name="arg1" type="xs:double"/>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="doDivideResponse">
    <xs:sequence>
      <xs:element minOccurs="0" name="return" type="xs:double"/>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="doSubtract">
    <xs:sequence>
      <xs:element minOccurs="0" name="arg0" type="xs:double"/>
      <xs:element minOccurs="0" name="arg1" type="xs:double"/>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="doSubtractResponse">
    <xs:sequence>
      <xs:element minOccurs="0" name="return" type="xs:double"/>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="doMultiply">
    <xs:sequence>
      <xs:element minOccurs="0" name="arg0" type="xs:double"/>
      <xs:element minOccurs="0" name="arg1" type="xs:double"/>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="doMultiplyResponse">
    <xs:sequence>
      <xs:element minOccurs="0" name="return" type="xs:double"/>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="doAdd">
    <xs:sequence>
      <xs:element minOccurs="0" name="arg0" type="xs:double"/>
      <xs:element minOccurs="0" name="arg1" type="xs:double"/>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="doAddResponse">
    <xs:sequence>
      <xs:element minOccurs="0" name="return" type="xs:double"/>
    </xs:sequence>
  </xs:complexType>

</xs:schema>
  </wsdl:types>
  <wsdl:message name="doSubtractResponse">
    <wsdl:part element="tns:doSubtractResponse" name="parameters">
    </wsdl:part>
  </wsdl:message>
  <wsdl:message name="doMultiplyResponse">
    <wsdl:part element="tns:doMultiplyResponse" name="parameters">
    </wsdl:part>
  </wsdl:message>
  <wsdl:message name="doAddResponse">
    <wsdl:part element="tns:doAddResponse" name="parameters">
    </wsdl:part>
  </wsdl:message>
  <wsdl:message name="doDivide">
    <wsdl:part element="tns:doDivide" name="parameters">
    </wsdl:part>
  </wsdl:message>
  <wsdl:message name="doSubtract">
    <wsdl:part element="tns:doSubtract" name="parameters">
    </wsdl:part>
  </wsdl:message>
  <wsdl:message name="doDivideResponse">
    <wsdl:part element="tns:doDivideResponse" name="parameters">
    </wsdl:part>
  </wsdl:message>
  <wsdl:message name="doMultiply">
    <wsdl:part element="tns:doMultiply" name="parameters">
    </wsdl:part>
  </wsdl:message>
  <wsdl:message name="doAdd">
    <wsdl:part element="tns:doAdd" name="parameters">
    </wsdl:part>
  </wsdl:message>
  <wsdl:portType name="Calculator">
    <wsdl:operation name="doDivide">
      <wsdl:input message="tns:doDivide" name="doDivide">
    </wsdl:input>
      <wsdl:output message="tns:doDivideResponse" name="doDivideResponse">
    </wsdl:output>
    </wsdl:operation>
    <wsdl:operation name="doSubtract">
      <wsdl:input message="tns:doSubtract" name="doSubtract">
    </wsdl:input>
      <wsdl:output message="tns:doSubtractResponse" name="doSubtractResponse">
    </wsdl:output>
    </wsdl:operation>
    <wsdl:operation name="doMultiply">
      <wsdl:input message="tns:doMultiply" name="doMultiply">
    </wsdl:input>
      <wsdl:output message="tns:doMultiplyResponse" name="doMultiplyResponse">
    </wsdl:output>
    </wsdl:operation>
    <wsdl:operation name="doAdd">
      <wsdl:input message="tns:doAdd" name="doAdd">
    </wsdl:input>
      <wsdl:output message="tns:doAddResponse" name="doAddResponse">
    </wsdl:output>
    </wsdl:operation>
  </wsdl:portType>
  <wsdl:binding name="CalculatorImplServiceSoapBinding" type="tns:Calculator">
    <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
    <wsdl:operation name="doDivide">
      <soap:operation soapAction="" style="document"/>
      <wsdl:input name="doDivide">
        <soap:body use="literal"/>
      </wsdl:input>
      <wsdl:output name="doDivideResponse">
        <soap:body use="literal"/>
      </wsdl:output>
    </wsdl:operation>
    <wsdl:operation name="doSubtract">
      <soap:operation soapAction="" style="document"/>
      <wsdl:input name="doSubtract">
        <soap:body use="literal"/>
      </wsdl:input>
      <wsdl:output name="doSubtractResponse">
        <soap:body use="literal"/>
      </wsdl:output>
    </wsdl:operation>
    <wsdl:operation name="doMultiply">
      <soap:operation soapAction="" style="document"/>
      <wsdl:input name="doMultiply">
        <soap:body use="literal"/>
      </wsdl:input>
      <wsdl:output name="doMultiplyResponse">
        <soap:body use="literal"/>
      </wsdl:output>
    </wsdl:operation>
    <wsdl:operation name="doAdd">
      <soap:operation soapAction="" style="document"/>
      <wsdl:input name="doAdd">
        <soap:body use="literal"/>
      </wsdl:input>
      <wsdl:output name="doAddResponse">
        <soap:body use="literal"/>
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>
  <wsdl:service name="CalculatorImplService">
    <wsdl:port binding="tns:CalculatorImplServiceSoapBinding" name="CalculatorImplPort">
      <soap:address location="https://th-apex-soap-service.herokuapp.com/service/calculator"/>
    </wsdl:port>
  </wsdl:service>
</wsdl:definitions>

Basic Steps to implement Apex SOAP Callouts
  1. Define Endpoint address in Remote Setting.
  2. Generate class from WSDL file that you retrieve from external service.Go to Setup > Develop > Apex Classes and hit button Generate from WSDL and wallahhh... the class is ready for you to use.Use the class as usual.

I will write about Apex Web Services later.

Ultimate reference is Apex Integration Services

Monday, January 22, 2018

Compare two Salesforce sandbox

As developer I always found it handy to do this by downloading file/type that I wanted to compare using Force.com IDE(Eclipse) and then use Winmerge tool to compare.

 I wonder if there any other way to do this so I figured out that some peoples are using Ant and some are using  Salesforce org compare.It is one of feature that reside in  Salesforce Toolkit which contains other features that I will play with it later.
Salesforce Toolkit
You start by choosing which org you want to compare

You need provide username and password for both organization.

It will take a while depending how big your org is.
The good thing is you can wait or you can just close the window.
It will send the result to your email.

It provide three color codes to indicate if there new file, different or match file.

Orange mean there difference, red mean the file only exist in one sandbox.

You also can download the file.

It's cool and user friendly tool.Compare to Force.com IDE and ANT, this tool require no configuration at all.

Also you can find an idea has been raised regarding this.

Sunday, January 07, 2018

Understand Connected Apps in Salesforce

What is connected apps?

A "Connected App" is an application that can connect to salesforce.com over Identity and Data APIs. Connected Apps use the standard OAuth 2.0 protocol to authenticate, provide Single Sign-On, and acquire access tokens for use with Salesforce APIs. In addition to the standard OAuth capabilities supported by the existing Remote Appsfeature (which Connected Apps is designed to replace), Connected Apps add additional levels of control, allowing administrators explicit control over who can use the application, and various security policies to be enforced by the application.Read more ...

When we develop an external application that needs to authenticate with Salesforce, we need to define it as a new connected app within the Salesforce organization that informs Salesforce of this new authentication entry point.Read more ...
It is an external application that connect to salesforce.In order to enable the authentication we need to definit it as Connected Apps in Salesforce.
Some example of Connected Apps are :

  • Ant Migration Tool
  • Chatter Desktop
  • Dataloader
  • Forcec.com IDE
  • Salesforce for Outlook
  • Workbench

How to create and define Connected Apps ?

First time I am little bit confused with the interface because there no Create or New button to create Connected Apps when you go via Setup > Manage Apps.

To define Connected Apps, we need to Setup > Apps and scroll to the bottom until we Connected Apps.

Click New button to define new Connected Apps.Fill in required field such Connect App Name , API Name and Contact Email .

Check Enable OAuth will expand API(Enable OAuth Setting) which you require to fill in Callback URL and Selected OAuth Scopes


  1. Callback URL basically is endpoint URL that Salesforce calls back to your application during OAuth. It’s the OAuth redirect URI.
    If you enter multiple callback URLs, at run time Salesforce matches the callback URL value specified by the app with one of the values in Callback URL. It must match one of the values to pass validation.
    Separate multiple callback URLs with line breaks.The callback URL field has a limit of 2000 characters, cumulatively. If you enter several URLs and they exceed this limit, create another connected app to manage more callback URLs.
  2. Scopes refer to permissions the user gives to the connected app while it’s running. The OAuth token name is in parentheses.

Once you save, it will come out something like this.


Now if we go to Setup > Manage Apps > Connected Apps , we able to see the Connected Apps that we just created.



One of example of how external can use the Customer Key and Customer Secret in Java program


static final String USERNAME     = "YOUR DEVORG USERNAME";
    static final String PASSWORD     = "YOUR DEVORG PASSWORD + SECURITY TOKEN";
    static final String LOGINURL     = "https://login.salesforce.com";
    static final String GRANTSERVICE = "/services/oauth2/token?grant_type=password";
    static final String CLIENTID     = "YOUR OAUTH CONSUMER KEY";
    static final String CLIENTSECRET = "YOUR OAUTH CONSUMER SECRET";

    public static void main(String[] args) {

        DefaultHttpClient httpclient = new DefaultHttpClient();

        // Assemble the login request URL
        String loginURL = LOGINURL + 
                          GRANTSERVICE + 
                          "&client_id=" + CLIENTID + 
                          "&client_secret=" + CLIENTSECRET +
                          "&username=" + USERNAME +
                          "&password=" + PASSWORD;

        // Login requests must be POSTs
        HttpPost httpPost = new HttpPost(loginURL);
        HttpResponse response = null;

        try {
            // Execute the login POST request
            response = httpclient.execute(httpPost);
        } catch (ClientProtocolException cpException) {
            // Handle protocol exception
        } catch (IOException ioException) {
            // Handle system IO exception
        }

//other code goes here

Refer here to view full code example.

Also other thing to note during refresh Sandbox, although Connected Apps is copied into Sandbox but consumer key and customer key will be different.So you might want to check if external apps not able to connect to Sandbox during in testing environment.

Some links that might be useful to look into


Thanks for reading.