📢 Attention Salesforce Certified Trailblazers! Maintain your credentials and link your Trailhead and Webassessor accounts by April 19th. Learn more.

Extend the Possibilities with Apex Triggers

Learning Objectives

After completing this unit, you’ll be able to:
  • Name a use case for using triggers with Rich Publisher Apps.
  • Build an intelligent Rich Publisher App using triggers.
  • Describe the Rich Publisher Apps API.

Use Your Apex Trigger Skills

Not only can you set up click-to-add Rich Publisher Apps, you can also set up apps that intelligently predict the information a member needs. For example, your app can respond to a member post with useful data or a Rich Publisher App selection. Members don’t click an app icon. Instead, Salesforce automatically includes a relevant Rich Publisher App in the member’s post.

You can achieve this using the power of Apex triggers for Chatter objects. With Apex triggers, you get the ability to set up custom actions before or after changes to Salesforce records—changes like inserts, updates, or deletes. You can add an after insert FeedItem trigger to listen to the content of a member’s post and intelligently insert a Rich Publisher App. For example, you can also add triggers that update your app in response to changes to other objects, like comments or answers.

Let’s see an after insert trigger in action.

Dreamforce Dreams

Imagine that you’re at Dreamforce, and you’re looking for some cool sessions. You enter the question in your community, Looking for some DF sessions. You add the detail, Looking for some cool DF sessions, with the hashtag, #lookingForSessions.

Question with detail and a topic in the Chatter publisher

You click Ask, and Salesforce automatically includes a Rich Publisher App—a map of the Dreamforce campus—with your published post.

Google Map attached to a post through an after-insert trigger

What did we do here? To get this result, you create two things.

  • A Rich Publisher App for attaching a map to a feed item based on some context
  • A trigger to auto-insert the app

Dream Maps

First, create a Rich Publisher App similar to the support case app in Unit 2, but this time using the Google Maps API.

Rather than clicking an icon, a user triggers our map app by entering a specific topic in the feed. But the Rich Publisher App platform requires an icon, so what do you do? In this case, you can add a blank image for the icon and an empty composition component.

Alternatively, you can create a regular click-to-add app and add the after insert trigger as an add-on experience.

Here’s one way to write a basic trigger for FeedItem.

trigger dreamforceMapInsertion on FeedItem (after insert) {
  // This is where we look for content in the post or topics. Based on our result, we can insert
  // a Rich Publisher App. Alternatively, we can continue adding a Rich Publisher App for each
  // post without the filtering. 
  // Get FeedItem Id & the body.
  String id = null;
  String body = “”;
  for(FeedItem f : Trigger.new) {
       id = f.id;
       body = f.body;
  if (id == null && !f.body.contains('#lookingForSessions’)) {
  String communityId = Network.getNetworkId();
  String feedElementId = id;
  ConnectApi.FeedEntityIsEditable isEditable = 
    ConnectApi.ChatterFeeds.isFeedElementEditableByMe(communityId, feedElementId);
  // Make sure the post is user-editable before inserting the Rich Publisher App.
  if (isEditable.isEditableByMe == true) {

        // This is the setup for Rich Publisher App insertion. 
        ConnectApi.FeedItemInput feedItemInput = new ConnectApi.FeedItemInput();
        ConnectApi.FeedElementCapabilitiesInput feedElementCapabilitiesInput = 
          new ConnectApi.FeedElementCapabilitiesInput();
        feedItemInput.capabilities = feedElementCapabilitiesInput;
        feedItemInput.capabilities.extensions = new ConnectApi.ExtensionsCapabilityInput();
        feedItemInput.capabilities.extensions.itemsToAdd = new List<ConnectApi.ExtensionInput>();
        ConnectApi.ExtensionInput ext = new ConnectApi.ExtensionInput();
        // This is the id for your Rich Publisher App.     
        ext.extensionId = '<Insert your extensionId>'; // This would be something you get from 
          //Workbench which is the id for extension entity for example ‘0MYB00000001234567’
        // This is the payload associated with this instance of the app.
        ext.payload = '<Insert your payload>'; // This would be your JSON blob for example: 
        // This can change if you want to use multiple payload versions with different versions of
        // your app. Or you can just use 1 version. This is Optional.                	
        ext.payloadVersion = '<Insert your payloadVersion>'; // This can be anything like ‘1.0’

        // The following fields add metadata to your Rich Publisher App.
        // This is similar to our actions in Unit 2 when we added metadata to the lightning event.
	 alt.textRepresentation = '<Insert your text representation here>'; 
	 ConnectApi.AlternativeInput alt = new ConnectApi.AlternativeInput();
        ext.alternativeRepresentation = alt;
        // Add a Rich Publisher App to FeedItem capabilities.
        // Here you can add multiple Rich Publisher App instances in the itemsToAdd Array.
        // Finally, edit the FeedItem to insert the Rich Publisher App.
        ConnectApi.FeedElement editedFeedElement = 
          ConnectApi.ChatterFeeds.updateFeedElement(communityId, feedElementId, feedItemInput);

In our code sample, we covered many concepts about how to write an after insert FeedItem trigger and how to work with the Rich Publisher Apps API.

To add a Rich Publisher App instance to your feed item, the platform edits the FeedItem just after it’s created in the after insert trigger. Then it inserts the Rich Publisher App instance as part of the FeedItem representation in the trigger. You can do filtering before doing the edit to determine whether you want to do the insertion.

In our example, the trigger looks for the #lookingForSessions topic in the feed body. Then it passes in the payload to provide context to the Rich Publisher App. With context, the Rich Publisher App knows to display the map for the Dreamforce campus. You can do various things to get context from the post body or its attachments. When you have context, you can pass it as payload to the Rich Publisher App so it can render something in response. You can also make requests to third-party services. For example, you can make a request to access machine learning resources or other intelligent APIs. These agents can provide a smart response in your Rich Publisher Apps.

Chatter Extension

In all our public APIs, the Rich Publisher Apps API is referred to as ChatterExtension. You can create Chatter Extensions only using the SOAP API through Workbench. But you can fetch it using Chatter Extension Connect API (or ConnectAPI in Apex). When you create a Rich Publisher App, you basically create a ChatterExtension object, as we covered in Unit 2, Step 3. Salesforce inserts Rich Publisher Apps as attachments to feed items, similar to attaching a file. That’s why you use Extensions Capability Input (or ConnectAPI in Apex) to insert a Rich Publisher instance with a feed item.

Let’s return to our example. Someone sees your question, and responds with, How to build Rich Publisher Apps at Moscone North.

The updated Google Map

Instantly, the map updates with a pin on the Moscone North location.

Another answer recommends a session at the Intercontinental hotel. The map updates again, this time with a pin in the hotel’s location.

The updated Google Map

Here, along with the FeedItem trigger, we have a FeedComment trigger that’s listening to the comments. After a member inserts a comment, your app matches the comment’s content body with the list of Dreamforce sessions. Then the trigger edits the FeedItem to update the payload with a pin on the mentioned spot. Alternatively, you can have your Rich Publisher App listen to an external third-party service for the list of locations to pin. In this case, your FeedComment trigger can update that third-party service instead of editing the FeedItem. This way you get the dynamic experience of pins updating on the map.