Build a Rich Publisher App
Learning Objectives
- List the interfaces and events provided in the Rich Publisher Apps platform.
- Build a Rich Publisher App from scratch.
- Configure Rich Publisher Apps in an Experience Cloud site.
Step 1. Upload Your Icon Image and Get Its File Asset ID
To provide an icon to show in the feed publisher and to package it with your app, you need the icon’s fileAsset ID.
You use the fileAsset ID when you create the ChatterExtension entity. Adding the fileAsset ID to ChatterExtension lets you package the icon file with your app.
Here’s how you upload the icon image and get its fileAsset ID.
- Upload your icon file to Salesforce.
- Copy the file ID.
You can get the file ID from file details in Salesforce. Go to the Files page, and view file details. Copy the file ID from your browser’s URL. It’s a long number, like 069R00000003roQ.
- Go to Workbench, and get the value for id under fileAsset.
- In the REST Explorer, select Post, and enter the path: /services/data/v43.0/connect/files/[file_ID]/asset
- For [file_ID], enter the file ID you copied in Step 2.
- In the Request Body, enter {}.
- Click Execute.
- Expand the fileAsset node, copy the value for id, and paste it somewhere for later user.
Step 2. Create Lightning Components for Composition and Rendering
When a site member clicks a Rich Publisher App icon, the action causes a composition modal to open. The modal contains a Lightning component. The Lightning component enables the user to select something, search for something, or generate something. You have the freedom to customize this component for your use case.
Let’s see how one company uses the Rich Publisher Apps platform to attach cases to posts and questions.
Meet Capricorn
Capricorn sells coffee and high-end coffee brewing equipment and prides itself on its customer service. One of its secrets is the site it set up for customer service agents to discuss open cases and collaborate on solutions. Capricorn wants to develop a Rich Publisher App for attaching cases to posts and questions. They want to give their agents a way to mine past solutions for quick resolutions in the present. Here’s what they do.
A. Create the First Lightning Component
Create a Lightning component that extends the Lightning interface lightning:availableForChatterExtensionComposer. The composition component uses this interface.
The Capricorn developer team uses an aura iteration to show list items in the component code. Here is the Lightning component code.
<aura:component implements="lightning:availableForChatterExtensionComposer" controller="caseController"> <aura:handler name="init" value="{!this}" action="{!c.init}"/> <aura:attribute name="items" type="List" description="Contains a list of items for user to select."/> <div class="container"> <aura:iteration items="{!v.items}" var="item" indexVar="index"> <div class="itemContainer" onclick="{!c.selected}"> <div class="itemLeft"> <img class="itemIcon" src="https://login.salesforce.com/logos/Standard/record/logo.svg"></img> </div> <div class="itemRight"> <div class="itemTitle">{!item.title}</div> <div class="itemDescription">Case Number: {!item.caseNo}</div> </div> </div> </aura:iteration> </div> </aura:component>
The Capricorn team makes an Apex request in the controller init function to fetch support case information for the selection list. Here is the controller code associated with the Lightning component.
({ init : function(cmp, event, helper) { var action = cmp.get("c.getCases"); action.setCallback(this, function(response) { var state = response.getState(); if (state === "SUCCESS") { var caseList = []; var response = response.getReturnValue(); for (var i=0;i<response.length;i++) { caseList.push({ "title": response[i].Subject, "caseNo": response[i].CaseNumber }) } cmp.set("v.items", caseList); } }); $A.enqueueAction(action); }, selected: function(cmp, event, helper) { var selectedItem = helper.getSelectedItem(cmp, event); var compEvent = cmp.getEvent("sendChatterExtensionPayload"); compEvent.setParams({ "payload" : helper.getPayload(selectedItem), "extensionTitle" : helper.getTitle(selectedItem), "extensionDescription" : helper.getDescription(selectedItem) }); compEvent.fire(); } })
Here is the helper code to go along with the controller.
({ getSelectedItem: function(cmp, event) { var clicked = event.currentTarget; var parent = clicked.parentElement; var total = parent.children.length; var selectedIndex = -1; for(var i=0; i<total; i++) { if(clicked === parent.children.item(i)) { selectedIndex = i; } $A.util.removeClass(parent.children.item(i), "selected"); } $A.util.addClass(clicked, "selected"); var selectedTh = cmp.get("v.items")[selectedIndex]; return selectedTh; }, getPayload: function(item) { return item; }, getTitle: function(item) { return item.title; }, getDescription: function(item) { return item.caseNo; } })
The important thing is to make sure that a user-click triggers the aura event lightning:sendChatterExtensionPayload in the controller code. In Capricorn’s code sample, the team set up the event in the selected function. Setting the event in the selected function sends the payload to associate with the feed item when the user makes a selection.
The team sets the extensionTitle and extensionDescription metadata using helper functions to associate with the payload. This metadata is for non-Lightning use cases, like email notifications or Classic view. Optionally, you can also add a thumbnail URL.
Here is a modal with a title and thumbnails.
The Rich Publisher Apps platform also provides the Add and Cancel buttons. In the previous image, the Add button is disabled. The Add button is enabled only after the lightning:sendChatterExtensionPayload event is fired with a non-empty payload. Notice in the previous image that no case is selected, and in the next image a case is selected. If the event is fired with an empty payload, then the button stays disabled.
B. Create the Second Lightning Component
Next, the Capricorn team creates a Lightning component that extends the Lightning interface lightning:availableForChatterExtensionRenderer. This interface renders the selected payload in the publisher when the FeedItem is rendered. There are two essential attributes as part of this interface: variant and payload. The variant attribute lets you decide how to render something based on whether the selected app is previewed in the publisher or rendered in the FeedItem. The payload attribute is the JavaScript Object that the user selected in the composition component.
<aura:component implements="lightning:availableForChatterExtensionRenderer"> <div class="container"> <a target="_blank" href="{!v.payload.url}"> <div class="{! (v.variant == 'FEED' ? 'itemContainerBorder' : '') + ' itemContainer'}"> <div class="itemLeft"> <img class="itemIcon" src="{!v.payload.icon}"></img> </div> <div class="itemRight"> <div class="itemTitle">{!v.payload.title}</div> <div class="itemSubtitle">{!v.payload.subtitle}</div> <div class="itemDescription">Case Number: {!v.payload.caseNo}</div> </div> </div> </a> </div> </aura:component>
Capricorn uses the variant FEED to decide which CSS class to use. The use of FEED signals the rendering of the Rich Publisher App in a FeedItem. To render the app in the publisher, use the variant PREVIEW. The payload information shows which case to render. In this example, the payload is static. But you can also use server-side Apex controllers to get live, dynamic information inside your renderer component.
Here’s how the payload looks as a preview inside the publisher (PREVIEW):
Here’s how the payload looks in the final rendered feed item (FEED):
Step 3. Create a Rich Publisher App in Workbench
Now that you’ve created the Lightning components and grabbed the fileAsset ID, you’re ready to create the Rich Publisher App in Workbench.
Go to Workbench, and insert a ChatterExtension object (Workbench > Data > Insert > ChatterExtension). Then associate all your component values with ChatterExtension fields.
- Provide the Lightning component ID for the composition component.
- Add text for the modal header.
- Add hover text for the app icon (the icon that appears in the feed publisher).
- Provide the fileAsset ID for the app icon.
- Provide the Lightning component ID for the render component.
- For Type enter Lightning. Currently, Lightning is the only type available.
Step 4. Enable Rich Publisher Apps in Your Experience Cloud Site
When everything’s ready to go, the Capricorn team adds the app to the feed publisher in their site. You can add up to five Rich Publisher Apps to your site through the Administration Workspace in Experience Workspaces.
- Go to Experience Workspaces, and click the Administration tile.
- In the navigation column, click Rich Publisher Apps.
- Select up to five apps from the Available Apps column, and move them to the Selected Apps column.
- To set the order of icons in the publisher, move selected apps up or down the list.
- Click Save.
Resources
- Upload and Share Files
- Enable and Disable the Translation Workbench
- Translate Terms
- Asset File
- ChatterExtension
- lightning:availableForChatterExtensionComposer
- lightning:availableForChatterExtensionRenderer
- lightning:sendChatterExtensionPayload
- Calling a Server-Side Action
- Apex Server-Side Controller Overview
- Creating an Apex Server-Side Controller