When Salesforce is life!

Tag: Crusade Page 3 of 4

[Salesforce] The Sobject Crusade: ActivityHistory

Back to the Sobject Crusade list.

Source: ActivityHistory

The ActivityHistory object is a read-only object that shows all completed Tasks and past Events related to a give object (e.g. Account). It includes activities for all contacts related to the object.

This object is shown in the Activity History related list:

Few limitations apply:

  • The object cannot be queried directly but only queried through inner query (e.g. Select Id, (Select Subject From ActivityHistory) From Account Where Name = ‘ACME bros’)
  • Your main query must reference exactly 1 record
  • Inner query must not have a WHERE clause
  • Inner query must filter a maximum of 500 items

Here is an example query:

SELECT Name, (SELECT ActivityDate, Subject, IsTask FROM ActivityHistories ORDER BY ActivityDate ASC NULLS LAST Limit 500) FROM Account WHERE Name =’ACME Bros’

[Salesforce] The Sobject Crusade: AdditionalNumber

Back to the Sobject Crusade list.

Source: AdditionalNumber

This is an optional additional number for a call center, visible on the call center’s phone directory: this is useful for numbers not releated to CRM objects (e.g. queues, conference rooms).

This seems boring, but continue reading to see some more action!

To create a new number, go to Setup > Customize > Call Center > Directory Numbers and click the New button:

The object can be optionally linked to a specific call center: if not set, this will be considered a global value (cross-call center valid).

Upon save you can query this object:

select Id, Name, Phone, Description, CallCenterId from AdditionalNumber

This is awesome, right?

Not at all!

Let’s see how this is included in the overall Call Center configuration.

The Call Center configuration involves the configuration of a Computer Telephony Intgration, aka CTI.

As you can see in the picture above, CTI is an external service that communities with Salesforce: it is responsibile for handling phone (and other means, such as SMS or chat) communications and sending back to the CRM information about the call (e.g. calling number, duration of the call, origin, …).

Here you can find the latest complete guide on CTI configuration.

Salesforce.com fortunately give developers a way to try this feature out without having to have access to real CTI hardware.

First download the CTI Demo Adapter from this link.

Once installed, you’ll see the icon in the lower right corner of your desktop (sorry, MS Windows systems only); take the [installed dir]/DemoAdapter.xml file.

Now click on Setup > Customize > Call Center > Call Centers and click the Import button and import the previous XML file.

Click on Add user button to add new users (your current user at least).

Go to the Home page, you’ll see a new component on the sidebar:

Wait till you see a new popup appearing (if it takes longer that a few seconds, click the button):

If you can’t still see anything, it may be because of this kind of error while loading the CTI “localhost” service (see the CTI Adapter URL field on the Call Center setup page):

This happens because you are on an HTTPs site and trying to load an HTTP (less secure) content inside an iframe (don’t worry it’s not your fault!).

Click on the little shield on the addess bar (I’m using Chrome) and click on “Load Anyway” link on the popup that will appear (and reload the page).

Insert your Salesforce username/password to connect to the CTI:

Now the fake CTI adapter can trigger the following actions (right click on the adapter icon):

All this configuration to show where the AdditionalNumber object lays.

Click on the search button next to the textbox for dialing a number:

Select the number and watch it on the dial box:

Just for fun, let’s take an Account and assign it the “4155551212” phone number:

This means that when the customer calls from this number, the CTI adapter will give Salesforce the calling phone number and redirects the user to the correct Account page. Let’s click on the “Call From 415-555-1212” CTI Adapter action:

To watch Salesforce loading automagically the given Account page:

The sidebar shows additional infos for the Call Log, you can update as needed: this call will be saved in a Task object:

You can customize the Demo Adapter by changing the “demo_menu.xml” file (see more datails in the guide).

[Salesforce] The Sobject Crusade: ActionLinkTemplate

Back to the Sobject Crusade list.

Source: ActionLinkTemplate

Action Links has been presented when discussing the ActionLinkGroupTemplate object (see this object for a complete guide on configuring and using Action Links): they are a way to execute custom actions on button click on Chatter feed posts.

By templating an Action Link you define a template action which can be “instantiated”.

The Action Link is defined by:

  • LinkType: this is the kind of action that you want to expose, and it can be:
    • Api: direct call to an API endpoint (with given method, parameters, headsrs)
    • Api Async: like the previous point but the server response is asyncrhonous: this way the serve have to send a response to /connect/action-links/[actionLinkId] endpoint to set the SuccessfulStatus o FailedStatus of the operation
    • Download: triggers a download of a file
    • Ui: redirects to the given URL
  • ActionUrl: endpoint of the action. This could have bindings values, e.g. “https://myapi.com/id={!Bindings.customValue}&userId={!userId}”
  • Headers: headers request values (only for Api and ApiAsync), binding supported. Every header value should be in the form (one per line) “Header-key: value”
  • Method: HTTP method for the request, with the following supported behavior:
    • HttpDelete: HTTP 204 on success, response body is empty
    • HttpGet: HTTP 200 on success
    • HttpHead: HTTP 200 on success, response body is empty
    • HttpPatch: HTTP 200 on success or HTTP 204 if response body is empty
    • HttpPost: HTTP 201 on success or HTTP 204 if response body is empty
    • HttpPut: HTTP 200 on success or HTTP 204 if response body is empty

    “Ui” and “Download” types support only “HttpGet” value.

  • RequestBody: bpdy of the request (only for Api and ApiAsync), binding supported
  • LabelKey: standard set of labels (None if none apply, then use the Label field)
  • Label: custom label associated to the action (Pending, Success and Failed applied to the action action)
  • Position: position of the action in the defined group (0 is the first)
  • IsConfirmationRequired: users is prompted with a confirmation alert box upon click on the action
  • IsGroupDefault: default group action
  • UserVisibility: states who can see the action, that is Creator, Everyone, EveryoneButCreator, Manager (manager of the creator on the Action Link), CustomUser or CustomExcludedUser (using the UserAlias field to link to a specific user)
  • UserAlias: user alias to set the visibility of the action. Supports binding
  • LinkType:
  • LinkType:

You can query this object:

Select Id, ActionLinkGroupTemplate.DeveloperName, LinkType, ActionUrl, Headers, IsConfirmationRequired, Label, Method, RequestBody From ActionLinkTemplate

And get:

[Salesforce] The Sobject Crusade: ActionLinkGroupTemplate

Back to the Sobject Crusade list.

Source: ActionLinkGroupTemplate

Action Links are actions you can do in chatter posts (e.g. API call, document download, UI redirect) by clicking a button on the related chatter post.

Action Links are grouped into Action Link Group, so you can choose which action you want to play:

You may think that these actions comes to configuration and some sort of layout, but it is part configuration and part Chatter API call.

Action Links are grouped into Action Link Groups but this is not the object that will be configured.

In fact we talk about Templates (Action Link Group Template and Action Link Template): we define template actions rather than the actual actions we’ll be executing.

The template defines the actions you want to apply to a Chatter feed: when you want to apply the group of actions to a feed, we’ll make an API call to get the “instance” of the actions to be linked to the feed.

Let’s start creating a Group Template (the object we are inspecting here) clicking on Setup > Create > Action Link Templates:

You can define:

  • Name and DeveloperName
  • Category (position of the action buttons in the feed)
  • Number of execution allowed
  • Hours untile the action expires

Once a group is published it cannot be modified anymore.

Let’s query the object:

select id, DeveloperName, IsPublished, MasterLabel  from ActionLinkGroupTemplate

Let’s define the actions:

With the following main fields (more details here):

  • Type of Action (API, API Async, UI, Download)
  • Endpoint of the action (in this example a simple request bin)
  • HTTP Method
  • HTTP Request Body
  • HTTP headers
  • Position among other buttons
  • Label (you can choose between some presets and a custom label)
  • Visibility

Consider that URL, request body and headers can have standard and custom binding values (you can for example pass the current User ID or a custom binding value).

These are the actions defined:

To use them we need a valid Session ID, a call to the /connect/action-link-group-definitions/ API endpoint and a call to Chatter API to send a feed.

We’ll be doing things manually (we could use Workbench, but we like to get our hands dirty!).

First we get a valid OAuth Session ID.

Click on Setuo > Create > Apps click on New button in the Connected Apps section; we only need to setup the middle section:

to get access to Chatter API.

This is what you get:

This application will be online in 10 minutes at most.

Let’s make a REST call to get a valid token using the OAuth Password Flow (details here ):

POST https://login.salesforce.com/services/oauth2/token
    Headers:
        Content-Type: application/x-www-form-urlencoded
    Body:
        grant_type=password&client_id=[APP_CONSUMER_KEY]&client_secret=[APP_CONSUMER_SECRET]&username=[USERNAME]&password=[PASSWORD+TOKEN]

The response returns the Session ID (athorization token) we’ll use to get a valid Action Group Id from this REST call:

POST https://xxx.salesforce.com/services/data/v34.0/connect/action-link-group-definitions/
    Headers:
        Authorization: Bearer [SESSION_ID]
        Content-Type: application/json
    Body:
        {"templateId":"07g24000000CaTc","templateBindings":[]}

Where templateId is the ID of the Action Link Group Template (you can query for it or get it in the configuration section of the template), and templateBindings is a list of objects (with “key” and “value” fields) for custom bindings.

This call will return an instance of the template:

{
  "actionLinks": [
    {
      "actionUrl": "https://requestb.in/11jyqzq1",
      "createdDate": "2015-08-14T20:41:42.566Z",
      "excludedUserId": null,
      "groupDefault": false,
      "headers": [
        {
          "name": "content-type",
          "value": "application/json"
        }
      ],
      "id": "0An240000004FSDCA2",
      "label": "Salute!",
      "labelKey": "None",
      "method": "HttpPost",
      "modifiedDate": "2015-08-14T20:41:42.566Z",
      "requestBody": "{"message": "Hello!", "from":"{!userId}"}",
      "requiresConfirmation": false,
      "templateId": "07l24000000GmbgAAC",
      "type": "Api",
      "userId": null
    },
    {
      "actionUrl": "https://requestb.in/11jyqzq1",
      "createdDate": "2015-08-14T20:41:42.566Z",
      "excludedUserId": null,
      "groupDefault": false,
      "headers": [
        {
          "name": "Content-Type",
          "value": "application/json"
        }
      ],
      "id": "0An240000004FSECA2",
      "label": "Insult!",
      "labelKey": "None",
      "method": "HttpPost",
      "modifiedDate": "2015-08-14T20:41:42.566Z",
      "requestBody": "{"message":"Bad Word", "from":"{!userId}"}",
      "requiresConfirmation": true,
      "templateId": "07l24000000GmblAAC",
      "type": "Api",
      "userId": null
    }
  ],
  "category": "Primary",
  "createdDate": "2015-08-14T20:41:42.566Z",
  "executionsAllowed": "Once",
  "expirationDate": null,
  "id": "0Ag240000004FSNCA2",
  "modifiedDate": "2015-08-14T20:41:42.566Z",
  "templateId": "07g24000000CaThAAK",
  "url": "/services/data/v34.0/connect/action-link-group-definitions/0Ag240000004FSNCA2"
}

Now we can use the id to post the action with a feed:

POST https://xxx.salesforce.com/services/data/v34.0/chatter/feed-elements
    Headers:
        Authorization: Bearer [SESSION_ID]
        Content-Type: application/json
    Body:
        {
          "body": {
            "messageSegments": [
              {
                "type": "Text",
                "text": "What do you want to say me?"
               }
            ]
            },
          "subjectId": "me",
          "feedElementType": "FeedItem",
          "capabilities": {
            "associatedActions": {
              "actionLinkGroupIds": ["0AgRR0000004CTr0AM"]
            }
          }
        }

Once you click on a button, the action is executed and no more action is possible:

The same sequence can be done using Apex and the ConnectApi library:

// Get the action link group template Id.
ActionLinkGroupTemplate template = [SELECT Id FROM ActionLinkGroupTemplate WHERE DeveloperName='Say_Hello'];


// Create ActionLinkTemplateBindingInput objects from the map elements.
List bindingInputs = new List();
/*
// Add binding name-value pairs to a map: our action does not have custom bindings
Map bindingMap = new Map();
bindingMap.put('aBinding','aValue');
for (String key : bindingMap.keySet()) {
    ConnectApi.ActionLinkTemplateBindingInput bindingInput = new ConnectApi.ActionLinkTemplateBindingInput();
    bindingInput.key = key;
    bindingInput.value = bindingMap.get(key);
    bindingInputs.add(bindingInput);
}
*/

// Set the template Id and template binding values in the action link group definition.
ConnectApi.ActionLinkGroupDefinitionInput actionLinkGroupDefinitionInput = new ConnectApi.ActionLinkGroupDefinitionInput();
actionLinkGroupDefinitionInput.templateId = template.id;
actionLinkGroupDefinitionInput.templateBindings = bindingInputs;

// Instantiate the action link group definition.
ConnectApi.ActionLinkGroupDefinition actionLinkGroupDefinition = 
ConnectApi.ActionLinks.createActionLinkGroupDefinition(Network.getNetworkId(), actionLinkGroupDefinitionInput);

This is what the bin has received:

Imagine you can use this feature for allowing selected users to partecipate to surveys/polls or make them doing actions to monitor their behavior.

Page 3 of 4

Powered by WordPress & Theme by Anders Norén