Thursday, September 19, 2013

Chatter in Apex: Posting custom Chatter FeedItems more easily

One of the first challenges I set out to tackle was to simplify the process of inserting a Chatter FeedItem.  My team had already built two use-cases for posting an automated message into a Chatter feed, but each time we needed to modify the process of those use-cases, the FeedItem posting code was getting in the way.

My goal: Create a helper utility to simplify the process

It was simple enough to deconstruct and normalize the code since there were some very obvious overlaps: Adding a TextSegment, adding a MentionSegment, etc.  At this time, those are the only two I've tackled, but I plan to continue to build this out and will post an update when it makes sense.

This makes it very easy to post a message into Chatter.  As an example, if I wanted to post a message to a record that started with an @mention to someone, then had a text body, followed by a list of CC worthy @mentions, it would look roughly like:

postChatterFeedItem(ConnectApi.FeedType.Record, recordId, userId, textBody, List<userId>);

1. Create a new Apex Class (Setup > Develop > Apex Classes > New) and paste the following code:

global class UtilsChatter {
    
    //** Turn an input String into a useful TextSegmentInput
    global static void postChatterFeedItem(ConnectApi.FeedType FeedType, Id SubjectID, ConnectApi.FeedItemInput Input) {
        ConnectApi.ChatterFeeds.postFeedItem(null, FeedType, SubjectID, Input, null);
    }
    
    //** Turn an input String into a useful TextSegmentInput
    global static ConnectApi.TextSegmentInput addTextSegment(String thisString) {
        ConnectApi.TextSegmentInput textSegment = new ConnectApi.TextSegmentInput();
        textSegment.text = thisString;
        return textSegment;
    }
    
    //** Turn an input Id into a useful MentionSegmentInput
    global static ConnectApi.MentionSegmentInput addMentionSegment(Id thisId) {
        ConnectApi.MentionSegmentInput mentionSegment = new ConnectApi.MentionSegmentInput();
        mentionSegment.id = thisId;
        return mentionSegment;
    }
    
    //** Create and post a message to Chatter (Text)
    global static void postChatterFeedItem(ConnectApi.FeedType FeedType, Id SubjectId, String TextString1) {
        //** Combine the needed messageSegments into one coherent messageInput
        ConnectApi.MessageBodyInput messageInput = new ConnectApi.MessageBodyInput();
        messageInput.messageSegments = new List<ConnectApi.MessageSegmentInput>();
        messageInput.messageSegments.add(addTextSegment(TextString1));
        //** Attach the messageInput as the Input.body
        ConnectApi.FeedItemInput Input = new ConnectApi.FeedItemInput();
        Input.body = messageInput;
        //** Post to Chatter
        postChatterFeedItem(FeedType, SubjectId, Input);
    }
    
    //** Create and post a message to Chatter (Mention)
    global static void postChatterFeedItem(ConnectApi.FeedType FeedType, Id SubjectId, Id UserId1) {
        //** Combine the needed messageSegments into one coherent messageInput
        ConnectApi.MessageBodyInput messageInput = new ConnectApi.MessageBodyInput();
        messageInput.messageSegments = new List<ConnectApi.MessageSegmentInput>();
        messageInput.messageSegments.add(addMentionSegment(UserId1));
        //** Attach the messageInput as the Input.body
        ConnectApi.FeedItemInput Input = new ConnectApi.FeedItemInput();
        Input.body = messageInput;
        //** Post to Chatter
        postChatterFeedItem(FeedType, SubjectId, Input);
    }
    
    //** Create and post a message to Chatter (Mention List)
    global static void postChatterFeedItem(ConnectApi.FeedType FeedType, Id SubjectId, List<Id> UserId1) {
        //** Combine the needed messageSegments into one coherent messageInput
        ConnectApi.MessageBodyInput messageInput = new ConnectApi.MessageBodyInput();
        messageInput.messageSegments = new List<ConnectApi.MessageSegmentInput>();
        for (Id i : UserId1) {
            messageInput.messageSegments.add(addMentionSegment(i));
        }
        //** Attach the messageInput as the Input.body
        ConnectApi.FeedItemInput Input = new ConnectApi.FeedItemInput();
        Input.body = messageInput;
        //** Post to Chatter
        postChatterFeedItem(FeedType, SubjectId, Input);
    }
    
}

A few notes:
  • I only posted the three headlining postChatterFeedItem methods above for simplicity, but these do not give much posting flexibility in and of themselves.  I have built out many more scenarios (e.g. Mention List + Text + Mention + Text + Mention List), let me know if you want the entire class (I'll send it offline so as not to clog up a post with the code).
  • I've only tackled MentionSegment and Text Segment (no support yet for Polls, Attachments, etc), but I plan to continue to build this out and will post an update when it makes sense.
Happy Coding!

4 comments :

  1. Congratulations, great job!

    José Luis Almazán
    Senior Salesforce Developer
    TicMind Consulting, Salesforce Consulting Partner

    ReplyDelete
  2. messageInput.messageSegments = new List(); generates an error : expecting a left angle bracket, found '('. Why So also next block of code are used in assigning but why this not

    ReplyDelete
    Replies
    1. Hi Preet, thanks for giving this a try. However, I'm not exactly sure your question as I think your copy/paste above of the code was corrupted a little... Could you try re-stating your question for me?

      Delete