Site icon Salesforce Diaries

Agentforce Models AI API: Posting Chatter with Apex

In this article, we’ll explore how to use the Agentforce Models AI API to automatically generate and post Chatter messages when a Salesforce Case status changes. Leveraging Apex @future methods and OpenAI-powered prompts, we offload the writing to AI—so agents can focus on solving problems, not posting updates.

Let’s walk through a practical and scalable use case: Automatically generating Chatter posts when a Case transitions to “Working” using the Agentforce AI Models API.

🧠 The Idea

Every time a support Case enters the “Working” status, we want to notify internal stakeholders with a professionally written Chatter message. Instead of hardcoding a message, we’ll let AI craft a natural, contextual update—tailored to each Case.

💡 Design Overview

This solution uses:

⚙️ How It Works

1. Trigger Fires

The CaseTrigger invokes the CaseTriggerHandler on insert and update.

trigger CaseTrigger on Case (after insert, after update) {
    if (Trigger.isAfter && (Trigger.isInsert || Trigger.isUpdate)) {
        CaseTriggerHandler.handleAfterInsertOrUpdate(Trigger.new, Trigger.oldMap);
    }
}

2. Business Logic in Handler

We detect when a Case changes status to “Working” and queue it for Chatter posting.

public class CaseTriggerHandler {

    public static void handleAfterInsertOrUpdate(List<Case> newCases, Map<Id, Case> oldMap) {
        if (newCases == null || newCases.isEmpty()) {
            return;
        }

        List<Id> toChatter = new List<Id>();

        for (Case newCase : newCases) {
            if (newCase == null || String.isBlank(newCase.Status)) {
                continue;
            }

            Case oldCase = oldMap != null ? oldMap.get(newCase.Id) : null;
            String oldStatus = oldCase != null ? oldCase.Status : null;

            // Check for transition to 'Working'
            if (oldStatus != 'Working' && newCase.Status == 'Working') {
                toChatter.add(newCase.Id);
            }
        }

        // Trigger async actions
        for (Id caseId : toChatter) {
            CaseChatterAIService.postChatterOnCaseCloseAsync(caseId);
        }
    }
}

3. AI Generates Message Asynchronously

The core of this approach is CaseChatterAIService, which builds a prompt and sends it to the AI model.

public class CaseChatterAIService {

    private static final String MODEL_NAME = 'sfdc_ai__DefaultOpenAIGPT4OmniMini';
    private static final String PROMPT_TEMPLATE = 
        'Generate a positive and professional Chatter message announcing that Case #%s titled "%s" has been handled by the agent. ' +
        'Here are the relevant details:\n%s';

    @future(callout = true)
    public static void postChatterOnCaseCloseAsync(Id caseId) {
        if (caseId == null) {
            return;
        }

        try {
            Case caseRecord = [
                SELECT Id, CaseNumber, Subject, Status, Priority, Owner.Name 
                FROM Case 
                WHERE Id = :caseId 
                LIMIT 1
            ];

            String caseDetails = String.format(
                'Case Number: {0}\nSubject: {1}\nStatus: {2}\nPriority: {3}\nOwner: {4}', 
                new List<String>{
                    String.valueOf(caseRecord.CaseNumber),
                    String.valueOf(caseRecord.Subject),
                    String.valueOf(caseRecord.Status),
                    String.valueOf(caseRecord.Priority),
                    String.valueOf(caseRecord.Owner.Name)
                }
            );

            String prompt = String.format(
                PROMPT_TEMPLATE,
                new List<String>{
                    String.valueOf(caseRecord.CaseNumber),
                    String.valueOf(caseRecord.Subject),
                    caseDetails
                }
            );

            aiplatform.ModelsAPI modelsAPI = new aiplatform.ModelsAPI();

            aiplatform.ModelsAPI.createGenerations_Request request = 
                new aiplatform.ModelsAPI.createGenerations_Request();
            request.modelName = MODEL_NAME;

            aiplatform.ModelsAPI_GenerationRequest requestBody = 
                new aiplatform.ModelsAPI_GenerationRequest();
            requestBody.prompt = prompt;
            request.body = requestBody;

            aiplatform.ModelsAPI.createGenerations_Response response = modelsAPI.createGenerations(request);

            String chatterMessage = (response != null && response.Code200 != null)
                ? response.Code200.generation.generatedText
                : null;

            if (String.isNotBlank(chatterMessage)) {
                FeedItem post = new FeedItem();
                post.ParentId = caseRecord.Id;
                post.Body = chatterMessage;
                insert post;
            }

        } catch (QueryException qe) {
            System.debug(LoggingLevel.ERROR, 'Query failed for Case Id: ' + caseId + ' => ' + qe.getMessage());
        } catch (aiplatform.ModelsAPI.createGenerations_ResponseException ae) {
            System.debug(LoggingLevel.ERROR, 'AI API error for Case Id: ' + caseId + ' => ' + ae.getMessage());
        } catch (DmlException de) {
            System.debug(LoggingLevel.ERROR, 'DML error while posting to Chatter for Case Id: ' + caseId + ' => ' + de.getMessage());
        } catch (Exception e) {
            System.debug(LoggingLevel.ERROR, 'Unexpected error for Case Id: ' + caseId + ' => ' + e.getMessage());
        }
    }
}

Key Benefits

⚠️ Gotchas and Best Practices

🔚 Final Thoughts

With Agentforce Models AI API, Chatter becomes more than a collaboration tool—it becomes a canvas for real-time, intelligent communication. This is Apex infused with AI, native to the Salesforce Platform, and built for scale.

Agentforce is here—and Chatter just got a lot smarter.

Demo: Agentforce Models AI API: Posting Chatter with Apex

Do you need help?

Are you stuck while working on this requirement? Do you want to get review of your solution? Now, you can book dedicated 1:1 with me on Lightning Web Component and Agentforce completely free.

GET IN TOUCH

Schedule a 1:1 Meeting with me

Exit mobile version