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.