Automating Chatter Polls with Apex


Salesforce Chatter is a powerful collaboration platform that enables users to connect, communicate, and share information efficiently. Its features include posting to record feeds, collaborating in Chatter groups, organizing conversations with topics and tags, sharing documents, and directly engaging team members through mentions. One often underutilized feature of Chatter is the ability to create polls.

Most of the organizations I worked in uses the "Post" functionality in Chatter. In this blog, we will be talking about the "Poll" functionality, and how to automate Chatter polls using Apex. Automating polls can help businesses gather feedback, opinions, or decisions on a recurring basis without manual intervention.

Benefits of Automating Monthly Chatter Polls

Automating Chatter polls using Apex can save time and enhance engagement across your organization. With scheduled polls, teams can easily gather feedback or make decisions without the hassle of manual setup. This ensures consistency, fosters collaboration, and makes it easier to scale the process for multiple groups or topics.
  • Consistency: No manual effort needed to remember and post polls on recurring date.
  • Engagement: Regular polls keep employees engaged and involved in decision-making.
  • Transparency: Sharing results fosters a collaborative and open culture.
  • Scalability: Easily adapt the solution to handle multiple teams, groups, or questions.

Use Case: Automating Training Session Selection with Monthly Chatter Polls

Imagine a company organizing monthly training sessions for employees. To decide on the next month’s topic, a poll is conducted in the “Learning and Development” Chatter group with the question: “Which training session do you want to attend next month?”

Poll options could include topics like “Automation with Salesforce Flows” or “Leadership and Management Skills.” The poll will be automatically created at the end of each month, and after one week, it will close. The option with the highest votes is declared the winner, and the results are posted to the group.

Solution Overview

To implement this automation, the following components are required:
1. A Schedulable Apex class that runs at the end of each month to create a poll in a Chatter group.
2. A custom object called Poll Tracker which will capture the Poll ID, Chatter Group ID, and Created Date.
3. Another Schedulable Apex that queries open polls, tallies responses, and posts the results after one week.

Poll Creation Scheduled Apex:

The MonthlyPollScheduler class helps automate the process of posting polls in Chatter groups at the end of each month. It defines the poll question and choices, creates the poll, and posts it directly to the specified group. Additionally, it keeps track of each poll by saving important details, like the poll ID and creation date, in a custom object. This ensures the poll is ready for follow-up actions, such as announcing the results.

global class MonthlyPollScheduler implements Schedulable {
    public void execute(SchedulableContext sc) {
        String groupId = '0F9d50000001D85CAE'; //ID of the Chatter group

        // Define the poll question
        String pollQuestion = 'Which training session do you want to attend next month?';

        // Define the poll choices
        List<String> pollChoices = new List<String>{
            'Automation with Salesforce Flows',
            'Advanced Data Analysis with Tableau',
            'Leadership and Management Skills',
            'Introduction to Salesforce OmniStudio',
            'Deep Dive into Salesforce Marketing Cloud',
            'Maximizing Efficiency with Agentforce'
        };

        try {
            // Create PollCapabilityInput to hold poll options
            ConnectApi.PollCapabilityInput myPoll = new ConnectApi.PollCapabilityInput();
            myPoll.choices = pollChoices; // Add poll choices to the input object

            // Define feed element capabilities and include the poll
            ConnectApi.FeedElementCapabilitiesInput itemCapabilities = new ConnectApi.FeedElementCapabilitiesInput();
            itemCapabilities.poll = myPoll; // Attach the poll capability to the feed element

            // Define the feed item to post the poll
            ConnectApi.FeedItemInput feedItem = new ConnectApi.FeedItemInput();
            feedItem.feedElementType = ConnectApi.FeedElementType.FeedItem; // Specify feed element type
            feedItem.capabilities = itemCapabilities; // Attach capabilities to the feed item
            feedItem.subjectId = groupId; // Set the Chatter group as the target

            // Create the message body for the poll post
            ConnectApi.MessageBodyInput messageBodyInput = new ConnectApi.MessageBodyInput();
            messageBodyInput.messageSegments = new List<ConnectApi.MessageSegmentInput>();

            // Add the poll question as a text segment
            ConnectApi.TextSegmentInput textSegment = new ConnectApi.TextSegmentInput();
            textSegment.text = pollQuestion;
            messageBodyInput.messageSegments.add(textSegment);

            feedItem.body = messageBodyInput; // Attach the message body to the feed item

            // Post the poll to the Chatter group
            ConnectApi.FeedElement feedElement = ConnectApi.ChatterFeeds.postFeedElement(null, feedItem);

            // Save Poll ID and Creation Date in the PollTracker custom object for tracking
            Poll_Tracker__c tracker = new Poll_Tracker__c(
                Poll_Id__c = feedElement.id, // Store the Feed Element ID
                Group_Id__c = groupId, // Store the Chatter group ID
                Created_Date__c = System.now() // Store the creation date
            );
            insert tracker;

        } catch (Exception ex) {
            System.debug('Error while creating poll: ' + ex.getMessage());
        }
    }
}

The output will be the creation of a poll on the Chatter group:



Poll Closure Scheduled Apex:

The PollClosureScheduler class manages polls created a week earlier by closing them and sharing the results. It identifies the winning choice based on the highest votes and posts a message in the Chatter group to announce the outcome. This process ensures that polls are concluded on time and participants are informed about the results, promoting transparency and collaboration.

global class PollClosureScheduler implements Schedulable {
    public void execute(SchedulableContext sc) {
        // Query PollTracker records for polls created a week ago
        List<Poll_Tracker__c> trackers = [
            SELECT Poll_Id__c, Group_Id__c
            FROM Poll_Tracker__c
            WHERE Created_Date__c <= LAST_N_DAYS:7
        ];
        
        // Iterate through the list of trackers to process each poll
        for (Poll_Tracker__c tracker : trackers) {
            try {
                // Retrieve the feed element containing the poll using its Poll_Id__c
                ConnectApi.FeedElement feedElement = ConnectApi.ChatterFeeds.getFeedElement(null, tracker.Poll_Id__c);
                
                // Access the PollCapability of the feed element, which contains poll details
                ConnectApi.PollCapability pollCapability = (ConnectApi.PollCapability) feedElement.capabilities.poll;
                
                // Check if PollCapability exists and has choices to process
                if (pollCapability != null && !pollCapability.choices.isEmpty()) {
                    // Determine the choice with the highest vote
                    ConnectApi.FeedPollChoice highestChoice = null;
                    for (ConnectApi.FeedPollChoice choice : pollCapability.choices) {
                        // Update highestChoice if the current choice has more votes
                        if (highestChoice == null || choice.voteCount > highestChoice.voteCount) {
                            highestChoice = choice;
                        }
                    }
                    
                    // Create the closure message with the highest-voted choice
                    String closureMessage = 'This poll is now closed. Thank you for participating!\n\n';
                    closureMessage += 'The winning choice is: ' + highestChoice.text + ' with ' + highestChoice.voteCount + ' votes.\n';
                    
                    // Prepare to post the closure message to the Chatter group
                    ConnectApi.FeedItemInput feedItemInput = new ConnectApi.FeedItemInput();
                    
                    // Create a message body for the feed post
                    ConnectApi.MessageBodyInput messageBodyInput = new ConnectApi.MessageBodyInput();   
                    messageBodyInput.messageSegments = new List<ConnectApi.MessageSegmentInput>();
                    
                    // Add the closure message as a text segment
                    ConnectApi.TextSegmentInput textSegmentInput = new ConnectApi.TextSegmentInput();
                    textSegmentInput.text = closureMessage;
                    messageBodyInput.messageSegments.add(textSegmentInput);
                    
                    // Assign the message body to the feed item
                    feedItemInput.body = messageBodyInput;
                    feedItemInput.feedElementType = ConnectApi.FeedElementType.FeedItem; // Set feed element type
                    feedItemInput.subjectId = tracker.Group_Id__c; // Post to the Chatter group identified by Group_Id__c
                    feedItemInput.visibility = ConnectApi.FeedItemVisibilityType.AllUsers; // Make the post visible to all users
                    
                    // Post the feed item to the Chatter group
                    ConnectApi.FeedElement newFeedElement = ConnectApi.ChatterFeeds.postFeedElement(null, feedItemInput);
                    
                    System.debug('Poll results posted successfully for poll: ' + tracker.Poll_Id__c);
                } else {
                    System.debug('No PollCapability found or no choices available for poll: ' + tracker.Poll_Id__c);
                }
            } catch (Exception ex) {
                System.debug('Error processing poll: ' + ex.getMessage());
            }
        }
    }
}

The output will be the generation of a Chatter post showing the result:


Conclusion

Automating Chatter polls with Apex is a practical way to streamline feedback collection and enhance collaboration in Salesforce. By leveraging scheduled Apex and the ConnectApi class, you can create scalable, repeatable processes for gathering team insights and sharing results effectively.


Post a Comment

0 Comments