Saturday 26 December 2020

Platform App Builder Certification Maintenance (Winter '21)

 Where should an app builder go to analyze performance on a Lightning record page?

  1. Lightning App Manager
  2. Lightning Object Manager
  3. Lightning App Launcher
  4. Lightning App Builder

Answer : Lightning App Builder

What field is updated when deploying sharing settings simultaneously?

  1. Sharing Criteria Rules
  2. Sharing Models
  3. Criteria Items
  4. Owner Rules
Answer: Sharing Models

What should an app builder use to build a collection of records for three different custom objects?

  1. Use a reusable screen Component
  2. Create a custom Component
  3. Clone a Screen Component
  4. Use Loop Component

Answer: Use a reusable screen Component

An app builder received feedback that a custom page layout has too many fields on it, and some fields are only needed if other fields are entered. What should an app builder configure to help with this issue?

  1. Dependent picklist
  2. Lightning Web Component
  3. Dynamic Forms
  4. Separate page layouts & record types
Answer: Dynamic Forms

What type of flow is available for an app builder to debug as another user?

  1. Invocable process
  2. Screen Flows
  3. Platform Events
  4. Record Change Process
Answer: Screen Flows


Platform Developer I Certification Maintenance (Winter '21)

 How can a suspended event be resumed where it left off, to avoid missing any events that were published during the suspension?

  1. Refresh the Event
  2. Resume the Event
  3. Resume the Event from New 
  4. Resume the Event from Tip
Answer: Resume the Event

Which statement is true regarding events configured with the Publish Immediately behavior?

  1. Publish immediately Events count towards Apex DML limits
  2. EventBus.publish() returns how many platform events are configured to publish immediately.
  3. The events are published and do not depend on the successful completion of the transaction.
  4. Events published immediately prevent Apex callout from being performed after publishing.

Answer: The events are published and do not depend on the successful completion of the transaction.

What is the minimum code coverage requirement in order to promote and release an unlocked package?

  1. 70%
  2. 75%
  3. 85%
  4. 90%

Answer: 75%

When using WITH SECURITY_ENFORCED in a SELECT clause, what happens if a field referenced in the clause is inaccessible to the user?

  1. The query succeeds, but no data returned.
  2. The query succeeds, and null data set is returned.
  3. The query fails with an error indicating no access allowed.
  4. The query throws an exception indicating insufficient permission and no data is returned.

Answer: The query throws an exception indicating insufficient permission and no data is returned.

A developer wants to send a custom notification when an important event occurs. What can the developer use?

  1. Messaging.Custom Notification Class
  2. Messaging.Push Notification Class
  3. Messaging.Notification Action Class
  4. Messaging.Send Notification Class

Answer: Messaging.Custom Notification Class

A developer wants to check whether a user has a standard permission. Where should the developer import Salesforce permissions from in order to check this?

  1. @salesforce/hasPermission
  2. @salesforce/customPermission
  3. @salesforce/userPermission
  4. @salesforce/customPermission/namespace

Answer: @salesforce/userPermission

When does Salesforce plan to enforce the removal of instance names from all Visualforce URLs?
Answer: Summer 22
What is a current use case for incorporating the @track decorator in a field of a Lightning web component?
Answer: To observe changes when the field contains an array

What is the default behavior of the Lightning message service scope parameter?

  1. Active area Only
  2. Entire application
  3. Publisher message channel
  4. Active area and all hidden tabs

Answer: Active area only

HandsOn 


Updated Code of class

@RestResource(urlMapping='/apexSecurityRest')
global with sharing class ApexSecurityRest {
    @HttpGet
    global static Contact doGet() {
        Contact result;
         Id recordId = RestContext.request.params.get('id');
    
          List<Contact> results = [SELECT id, Name, Title, Top_Secret__c, Account.Name FROM Contact WHERE Id = :recordId];
          SObjectAccessDecision securityDecision = Security.stripInaccessible(AccessType.READABLE, results);
          
           SObjectAccessDecision securityDecision2 =
       Security.stripInaccessible(AccessType.UPDATABLE,
             [SELECT Description FROM Contact]
             );
             result.Description = result.Account?.Name;

           return result;
      }
      public class FunctionalException extends Exception{}
      public class SecurityException extends Exception{}
}

Thursday 24 December 2020

Salesforce - Sending Surveys to Customer using Salesforce Survey

 Salesforce Survey

In order to use salesforce surveys, org must have salesforce surveys enabled. Salesforce gives us previlage to send surveys to employees and to user outside of company. In this post I will explain how we can send surveys to contacts outside of company without using code.

In order to achieve this we will use following things
  1. Salesforce Surveys
  2. Community
  3. Flow
  4. Email template
  5. Process Builder

Survey

Make sure your salesforce org has lightning turned on as salesforce survey object is accessible in lightning only. In order to access salesforce survey tab you can access it from both lightning and classic.
 Go in setup search and write down survey. Click on survey settings and make sure you turned on survey from here. Later in this post we will create a community to select here.
Now select salesforce survey from lightning tabs and click new and create a survey. Select name as surveys for customers. Add some text on survey welcome page. Something like that

At Universal Container we are committed to providing our customers the best technical support and service. Please take this brief two-minute survey about your recent contact with our Technical Support Staff.

Add next page and click on page and click on Add Question button and select NPS to add on your page. Enter below text as question




How likely are you to recommend our service to a friend or colleague?

Add below text on thank you page

Thank you for taking the survey. Your feedback is important to us

Click save and then click activate button. If you want to update this survey you have to create a separate version.

Survey Invitation

Go in survey invitation object and create a custom field email. This field will be used to send surveys to emails.

Community

Now we will create a community which will be used as a bridge to send surveys to contacts outside of our company.
Go in setup search and write all communities. Click on All communities and then create a community by clicking button new community.
Select build your own and then click Get Started. Enter name "Survey" and url survey and click create.

It will take few minutes for system to create your community.
Now go back into survey settings and select this community 

Flow

In order to launch surveys automatically we will be using lightning flows. When a case is closed we will automatically launch a flow. Go in the setup search and write down flow. Click on flows under process automation heading. Click new flow button and select record triggered flow.

Now select when record is updated then select objects is case and then put condition status equal to closed.
Now drag get records to get community information. We need community information create survey invitation data.
Add condition community name = survey
Now use get records to get survey record id.

Drag create record and now create a record for survey invitation object with below mapping

community id = community id
Survey id = survey id
Email = Contact email
Allow guest user response = true
Invitation name = test




Now add an action. select email send. Add email alert name and select survey invitation record id in related record id option.

In order to make sure you only send one survey per case update case with the check box survey send = true in the end of flow.
Now activate your flow.

Publishing Community

Now go back into setup and select all communities and then click builder in front of your community name.
Click on components and type survey in search box. drag and drop survey component on front page and then select your survey on it.
Now go in community profile and make sure that community profile have cru right on survey, survey invitation and survey response object.
Now mark your community as public and then publish it.



Email Template

Create an email template with below wording and create take survey link like this
Community Url/runtimeApp.app?invitationId={!SurveyInvitation.Id}&surveyName={!SurveyInvitation.Name}&UUID={!SurveyInvitation.UUID}


Process Builder


In order to stop contacts filling survey multiple times you can create a process builder on survey invitation object. Select when record is created or updated.
In condition select status ischanged = true and status = completed in action use immediate action and mark allow guest response to false.


Friday 17 July 2020

Salesforce - Text Messaging Service

Salesforce Messaging

Messaging lets your company have conversations with customers in the ways that are most convenient for your customers—on their mobile devices using messaging apps such as SMS text messaging and Facebook Messenger. Agents can respond in the Service Console, where they can access all the benefits of Digital Engagement at their fingertips.

Text Messaging

To setup text messaging you first need messaging license from salesforce. License name is "Messaging User". Once you have license you have to go in setup(make sure to use lightning and click on service setup) to enable messaging. Go in service setup and search for messaging.Click on messaging settings and toggle the button and enable messaging in your organization.

After enable click on "New Channel" button. It will ask you log a case with salesforce so they can assign a channel number(phone number) to your org. This number will be used by your org to send messages to customers.

You can use text, messenger and whatsapp messages in our scenario we will discuss about text messages.

Use Case

 In this article we will perform a use case that when order status is changed system should pick up contacts of the account the order is associated to and send them status of order. This is like the same use case when we place an order with amazon and get order status updates text messages.

Messaging Setup

Once salesforce replies you back with a phone number assigned to your org you have to start configuring system.First of all go on your user record and scroll down to license permission  and then assign yourself messaging user license.
Then create messaging user permission set as per this link and assign it to your user. Once these two step are down you will be able to edit channel configurations to setup opt in and opt out communications.
 
Note:As in my use case we are not using omni channel but we still have to configure complete setup of omni channel otherwise  text messaging will not receive opt in and opt out communications.

Go in set up and search for omni channel setting and click the checkbox and enable omni channel.
Now from setup search for presence configuration and create a presence configuration.

Now from setup search for presences statuses and click on new button.Create new presence status "Messaging" and select messaging channel in it.

Now from setup search for routing configuration and click new button.Create a new routing configuration and 
Routing Configuration Name = Messaging Routing
Routing Priority = 1
Routing Model = Most Available

Now from setup search for service channel and click new. Create  anew service channel.
Name = Messaging
developer name = sfdc_livemessage
Object = Messaging Session
Create a queue with name messaging queue and add following objects
Order
Contact 
Account
Messaging User
Messaging Session

Routing Configuration = Messaging Routing(the one you created above)

Add system admin profile in this queue. Now edit channel in routing type select queue based routing and in queue lookup selects your messaging queue.Add opt in and opt out communication as per below and leave all the other things blank and save the channel configurations.

Opt in: You have opted in to receive sales order update texts
Opt out: You have opted out for all sales order update texts

Process Builder

Now to send text messages automatically once order status is updated we will create a process builder.
From setup search process builder and click new. Select Order object and add a criteria Ischanged(Status) then on action choose flow. Pass order id to flow

Flow

Create an auto launched flow 
Flow name = Order Status Message

Get Records

Get order records from the id passed by flow as per below image

Get Records

Get account contact relation data using order object account. In this way we can get all the contacts of account.As shown in image



Decision


Check if no contacts are found then stop the flow if contacts are found then Loop around them.As per image

Loop




Get Records

Get messaging user record of contact as per image.

Decision

Check if messaging user record is already exist for this contacts or not. As per image


Action

If messaging user record exist then send text.As per image


Create Messaging User Record

If messaging user record does not exist then create a messaging user record.Note: Make sure that when you create messaging user record then platform key and messaging user name should be same and platform key should have +1 in phone number otherwise system will create duplicate records.

Note: messaging user record of one phone number can be configured on one channel

Friday 10 July 2020

Salesforce - Open SAP from Salesforce

Scenario:

I got a requirement from one of my client that while using salesforce they want to open SAP. So they need a button on order screen which will pass few values from salesforce into SAP.Once user click the button in salesforce, SAP screen should popup on the salesforce screen with all the values of order auto populated in SAP. This will help the reps to enter order information into their SAP system. If SAP is not login then the SAP popup should still appear but with an error that SAP is not login.

Design:

After a lot of struggle we were able to make this happen but it has few down sides too. 
We created a javascript button in salesforce below is the code of it. This javascript query all the data from case object related to order and call a bat file which is on client centralized location. This centralized location is easily accessible by all the users from client side. Then this bat file call SAP.

Drawbacks

This solution will only work if salesforce is open in internet explorer as chrome and other browsers have different level of security for Active XObject which is not allowing to open another application.

We need a VBS file which listen to our request and enter all the values send by salesforce into fields.

VBS file and BAT file should be on same location not accessible by all users who want to use this functionality.

Code of button:


{!REQUIRESCRIPT("/soap/ajax/33.0/connection.js")}

{!REQUIRESCRIPT("/soap/ajax/33.0/apex.js")}


var ContactInfo = sforce.connection.query("select Id,Contact.RecordTypeId,Contact.LastName,Contact.FirstName,Contact.Phone,Contact.Email,Contact.MailingCountryCode, Contact.MailingCity,Contact.MailingStreet, Contact.MailingStateCode, Contact.MailingPostalCode,Contact.MobilePhone from case where id = '{!Case.Id}'");


records = ContactInfo.getArray("records");


if(records[0].Contact.RecordTypeId != 'ABC9999999'){
alert('Order type not supported, this feature.Enter order manually');
}

else if( records[0].Contact.MailingCity && records[0].Contact.MailingStreet && records[0].Contact.MailingStateCode && (records[0].Contact.Phone || records[0].Contact.MobilePhone)&& records[0].Contact.MailingPostalCode && records[0].Contact.MailingCountryCode && records[0].Contact.FirstName){


var ConCity = records[0].Contact.MailingCity;
var ConStreet = records[0].Contact.MailingStreet;
var ConState = records[0].Contact.MailingStateCode;
var ConPostalCode = records[0].Contact.MailingPostalCode;
var ConCountry = records[0].Contact.MailingCountryCode;
var ConFirstName = records[0].Contact.FirstName;
var ConLastName = records[0].Contact.LastName;
var Name = ConFirstName +' ' +ConLastName;
var CaseID = '{!Case.CaseNumber}';
if(records[0].Contact.Email){
var ConEmail = records[0].Contact.Email;}
else
var ConEmail = '';
if(records[0].Contact.Phone){
var ConPhone = records[0].Contact.Phone;}
else
var ConPhone = '';
if(records[0].Contact.MobilePhone){
var ConMobile = records[0].Contact.MobilePhone;}
else
var ConMobile = '';
var PONumber = (ConPhone == ''?ConMobile:ConPhone) ;


var path = "\\\testlocation\\SFDC_test.bat " +'"'+ConPhone+'"'+' '+'"'+Name+'"'+' '+'"'+ConLastName+'"'+' '+'"'+ConStreet+'"'+ ' '+'"'+ConPostalCode+'"'+' '+'"'+ConCity+'"'+ ' ' +'"'+ConState+'"'+ ' '+'"'+ConCountry+'"'+' ' +'"'+ConEmail+'"'+ ' ' +'"'+CaseID+'"'+ ' ' +'"'+ConMobile+'"'+ ' ' +'"'+PONumber+'"';

MyObject = new ActiveXObject("WScript.Shell");


MyObject.Run(path);

}

else if( !records[0].Contact.MailingCity || !records[0].Contact.MailingStreet ||
!records[0].Contact.MailingStateCode || !records[0].Contact.MailingPostalCode || !records[0].Contact.MailingCountryCode){

alert('Please provide complete address on Contact');
}
else if( !records[0].Contact.Phone && !records[0].Contact.MobilePhone){

alert('Please provide Phone/Mobile Phone on Contact');
}
else if( !records[0].Contact.FirstName){

alert('Please provide First Name on Contact');
}
else{
alert('There is some error in the data');
}

Code of bat File

@echo off
 
SET p1="%~1" 
SET p2="%~2"
SET p3="%~3" 
SET p4="%~4"
SET p5="%~5" 
 
SHIFT
SHIFT
SHIFT
SHIFT
SHIFT
SHIFT
 
SET p6="%~0"
SET p7="%~1"
SET p8="%~2"
SET p9="%~3"
SET p10="%~4"
SET p11="%~5"
SET p12="%~6"
SET p13="%~7"
SET p14="%~8"
SET p15="%~9"
 
  
 
wscript "\\testlocation\demo.vbs" %p1% %p2% %p3% %p4% %p5% %p6% %p7% %p8% %p9% %p10% %p11% %p12% %p13% %p14% %p15%
 
Note: You may see more parameters in bat file. You can add or subtract as many parameters as per your need.

Dell Boomi-Consume WSDL in Boomi to integrate system with Salesforce

WebService Soap Client Connector

In order to connect salesforce with some other system using wsdl, we have to use dell boomi webservice soap connector.

Use the Web Services SOAP Client connector (a generic connector) to integrate with any web-based or on-premise application that exposes a SOAP web services interface.

This connector enables developing integrations against various SOAP-enabled applications.

Configure Connector

You will have a wsdl link from your source system. In my case we will use a dynamic link which can get some parameters and return us results. This is a secure wsdl so we have to configure the security also.

Here is a test link

WDSL URL = https://demo.com/fni-bin/demotest.cfg/services/soap?wsdl
SOAP End point URL = https://demo.com/fni-bin/demotest.cfg/services/soap

Note: One thing to note is that while configuring connector do make sure that you do not add wsdl word in the soap end point url. as shown above. If your wsdl is secure then enter user name and passwords.Based on the security level you can set security type.




Setting Parameter

In the start shape connector when you are done with configuring connector click on parameter shape and set your parameters. As shown in picture.

Convert Data from WSDL into CSV

When wsdl sends us data its in the form of columns and rows and we have to convert it into a format that can be read by salesforce. In order to accomplish this we will use a map in boomi. In the source profile we will use the profile structure which we get from wsdl and in the destination we will create a dummy data holder flat file profile. This flat file profile will help us to distinguish between data and column headers. As shown below.

Convert Data from CSV format to XML for Salesforce

Now we will configure another map and put it right after our conversion map(the map we configure above). This new map will help us to convert flat file data into xml format which salesforce accept.
In the source side you will create a flat file with all the column names your wsdl provides. This will be a manual activity. You have to manually create all the column names.Make sure you use correct names and sequence.If name or sequence are misspelled or misplaced data of one field will enter into another field.
On the destination side use salesforce xml profile and do the mapping as per your requirements.Now add your salesforce connector and insert data into salesforce.

Add try and catch to make sure all the errors you encounter are logged somewhere.

Dell Boomi API Management-Configure Rest Based API for form Based Jason Response

Dell Boomi API Management
Most of you are familiar with Dell Boomi API management feature. APIs are implemented as deployable API components. There are two types: API Service and API Proxy. Using API components enables you to consolidate API design into a single, explicit location.
In API Service, we can define an endpoint using a Rest or Soap.

Configure API:
First we have to configure an API.Give your API a title and then a base path.As Shown in screen shot below.


Then go on Rest Tab and it will automatically configure path for you then click on Add End Point button.Configure you end point. Configure your input type and output type and create a process that will handle your request.As shown in screen shot.



Create Listener Process
Now create a process that will listen all the request send to API. In my example i am configuring a process that will get two inputs as API parameter and on the bases of those inputs insert data into salesforce.
Starting connector will be WebService Server Connector with Listen action. Create its operation with 
Operation Type = Get
Object= will be your resource path you configure during end point creation
Expected Input Type = Single Data
Response Output Type = Single Data
Result Content Type = text/plain


Then you have to use this groovy script so parameter values can be assigned to your variables.Below groovy script will be used.

import java.util.Properties;
import java.io.InputStream;

import org.apache.http.NameValuePair;
import org.apache.http.client.utils.URLEncodedUtils;
import java.nio.charset.StandardCharsets;

for( int i = 0; i < dataContext.getDataCount(); i++ ) {
    InputStream is = dataContext.getStream(i);
    Properties props = dataContext.getProperties(i);

    def input = is.text;
    def data = URLEncodedUtils.parse(input, StandardCharsets.UTF_8) as List<NameValuePair>;
    
    for ( NameValuePair arg: data ) {
        props.setProperty("document.dynamic.userdefined." + arg.name, arg.value);
    }
    
    dataContext.storeStream(is, props);
}

Now we have to use dynamic properties to get values from endpoints. Will create two dynamic process properties to get Account Id and Account Key. Dynamic process property name = AccountId and AccountKey. It will get value from our endpoint. Our endpoint is 

Http:Demo//ws/rest/Test/Lim?AID=123456&Key=444 

Dynamic Process Property Name = AccountId
Parameter = Dynamic document property with name = AID

Dynamic Process Property Name = AccountKey
Parameter = Dynamic document property with name = Key

Note: One thing to note here is that my dynamic process property names are same as my url parameter name. This is the key point to set variables. The bold words in my url are my parameters placeholder i have given the same name to my dynamic process property. This is how you can set values.

In my case we will use another dynamic process property to check that the account id and key combination is in salesforce or not.In the decision box will check if salesforce do not have this combination we will send an email alert if this combination exists we will insert data in salesforce.

Salesforce Connector

Configuring salesforce connector or mapping data is easy tasks and can be found in below links.