How to call ChatGPT using Salesforce Apex and display in Lightning Web Component?

How to call ChatGPT using Salesforce Apex and display in Lightning Web Component?

We can use Salesforce Apex to make callout to OpenAI. Apex makes the callout more secured instead of doing the Callout from the Lightning Web Component JavaScript. We can display the response from the ChatGPT using the Lightning Web Component.

In the following example, I have passed Case Subject as the prompt.

Remote Site Settings:

Sample Code:

Apex Class:

public class AICaseSuggestionsController {
    
    @AuraEnabled( cacheable = true )
    public static OpenAPIResultWrapper callOpenAI( String strPrompt ) {
        
        String strEndpoint = 'https://api.openai.com/v1/completions';
        HTTP h = new HTTP();
        HTTPRequest req = new HTTPRequest();
        req.setEndPoint( 
            strEndpoint 
        );
        req.setMethod( 
            'POST' 
        );
        req.setHeader( 
            'Content-Type', 
            'application/json' 
        );
        req.setHeader( 
            'Authorization', 
            'Bearer <OpenAPIToken>' 
        );        
        req.setBody( 
            '{ "model" : "text-davinci-003", '+
            '"prompt" : "' +
            strPrompt + '", "n" : 3 }' 
        );
        HTTPResponse response = h.send(
            req
        );
        System.debug( 
            'Response is ' + 
            response.getBody() 
        );
        return ( OpenAPIResultWrapper )System.JSON.deserialize( 
            response.getBody(), 
            OpenAPIResultWrapper.class 
        );
        
    }
    
    public class ChoiceWrapper {
        
        @AuraEnabled public String text;
       
    }
    
    public class OpenAPIResultWrapper {
        
        @AuraEnabled public String created;
        @AuraEnabled public String model;
        @AuraEnabled public List < ChoiceWrapper > choices;
        
    }
    
}

Lightning Web Component:

HTML:

<template>
    <lightning-card 
        title="AI Case Suggestions" 
        icon-name="standard:einstein_replies">
        <div class="slds-var-p-around_small slds-text-color_success slds-text-align_center">
            Prompt is {strCaseSubject}
        </div>
        <div class="slds-var-p-around_small">
            <lightning-datatable 
                key-field="Id" 
                data={suggestions} 
                columns={columns} 
                hide-checkbox-column 
                show-row-number-column
                wrap-text-max-lines="3"> 
                </lightning-datatable>   
        </div>
    </lightning-card>
</template>

JavaScript:

import { LightningElement, api, wire } from 'lwc';
import { getRecord } from 'lightning/uiRecordApi';
const FIELDS = [ 'Case.Subject' ];
import caseSuggestions from '@salesforce/apex/AICaseSuggestionsController.callOpenAI';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';

export default class AICaseSuggestions extends LightningElement {

    @api recordId;
    strCaseSubject;
    suggestions;
    columns = [  
        { 
            label: 'Suggestion', 
            fieldName: 'text', 
            wrapText: true 
        }, 
    ];  

    @wire( getRecord, { recordId: '$recordId', fields: FIELDS } )
    wiredRecord({ error, data }) {

        if ( error ) {

            console.log( 'Inside error block' );
            let message = 'Unknown error';

            if ( Array.isArray( error.body ) ) {

                message = error.body.map(e => e.message).join(', ');

            } else if ( typeof error.body.message === 'string' ) {

                message = error.body.message;

            }

            this.dispatchEvent(
                new ShowToastEvent( {
                    title: 'Some error occurred',
                    message,
                    variant: 'error',
                } ),
            );

        } else if ( data ) {

            console.log( 
                'Subject Value is', 
                JSON.stringify( data.fields.Subject.value ) 
            );
            this.strCaseSubject = data.fields.Subject.value;

        }

    }

    @wire( caseSuggestions, { strPrompt: '$strCaseSubject'} )  
    wiredCallAPI( { error, data } ) {

        if ( data ) {

            console.log(
                'Data received is', 
                data
            );
            this.suggestions = JSON.parse(
                JSON.stringify( 
                    data.choices 
                ).replace( /\\n/g, '' )
            );

        } else if ( error ) {

            console.log( 
                JSON.stringify( error ) 
            );
            
        }

    }

}

js-meta.xml:

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

Output:

Leave a Reply