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: