Display Salesforce Conversation Entries in Tabular Format

Display Salesforce Conversation Entries in Tabular Format

In this Blog Post, Conversation Entries retrieval is for enhanced messaging channels and not for the standard messaging channels.

To display Salesforce Conversation Entries in Tabular Format, we can make use of Connect REST API to get the Conversation Entries for the Messaging Session record.

Steps:

1. Create a Connected App. In the Callback URL, use a temporary URL. The temporary URL should be updated later after completing the Step 2. Get the Callback URL from the Auth. Provider and update it.

2. Create an Auth. Provider.

Don’t forget to update the Callback URL in the connected app.

3. Create a Named Credential.

Sample Code:

Apex Controller:

public class FetchConversationEntriesController {
    
    @AuraEnabled( cacheable = true )
    public static List < ConversationEntryWrapper > fetchEntries( String strMessagingSessionId ) {
        
        List < ConversationEntryWrapper > listEntries = 
            new List < ConversationEntryWrapper >();
        
        // Fetching Messaging Session record
        MessagingSession objMS = [
            SELECT Conversation.ConversationIdentifier, ConversationId
            FROM MessagingSession
            WHERE Id =: strMessagingSessionId
        ];
        System.debug(
            'ConversationIdentifier is ' + 
            objMS.Conversation.ConversationIdentifier
        );
        
        // GET Request to Connect API
        Http h = new Http();  
        HttpRequest req = new HttpRequest();  
        req.setEndpoint( 
            'callout:Fetch_Conversation_Entries' + 
            '/services/data/v60.0/connect/conversation/' + 
            objMS.Conversation.ConversationIdentifier + 
            '/entries?queryDirection=FromStart' 
        );  
        req.setMethod( 'GET' );  
        HttpResponse res = h.send(req);  
        system.debug( 
            'Conversation Entries are ' + res.getBody() 
        );  
        
        Map < String, Object > jsonMap = 
            ( Map < String, Object > )JSON.deserializeUntyped( res.getBody() );
        
        List < Object > conversationEntries = ( List < Object > ) jsonMap.get( 'conversationEntries' );
        
        for ( Object objEntry : conversationEntries ) {
            
            Map < String, Object > entryMap = ( Map < String, Object > ) objEntry;
            
            ConversationEntryWrapper objWrap = new ConversationEntryWrapper();
            objWrap.identifier = ( String ) entryMap.get( 'identifier' );
            objWrap.messageText = ( String ) entryMap.get( 'messageText' );
            objWrap.clientDuration = ( Long ) entryMap.get( 'clientDuration' );
            objWrap.clientTimestamp = ( Long ) entryMap.get( 'clientTimestamp' );
            objWrap.serverReceivedTimestamp = ( Long ) entryMap.get( 'serverReceivedTimestamp' );
            Map < String, Object > senderMap = ( Map < String, Object > ) entryMap.get( 'sender' );
            System.debug( 'senderMap is ' + senderMap );
            objWrap.role = ( String ) senderMap.get( 'role' );
            objWrap.appType = ( String ) senderMap.get( 'appType' );
            objWrap.subject = ( String ) senderMap.get( 'subject' );
            listEntries.add( objWrap );
            System.debug( objWrap );
            
        }
        
        return listEntries;
        
    }
    
    public class ConversationEntryWrapper {
            
        @AuraEnabled
        public String role;
        @AuraEnabled
        public String appType;
        @AuraEnabled
        public String subject;
        @AuraEnabled
        public String identifier;
        @AuraEnabled
        public String messageText;
        @AuraEnabled
        public Long clientDuration;
        @AuraEnabled
        public Long clientTimestamp;
        @AuraEnabled
        public Long serverReceivedTimestamp;
        
    }
    
}

Lightning Web Component:

HTML:

<template>
    <div> 
        <lightning-datatable 
            key-field="identifier"
            data={entries}
            columns={columns}
            hide-checkbox-column="true" 
            show-row-number-column="true">
        </lightning-datatable>
    </div>  
</template>

JavaScript:

import { LightningElement, wire, api } from 'lwc';
import fetchEntries from '@salesforce/apex/FetchConversationEntriesController.fetchEntries';

export default class FetchConversationEntries extends LightningElement {
    
    @api recordId;
    entries;

    columns = [ 
        { label: 'Role', fieldName: 'role' },
        { label: 'Message Text', fieldName: 'messageText' },
        { label: 'Server Received Date Time', fieldName: 'serverReceivedTimestamp' }
    ];

    @wire( fetchEntries, { strMessagingSessionId: '$recordId' } )
    entries( { error, data } ) {

        if ( data ) {
           
            console.log( 'data => ', JSON.stringify( data ) );
            const dtOptions = {
                year: 'numeric', month: 'numeric', day: 'numeric',
                hour: 'numeric', minute: 'numeric', second: 'numeric',
                hour12: false
            };

            this.entries = data.map( entry => {
                console.log( 'entry => ', JSON.stringify( entry ) );
                console.log( 'entry.serverReceivedTimestamp => ', entry.serverReceivedTimestamp );
                return {
                    role: entry.role,
                    messageText: entry.messageText,
                    identifier: entry.identifier,
                    serverReceivedTimestamp: new Date( entry.serverReceivedTimestamp ).toLocaleString( 'en-US', dtOptions )
                };
            } );

            console.log( 'this.entries => ', JSON.stringify( this.entries ) );

        } else if ( error ) {

            console.error( 'Some Error occurred', JSON.stringify( error ) );

        }
   
   
    };

}

js-meta.xml:

<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>63.0</apiVersion>
    <isExposed>true</isExposed> 
    <targets> 
        <target>lightning__RecordPage</target> 
    </targets> 
</LightningComponentBundle>

Output:

For the standard messaging channels, you can directly query the Salesforce ConversationEntry object/entity.

Leave a Reply