A blog dedicated to Salesforce Ohana

Continuation in Salesforce - Asynchronous Callout option for long running requests

While implementing features, we need to write code to call external web services to fetch or update information. But calling external web service doesn't mean we should wait for the response from the web service. That is a bad design. We should always write code in such a way so that we can call external web service and still continue to do other work and when the response is available from the web service, we will update the page with response. This way of calling web service is known as Asynchronous callout.

Since in Salesforce, we are living in a multi-tenant architecture, so calling external services synchronously can create issues if the response is taking too much of time to come due to network latency or complex calculation or long running requests. There can be n number of reasons why the response is taking longer time. To make sure System resources are available to all customers, Salesforce introduces limitation on how much synchronous callout you can do from a single organization. Limit is each org can make a maximum of 10 synchronous requests running for more than 5 seconds. When the limit is reached, any subsequent request will fail until and unless an existing request completes successfully.

Apex continuation is an architectural design which will allow to call long running external web services in a scalable fashion without blocking any server threads and also avoiding Apex concurrency limit. With Apex continuation, you can make asynchronous external web service callout and then continue working on other activities. When the response is available, callback method will take care of that and take actions like - updating some values in object, rendering a section of the visual force page to display the result.

Below code snippet will demonstrate how you can use Continuation object for making Asynchronous callout.

I will be using two external web services for this demo. So you need to add them in your developer org's Remote Site settings.
Visualforce Page: click here

Apex Controller: click here

Here is the demo - click here

You can learn more about Apex continuation below -
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_class_System_Continuation.htm
Share:

Query Plan Tool from Salesforce - A Hidden Gem

Query Plan in the developer console can help to speed up SOQL queries done over large volumes of data. This is such a powerful tool when dealing with bad performance. Developer can use this tool to optimize and speed up SOQL queries.

We can enable Query Plan in the Developer Console by -


Before we go into details, it's better to understand how Salesforce uses indexes while running the SOQL. As we all know it is always good to go for selective query instead of full table scan. But even with selective query, when we are using different filter criteria, it is not always the best SOQL query we are writing. The reason behind is that just writing where clause in the query does not guarantee that the filter is selective. So it is very important to understand which are the fields are good to be used in filter. Let's understand that first in the below section -
  • All we need to use is the indexes in the filter.
  • If we are using filter on standard fields, then we are using index if -
    • it is primary key (Id, Name, OwnerId)
    • it is a foreign key (CreatedById, LastModifiedById, Lookup, Master-Detail)
    • it is an audit field (CreatedDate, SystemModstamp).
  • If we are using filter on custom fields, then we are using index if that field is marked as Unique or External Id.
Without indexed filter, the query will not be considered for optimization. 

So does that mean if I use filter which is indexed, I am safe and my query is optimized? Answer is Yes and No.

Why Yes, because definitely using indexed field in filter clause will make the query optimized, but there is a catch which I am going to explain now -

When SOQL query is using indexed field, Salesforce will determine how many records it would return. For example -

  • For a Standard index, the threshold is 30% of the first million targeted record and 15% of all records after that first million. In addition to that, selective threshold for a standard index maxes out at 1 million (which is only possible if the total number of records is 5.6 million).
  • For a Custom index, the threshold is 10% of the first million targeted record and 55% of all records after that first million. In addition to that, selective threshold for a standard index maxes out at 333,333 (which is only possible if the total number of records is 5.6 million).
So if the filter exceeds the threshold, then query will not be considered for optimization.

Query Plan will provide us the below information about the SOQL query -

Now with the above information, let's execute few queries and analyze the result -

Query 1: Select count() from Contact
Result: 

Here I am not using any index field, Field column is blank, Operation Type is TableScan and cost is > 1. Anytime the cost of a SOQL query is greater than 1, it means it is not considered for Optimization.

Query 2: Select count() from Contact Where External_Id__c = '0xP1500100KXFU4512'
Result: 

Here I am using custom index field (External_ID__c) which is there in the Field column, Operation Type is Index and cost is < 1. Since we have one cost which is less than 1, that will be used to optimized the query.

Query 3: Select count() from Contact Where External_Id__c != '0xP1500100KXFU4512'
Result: 

Here I am using custom index field (External_ID__c) but still the field column in blank and Operation Type is TableScan and cost is > 1. So definitely this query is not optimized. But Why??
The reason is -
There are few unsupported operations which will make your query not good enough for optimization. They are as mentioned below -

Query 4: Select count() from Contact Where External_Id__c = '0xP1500100KXFU4512' and Contact_Type__c = 'Customer'
Result: 

Here I have used second indexed field(Contact_Type__c) in the query. In this scenario, Salesforce will select the plan with lowest cost.

Query 5: Select count() from Contact Where External_Id__c = '0xP1500100KXFU4512' And Client_Status__c = 'Active'
Result: 

Here I have used second non-indexed field(Client_Status__c) in the query. That is why only one indexed field in the result.

Query 6: Select count() from Contact Where External_Id__c = '0xP1500100KXFU4512' Or Client_Status__c = 'Active'
Result: 

Here I have used second non-indexed field(Client_Status__c) in the query with or condition.When using OR condition, all filters must be indexed and under the 10% threshold.

Query 7: Select count() from Contact Where Contact_Type__c = 'Customer'
Result: 

Here even though I have used indexed field(contact_type__c), but still the query is not optimized as you can see the lowest cost is also greater than 1. The reason is that here the finding variable 'Customer' is resulting more than 10% of the full table.

Query 8: Select count() from Contact Where Contact_Type__c = 'Advisor'
Result: 

Here I have changed the binding variable to 'Advisor' and resulting data count is less than 10% of the full table. That is why this query is optimized.

You can go through the below articles to go through more examples -





Share:

LastModifiedDate Vs SystemModStamp


In Salesforce, when we create or update a record, there are so many things happen in the background. In this post, I am going to share my knowledge regarding two important fields present in each Salesforce record. I will start with a basic explanation regarding these fields and then at the end, I will explain how these fields are going to impact your query performance.

Let's start with basic explanation -

LastModifiedDate:

This is a standard field present in each Salesforce record. This field will be updated with current timestamp when the record is created or edited by Salesforce user. This field also has a very unique feature i.e. this field can be imported with some previous date. Let's say you want to load data from your old legacy system, but you want to preserve the dates from your legacy system. In this situation, you can load the records from your legacy system into Salesforce by updating the LastModifiedDate field with the previous date.

SystemModStamp:

This is a read-only field. This field will be updated with current timestamp when the record is updated by the user. But the important difference is that this field will also be updated when the record is updated by Automated System Process. So in mathematical term -
LastModifiedDate <= SystemModStamp    This is possible.
LastModifiedDate > SystemModStamp      This is not possible.

How LastModifiedDate and SystemModStamp affect SOQL performance:

LastModifiedDate field is not indexed, but SystemModStamp field is indexed. So when SOQL query uses LastModifiedDate field in the where clause, Salesforce's Query Optimizer will internally use SystemModStamp to improve the performance. But when LastModifiedDate is used to determine the upper boundary of a date range, then Salesforce's Query Optimizer will not be able to use SystemModStamp. Confused???
Let's understand the concept with below examples -

Consider one account record - ABC Technologies
Record created by user on Jan 31st, 2018 LastModifiedDate: Jan 31st, 2018
SystemModStamp: Jan 31st, 2018
Record updated by Automated Process on Feb 2nd, 2018 LastModifiedDate: Jan 31st, 2018
SystemModStamp: Feb 2nd, 2018

Query: Select Id From Account Where LastModifiedDate > 2018-01-30T00:00:00Z
Can Salesforce's Query Optimizer replace LastModifiedDate with SystemModStamp? Answer is YES
Salesforce's Query Optimizer will change the query to -
Select Id From Account Where SystemModStamp > 2018-01-30T00:00:00Z to improve the performance and definitely we will get out ABC Technologies back from the SOQL.

Now consider another situation where the query is:
Select Id From Account Where LastModifiedDate < 2018-02-01T00:00:00Z.
Can Salesforce's Query Optimizer replace LastModifiedDate with SystemModStamp? Answer is NO
Why?
With original query (Select Id From Account Where LastModifiedDate < 2018-02-01T00:00:00Z) we are expecting ABC Technologies will come out, but if Salesforce's Query Optimizer replaces LastModifiedDate with SystemModStamp, then the query will become Select Id From Account Where SystemModStamp < 2018-02-01T00:00:00Z. So definitely with this query, we will not get our ABC Technologies back.

That is why Salesforce's Query Optimizer will not be able to use SystemModStamp instead of LastModifiedDate when LastModifiedDate is used to determine with the upper boundary of a date range, otherwise, the records in between these two dates(SystemModStamp and LastModifiedDate) will be missed from the query result.



Share:

Setup Service Cloud Lightning Snap-Ins with Omni Channel - Basic Steps




When it comes to CRM Customer Engagement, as per Gartner's Magic Quadrant for the CRM Customer Engagement Center, Salesforce is the in the "Leaders" section. Gartner estimates that 20% of Salesforce's new revenue came from Service Cloud in 2016 and it expects to exceed $2 billion in 2017. Reference: Gartner.

Service always tries to bring new features, innovations to market and the goal is always to increase customer satisfaction. In order to serve the customer better, Salesforce introduces a new feature called - Service Cloud Lightning Snap-In. Service Cloud Lightning Snap-ins are a fundamentally new way to deliver a service experience for today's connected customers. 

In this post, I will explain how to configure Lightning Snap-Ins with Omni Channel and receive chat request. So I know you guys are really excited to know this new feature. So without any further detail, let's get into the main topic. I am going to mention the steps below. If there is any pre-requisite, I will mention the same.

Step 1: Pre-Requisite: Live Agent and Omni Channel is enabled.
You need to make sure Live Agent and Omni Channel is enabled. There should be user present in your org with Live Agent checkbox checked. Omni Channel should be added to your console app.

Step 2: Create Queue for Live Chat Transcript

Step 3: Create Omni-Presence

Step 4: Create Live Chat Button

Step 5: Create Live Agent Deployment

Step 6: Create Force.com Site. 
You can refer Salesforce help link for creating Force.com Site. Link: https://help.salesforce.com/articleView?id=sites_overview.htm&type=5
Step 7: Enable Lightning in your org
Link: https://help.salesforce.com/articleView?id=lex_enable_turn_on.htm&type=5
Step 8: Add your website to CORS Whitelist
You should add the website domain to CORS Whitelist. This website is the one where you will include your snap-ins code. 
Link: https://help.salesforce.com/articleView?id=snapins_chat_cors_whitelist.htm&type=5
Step 9: Create Snap-Ins Deployment
In order to do this step, we need to move into Lightning Experience and then from setup, search for Snap-Ins. Click on "New Deployment". Give Deployment name and select the site you created @ step 6. Here is the screenshot -

Step 10: Configure Snap-ins Deployment
In this step, click on Start next to Live Agent Basic Settings. Select the Live Chat Button and Live Agent Deployment you created @ Step #4 & 5.

Step 11: Get the code and put it in HTML page

Step 12: Open the HTML page in your browser and you will see that Chat Button is available.

Step 13: Here is the animated video chat conversation from Lightning Snap-Ins

In my next post, I will explain the customization options available with Snap-Ins.

Reference:

Share:

Winter 18 - Automatically Styling of Existing Visualforce Pages in Lightning Experience

Salesforce Winter'18 release came with lots of surprises to all of us. Before Winter'18 release, one of the biggest pain to switch to Lightning was - How to migrate existing VisualForce pages? We all tried to use the standard VisualForce component in our VisualForce pages as a best practice till date. The reason was Salesforce's backward compatibility. We all knew that using standard VisualForce component is safe because even if Salesforce enhances those components, we don't need to change our VisualForce pages.
But with the introduction of Lightning, things changed. People all over the world started investing in changing their existing VisualForce pages into Lightning and it is a not a very straightforward task.

Salesforce realized the problem and in Winter'18 release came as a savior to all of us. With very minimum changes now, we can keep our existing VisualForce pages and it will still work in Lightning experience. This feature is still in beta mode as there are so many things to improve. But it is really a good starting point and good to know. I am quite sure Salesforce will support more and more components in coming releases. It is definitely a game changer.

In this post, I will explain with an example what you need to do in your existing VisualForce page to make it work in both Lightning and Classic.

I have written this below VisualForce page containing PageBlock, CommandButton, InputText, PageBlockTable.
VisualForce Page: AutomaticStylingPage


Apex Controller: AutomaticStylingPageController


Now when I am rendering the same page in Salesforce Classic and Lightning, below is how it looks like  -
Salesforce Classic:








Salesforce Lightning:










To make the same VisualForce page work in both Salesforce Classic and Salesforce Lightning, the only change we need to do in our existing VisualForce page is add lightningStylesheets="true"

It is very simple and really a big win for Lightning Migration activity.

Note -

  • This feature is in Beta as of Winter'18 release.
  • This will only work with apex tags. So if your VisualForce page is having custom styling, this is not going to work now. 


Share:

Salesforce Service Cloud - Contact Center Reports

As a call center manager, it is very important to monitor team's case performances targets, train new support agents, analyze team's open case performance and etc. There are multiple matrices which a call center manager normally monitor to improve contact center's performance.

Call center manager can use Salesforce reports to monitor critical support metrics such as -
  • Total open cases by agents
  • Total cases created by agents and status
  • Total cases created by agents and products
  • Total average age by agent
  • Total closed cases by agent
Let's start with few important reports here -

Agent Open Case Load by Origin/Type:
This report will help call center manager to determine his/her team's bandwidth/workload. The report will be grouped based on Agent and Case Origin/Type(based on your business operation). From here call center manager can easily get real time view of his/her team's current work pressure. Here comes the report -

Average Age of Open Case:
Another very important report to understand your team's performance - how long your agents are taking to serving customers and thus meeting the service-level agreements (SLAs). To create this report, you can customize the out-of-the-box report "Total Open Cases By Agent" and then summarize the Age column (Summarize by Average). Below is how the report will look like -

Average Age of Closed Case by Agent:
Call center managers can use this report to monitor their agent's productivity in terms of how quickly agents are closing the cases. This report will give a very good comparative study of the agents in terms of their productivity. To create this report, you can customize the out-of-the-box report "Total Open Cases By Agent". Remove the Open equals True filter and add Closed equals True filter, then summarize the Age column (Summarize by Average). Below is how the report will look like -

Monitor Email Queues:
If you have email-2-case configured in your organization and your email cases are routed to individual queues as per the case assignment configuration, then you might need to monitor your email queues to understand how many cases violated, what is the percentage of cases(in standard and out of standard) per queue etc.

In order to do that, use the below details in the report -
  • Use Filter: Case Owner contains
  • Drag the field - Violation from Milestone in the report.
  • Create formula field - (attaching the individual screenshots below)
    • # in standard (# of cases without violation)
    • % in standard (% of cases without violation)
    • # out of standard (# of cases with violation)
 












Below is how the report will look like -

Knowledge Reports:
If you have implemented Knowledge in your organization, then you can install Knowledge base Dashboards and Reports from Appexchange. From there you can go to the report folder - Knowledge Reports Package and get all the important reports available to you. Few important reports are -
  • Case count by Article
  • Cases with Articles
  • Recently created Articles
  • Recently Searches by Keyword
  • Article views
  • Article scores
Omni-Channel Reports:
If you have implemented Omni-Channel in your organization, then below are the reports you might need in your organization. 
  • Omni-Channel - Active Users - This report will give the status of all users currently logged into Omni-Channel.
  • Omni-Channel - Agent Email Metrics - This report will give the summary of email average handle time by Agent.
  • Omni-Channel - Agent Time-Outs - This report will give the summary of email cases that Agents did not accept prior to time out.
  • Omni-Channel - Queue Email Metrics - This report will give the summary of email average handle time by Queue.
Share:

Salesforce Live Agent Chat - Objects

In this post, I am going to explain about the standard objects which will be created by default the moment you enable Live Agent in your organization. Let's start -

Live Chat Visitors:
This object contains information about the visitors who has initiated the chat session. One important field here is the Session Key. A session key in a unique record which is stored on Live Chat Visitor's record and end user's machine as a cookie. But why? The reason is if the end user is initiating multiple chat sessions, then Salesforce will link all Live Chat Transcripts records (This is another object, which I will explain in a few minutes) to this unique Live Chat Visitor record. Here is a sample Live Chat Visitor record.


Live Chat Transcripts:
This is the record which tells you the conversation that happened between your Service Representatives and End Users. It stores the chat transcripts. Salesforce will automatically create the record for you as soon as the chat session is ended and your service representatives close the chat transcript. Here is sample Live Chat Transcript record.


Live Chat Transcript Events:
This object tracks all the events that occur between Service Representatives and Customer during the chat. Few important events are like Chat Request, Accept Request, Route Information, Transfer information. You can see the detail of events - 
https://help.salesforce.com/articleView?id=live_agent_transcript_events.htm&language=en&type=0
Here is sample Live Chat Transcript Event record.

Live Agent Sessions:
This object holds the information about the agent sessions, time spent online, time spent chat, idle time etc. Here is sample Live Agent Session record.

Quick Text:
Quick Text is a very handy option when chatting with customers. If your Sales Representatives are using few sentences quite a number of times, then instead of asking them to write the same again and again you can create Quick Text. It is basically the shortcut for commonly used phrases/questions.
Below is a sample Quick Text for greeting customers with Good Morning.

Now from the chat window, your Sales Representatives can just enter ;; and all available Quick Texts will be available to them. They can select the one. This was it will help them to respond back to the customer much quickly.




Share:

Salesforce Live Agent Chat - Understand the Basics

Using Live Agent Chat, Sales Representatives can chat with their customers and solve their problems or answer their questions. In today's world providing first class services to customers is very important and chat support plays an important role here. Live Agent Chats are referred as Live Chat as well. With Live Chat, customers don't need to wait for the long queue or need to wait for replies for their email queries. They can get immediate attention which eventually improves customer satisfactions.

Trailhead comes up with a very good project "Build a Branded Chat" which explains how to enable Live Chat and it's basic configurations. I recommend everyone to please go through this one and understand the basic of the Live Agent Chat first before proceeding further.

Below is the visual representation of "Live Agent" Object Model. Though I am saying it "Object Model", but most of them are not objects. :-) 


Let's try to two basic terminologies associated with Live Agent.
1. Skill:
To understand Skills, we first need to understand how we want to support our customers - is it based on geography? Is it based on business units? Is it based on products? etc.. Then based on the answers you will hire employees and train them so that they can support your customers. These peoples are known as Sales Representatives who normally support your customers.

So let's say, the company "Global XYZ" is having business all over the world. They are supporting their customers based on geographies. So for them, they will create skills like - APAC, NA, EUROPE, EMEA.

Again let's say the company "Global Insurance MNOP" is selling Insurance Products. So for them, the skills will be - Health Insurance, Car Insurance, House Insurance.

Now you will assign your Sales Representatives(Salesforce Users) to the Skills. It's a many to many relationships i.e. one skill can have multiple Sales Representatives(Salesforce Users) and one Representative(Salesforce User) can have multiple skills. 

2. Deployment:
A deployment is basically the section where you will place all your configurations to control Live Agent behaviors in your website. Deployments will provide JavaScript codes which you will put in your Web pages.

You can have more than one Live Agent deployments. In case your organization has one Service console supporting multiple sites, you can create Live Agent deployments per site.



Trailhead comes up with an image which I really like and it explains the two pillars so clearly.

Trailhead Modules:


Share:

Summer'17 :: Retrieve and Deploy Metadata through Apex


In Salesforce World, Metadata plays a very important role. Metadata types and components are used to represent org specific configuration and customization. Salesforce is having a very good page explaining Metadata. Here is the link - "An Introduction to Force.com Metadata". 

Before Summer'17 release, in order to access Metadata, you need to use the Metadata API, but now Salesforce comes up with Metadata namespace. You can use classes in Metadata namespace to access Metadata components through Apex.

Why do I need to access Metadata?
Salesforce documentation explains it correctly and here are the possible reasons why you may need to access Metadata.

In this post, I am going to explain how you can access and deploy Metadata changes through Apex with an example.

Example -
In my Salesforce Org, I have one Custom Metadata Type named - "Admin Preference" which is -
The values of this Custom Metadata Type are -

Now I will create a simple VisualForce Page which will retrieve this Metadata Values and display them. At the same time from the same page, I will change the values. 

To implement this requirement, I will use the Salesforce Summer'17 New Feature - classes Metadata namespace.

Let's Start -
In order to store the Custom Metadata Values, I will use the below class -

public class MetadataHelper{
    public String name {get;set;}
    public Boolean isEnabled {get;set;}

    public MetadataHelper(String name, Boolean isEnabled){
        this.name = name;
        this.isEnabled = isEnabled;
    }

    public String getFullName(){
        String fullName = 'Admin_Preference__mdt.';
        if(name.equalsIgnoreCase('Process Builder Preference')){
            fullName = fullName + 'Process_Builder_Preference';
        }else if(name.equalsIgnoreCase('Trigger Preference')){
            fullName = fullName + 'Trigger_Preference';
        }else if(name.equalsIgnoreCase('Validation Rule Preference')){
            fullName = fullName + 'Validation_Rule_Preference';
        }else if(name.equalsIgnoreCase('Workflow Preference')){
            fullName = fullName + 'Workflow_Preference';
        }
        return fullName;
    }
 }

How to retrieve the Custom Metadata Types and it's Values: 

To retrieve the Custom MetadataTypes, the command is - Metadata.Operations.retrieve(). This method will retrieve the Metadata synchronously. We need to pass the list of component names and this method will return a list of matching component data (Metadata.Metadata format).

Once you have the list, power is completely in your hand. Trust me!! Really you have all the power you need then. You can iterate through the list and get the each CustomMetadataRecord. Now each CustomMetadataRecord is having CustomMetadataValues which also you can fetch and play around. 
CustomMetadataValues are stored in two fields - the first one is "field" which stores the API name of the field and the second one is "value" which stores the value of that field for that CustomMetadataRecord. Confused??? Don't worry I will give you now a clean picture which helped me to understand and I hope it will help you as well.

To understand how the custom metadata information is stored in Salesforce, consider our Custom Metadata Type mentioned above - Admin Preference. And let's consider one value here - 



So according to the above example - Metadata.Operations.retrieve() will retrieve the CustomMetadataRecord - Process Builder Preference. Now this record is having the label - "Process Builder Preference", which we can get from the label field. The fullName of this record is - "Admin_Preference__mdt.Process_Builder_Preference" which we can get from the method getFullName()
In the above example, this CustomMetadata is having only one value which is stored inside a field of type Metadata.CustomMetadataValue. For that single  Metadata.CustomMetadataValue, the field = 'Enabled__c" and value = true.

So the visual representation of the flow is -


With the above explanation, here comes to code -

How to deploy Custom Metadata Types and it's Values: 
The method Metadata.Operations.enqueueDeployment is used to deploy the changes to the org. The operation is happening in asynchronous mode and that is the reason we need to provide a callback method to handle the success/failure scenarios. To create the callback, we need to implement the interface Metadata.DeployCallback and by doing that we need to put our logic in the method - handleResult.

Below is the CallBack method -

Now to deploy the changes below is the code -

You can find the full code in my Github repository.

With all these changes, below is how the functionality working - 


Limitation - Metadata access in Apex is currently only possible for custom metadata records and page layouts. You can retrieve, create or update custom metadata, but you cannot delete metadata through Apex.


Share:

Follow Me

Enter your email address:

Delivered by FeedBurner

Popular Posts

Labels

Salesforce (95) Apex (42) admin (27) ADM (20) visualforce (20) dev 501 (19) integration (18) learn salesforce (17) 501 (16) SOAP (13) tutorial (11) Certification. (9) Trigger (7) lightning (7) test class (7) unit testing (7) design pattern (6) report (6) trailhead (6) Advanced Admin (5) New Features (5) SOQL (5) css (5) dashboard (5) debug (5) formula (5) javascript (5) mobile (5) salesforce release (5) security (5) service cloud (5) solution management (5) use case (5) JSON (4) Lightning Experience (4) WebSphere (4) best practice (4) cast iron (4) developer (4) github (4) html (4) polymer (4) profiles (4) responsive (4) tdd (4) ui (4) Live Chat (3) Performance (3) Products (3) Sales Cloud (3) Summer15 (3) Tips (3) component (3) deployment (3) dynamic apex (3) event (3) license (3) map (3) mapbox (3) singleton (3) version controlling (3) Advanced Apex (2) Bulkify (2) Distributed Version Controlling (2) Eclipse (2) Force.com IDE (2) Governor Limit (2) IBM (2) Lightning Design System (2) Live Agent (2) Price Book (2) REST (2) SOSL (2) Spring 15 (2) Study Notes. (2) Summer17 (2) ant (2) automation tool (2) basic (2) chatter (2) coding (2) communication (2) console (2) controller (2) documentation (2) flow (2) git (2) jquery (2) logging (2) permission (2) process builder (2) release (2) salesforce1 (2) strategy (2) xml (2) Agent Productivity (1) Asynchronous callout (1) Browser (1) Bulk data load (1) Calendar (1) Canon (1) Case Management (1) Classic (1) Contact Center (1) Continuation (1) Continuous Integration (1) Cookie (1) Custom Metadata (1) Custom Object (1) Decorator Design Pattern (1) Diwali (1) Email (1) Groups (1) Guide (1) Ideas (1) Improvement (1) KPIs (1) LastModifiedDate (1) Metadata (1) Metrics (1) Omni-Channel (1) Opportunity (1) Photo (1) Platform Developer I (1) Product Schedule (1) Profile (1) Public Site (1) Query Plan (1) QuickReference (1) Reports (1) Role (1) Salesforce Optimizer (1) Site (1) Skills (1) Snap-ins (1) Spring 17 (1) Summer14 (1) Summer16 (1) SystemModStamp (1) Users (1) Webservice (1) Winter'15 (1) Winter'17 (1) access (1) agile (1) app (1) approval process (1) aura (1) awesome (1) backup (1) bitbucket (1) book (1) campaign (1) change set (1) code (1) code coverage (1) configuration (1) csv (1) custom button (1) custom settings (1) customization (1) data loader (1) database (1) delegate Admin (1) describe (1) dom (1) dreamforce (1) duplicate (1) dynamic (1) equals (1) error (1) field-level security (1) folder (1) ftp (1) generic (1) gift (1) global describe (1) hashcode (1) import wizard (1) jenkins (1) keynote (1) long running requests (1) monitoring (1) mysql (1) object (1) page layout (1) personal (1) power of one (1) record type (1) relationship (1) request (1) review (1) sub-tab (1) tab (1) username (1) visual workflow (1) workflow (1)

My Trailhead

Total Subscribers

Total Pageviews