Build a Custom RTE Plugin with ChatGPT for AEM

Helping AEM authors to complete ideas through ChatGPT

Victor Serrato
Globant
10 min readMay 16, 2023

--

Image generated by DALL·E for "helping authors to complete ideas using ChatGPT"

This article describes how AEM authoring tools can be improved with ChatGPT technology to help authors complete ideas quickly and efficiently when authoring text on AEM pages. To facilitate its use, this functionality was implemented through an RTE plugin that can be configured on any AEM component that utilizes the AEM Rich Text Editor (RTE).

The article can be divided into four parts. In the first part, we describe the ChatGPT RTE plugin functionality. In the second, we illustrate how to make requests to Open AI endpoints and configure and test those requests through the Postman platform. In the third, we demonstrate how to implement the ChatGPT RTE plugin and configure an existing component to use it. We last show how the ChatGPT RTE plugin completes some ideas using a couple of Open AI endpoints.

ChatGPT RTE plugin

The ChatGPT RTE plugin helps authors to complete ideas using ChatGPT technology through the OpenAI API endpoints. The plugin utilizes the Completions and the Chat Completions endpoints to implement two features available as buttons on the RTE toolbar.

To complete an idea using ChatGPT, the author must select a piece of text in the Rich Text Editor and click on any of the plugin toolbar buttons (see image below):

Selecting text to be completed using the ChatGPT RTE plugin.
  • The first one is the ChatGPT Completions button (draft icon) to make a request to the Completions endpoint.
  • The second is the ChatGPT Chat Completions button (chat icon) to make a request to the Chat Completions endpoint.

After the author clicks on any of the plugin buttons, the Rich Text Editor passes to the ChatGPT RTE plugin the text selected by the author and the command represented by the toolbar button. Then, the plugin uses those parameters to make a request to an OpenAI endpoint. Finally, the RTE plugin processes the endpoint response and replaces the author selection with the proposed completion (see the image below).

Displaying OpenAI endpoint result on the Rich Text Editor.

OpenAI endpoints

For our purpose, we explored two OpenAI API endpoints: Completions and Chat Completions. We selected those endpoints since each one supports a distinct set of models (see the Models section in the OpenAI API documentation to better understand the models listed below).

The Completions endpoint supports the old text models such as DaVinci or Curie. For this part, the Chat Completions endpoint supports the newer chat models, for instance: GPT-3.5 or GPT-4. The newer GPT models are cheaper than the text models but require a more extensive and complex input. According to the Chat completion guide "gpt-3.5-turbo performs at a similar capability to text-davinci-003 but at 10% the price per token". That is why the selected OpenAI endpoints return a pretty different answer for the same question (some questions and their answers are available on the Using the ChatGPT RTE plugin in the AEM section).

The OpenAI API reference defines the Completions endpoint as "Given a prompt, the model will return one or more predicted completions, and can also return the probabilities of alternative tokens at each position". This endpoint is compatible with text models such as: text-davinci-003, text-davinci-002, text-curie-001, text-babbage-001, and text-ada-001.

The Chat Completions endpoint is defined as "Given a list of messages describing a conversation, the model will return a response". It is compatible with GPT models, including: gpt-4, gpt-4-0314, gpt-4-32k,gpt-4-32k-0314, gpt-3.5-turbo, gpt-3.5-turbo–0301.

Those endpoints provide several parameters that can be used to tune the completion text process. For the ChatGPT RTE plugin, we used the parameters listed below (taken from OpenAI API reference):

  • model: ID of the model to use. On the OpenAI API, not all models can be used on all endpoints. You should review the model endpoint compatibility before setting this parameter.
  • max_tokens: The maximum number of tokens to generate in the chat completion.
  • temperature: What sampling temperature to use, between 0 and 2. Higher values like 0.8 will make the output more random, while lower values like 0.2 will make it more focused and deterministic.

In addition, requests to the Completions endpoint use the prompt parameter to set the text to be completed. For its part, requests to the Chat Completions endpoint use the content parameter to set that text.

Get an OpenAI API key

OpenAI API uses the Bearer Authorization mechanism to authorize its clients before processing any request to its endpoints. In this mechanism, the client sends a security token as part of the HTTP Authorization header.

Moreover, OpenAI users can create, edit or delete keys through the API keys page. For more details about API keys, see the Authentication section on the API Reference page.

Use Postman to make a request to OpenAI endpoints

Postman API platform can be used to configure and tune the requests to OpenAI endpoints.

The first step to test the OpenAI endpoints is to define a global variable called OPENAI_API_KEY, and set the value of your OpenAI API key on it. To make this key available on a Postman request, set the value of the Authorization HTTP header to Bearer {{OPENAI_API_KEY}}.

To test the Completion endpoint, create a Postman POST request to https://api.openai.com/v1/completions, and in the Body tab, input the following raw body:

The variables defined above can be set through the Pre-request Script tab. For example:

To test the Chat Completions endpoint, create a POST Postman request to https://api.openai.com/v1/chat/completions, and in the Body tab, input the following text:

The variables defined in the previous JSON document can be set using the Pre-request Script tab. For instance:

In addition, you can use the Postman tools to generate JavaScript code snippets to make requests to Open AI endpoints using different options (i.e., Fetch, jQuery, or XHR).

Implement the ChatGPT RTE plugin on AEM

Let's see how to implement our plugin.

Create an AEM authoring client library

After configuring and testing the OpenAI endpoints through Postman, we created an AEM authoring client library to implement the ChatGPT RTE plugin. Next steps, describe how to use the CRXDE Lite tool to create the nodes required by the client library:

  1. Under the /apps/chatgpt/clientlibs node, create a cq:ClientLibraryFolder node and call it authoring.
  2. Click on the authoring node, then add a multi-value property called categories and add the rte.coralui3 category.
  3. Under the /apps/chatgpt/clientlibs/authoring node, create a nt:foldernode and call it js.
  4. Under the /apps/chatgpt/clientlibs/authoring/js node, create a nt:filenode and call it chatgpt-plugin.js.
  5. Under the /apps/chatgpt/clientlibs/authoring node, create a nt:file node and call it js.txt.

This is the definition of the /apps/chatgpt/clientlibs/authoring node:

This is the content of the /apps/chatgpt/clientlibs/authoring/js.txt node:

After completing the steps defined previously, the following node structure should be part of the JCR repository:

ChatGPT Client Library structure.

Implement the ChatGPT RTE plugin

On AEM, an RTE plugin is a JavaScript user-defined object type that should extend CUI.rte.plugins.Plugin. For our purpose, we implemented a JavaScript user-defined object type called CUI.rte.plugins.ChatgptPlugin with the following structure:

  • Line 1: Declares a JavaScript function that receives two arguments: an instance of jQuery called $ and an instance of Coral UI called CUI.
  • Line 4: Declares a user-defined object type on CUI.rte.plugins.ChatgptPlugin based on the CUI.rte.plugins.Plugin.
  • Line 7: Implements the getFeatures function. This function returns a String array with the features supported by the RTE plugin.
  • Line 10: Implements the initializeUI function. This function can be used to define buttons that represent the features supported by the RTE plugin.
  • Line 13: Implements the updateState function. This function is invoked when there is a change in the editor content or in the user selection. This function can enable or disable the RTE plugin toolbar buttons.
  • Line 16: Implements the execute function. This function is invoked when the user clicks the RTE plugin toolbar button. This function can be used to make the request to OpenAI endpoints and update the editor content.
  • Line 20: Registers the ChatGPT RTE plugin.

ChatGPT RTE plugin commands

The ChatGPT RTE Plugin supports two commands: ChatGPT Completions (chatgpt#completions) and ChatGPT Chat Completions (chatgpt#chat-completions):

ChatGPT RTE plugin command buttons.

These commands are exposed through the getFeatures function, supported by a pair of toolbar buttons that are initialized on the initializeUI and updated on the updateState function:

When an author clicks on any of the ChatGPT RTE plugin toolbar buttons, the execute function is invoked. The selected command is identified by the pluginCommand parameter. In our implementation, this function is used to make requests to the OpenAI endpoints:

Due to the body of requests and responses of the Completions and the Chat Completions endpoints being different, we had to implement a specific function for every endpoint. On the one hand, requests to the Completions endpoint are handled by the requestCompletions function:

On the other hand, requests to the Chat Completions endpoint are handled by the requestChatCompletions function:

A complete implementation of the ChatGPT RTE plugin can be found here.

Configure the ChatGPT RTE Plugin

To test ChatGPT RTE plugin implementation, we added this plugin to the We.Retail Text component. However, the steps listed in this section can be applied to any component that extends the Core Text (v2) component.

  1. Copy the cq:dialog node from /apps/core/wcm/components/text/v2/text to /apps/weretail/components/content/text
  2. Under the /apps/weretail/components/content/text/cq:dialog/content/items/tabs/items/properties/items/columns/items/column/items/text/rtePlugins node, create a nt:unstructured node and called it chatgpt.
  3. Click on the chatgpt node, then add a String property called features and set its value to *.
  4. Click on the /apps/weretail/components/content/text/cq:dialog/content/items/tabs/items/properties/items/columns/items/column/items/text/uiSettings/cui/inline node, then edit the toolbar property, and add at the top of the list the chatgpt#completions and chatgpt#chat-completions features.
  5. Click on the Click on the /apps/weretail/components/content/text/cq:dialog/content/items/tabs/items/properties/items/columns/items/column/items/text/uiSettings/cui/dialogFullScreen node, then edit the toolbar property, and add at the top of the list the chatgpt#completions and chatgpt#chat-completions features.

The following image shows the nodes that were modified in the previous steps:

Modified nodes during the RTE plugin configuration process.

In addition, the full definition of the cq:dialog node can be found here.

Using the ChatGPT RTE plugin on AEM

After implementing and configuring the ChatGPT RTE plugin, this plugin is ready to be used in the authoring phase. For this, we complete the same idea using the two features the plugin provides.

Example 1

Idea: two ideas for women winter sportswear ads

ChatGPT Completions feature response:

1. Photoshoots featuring real-life women in various environments for winter sporting activities, targeted toward showing those sports' efficacy with full controls: temperature, weather gear, and motivational articles.

2. Films visually showing users actually utilizing the merchandise, emphasizing comfort so customers understand intuitively why invest in planning for outdoor adventures and trust the expert ultimate gear, suitable for both short and long attires offers support enabled maximum diversity with minimal vulnerability (note: thermal grade parameters?).

ChatGPT Chat Completions feature response:

Idea #1: Embracing The Snow Queen In this ad, introduce a fierce, feminine skill masquerading graceful and dexterous moves. Capture a confident lead character while playing live against sleek marked line roads, embodying gallant victories won with grand entrance towards audiences online respective contribution with unapologetic turns pressed fearfully into character lining fitted outfit united white hued. Caption:#EmbraceYourFraconner beauty while rotating through magnificent miles; enjoy every lean into the adventure Goddestra-style this season.

Idea #2: Unlimited Exploration With Stylish Comfort This ad will strike your audience with a comfortable, exposed dare exploration in colorful images skill becomes your traveling partner without sacrificing fashion. Have your lead encourage other travelers moment taking them glimpsing to clearly related adventures acorn-color park trails. The detailing inclusion character remains wearing differently changeover. Caption: #AllowYourStyleDistinct, daring progression best celebrating you, invites natural welcoming realms feet towards uncertainties.daring#

Example 2

Idea: two sentences for a new women jacket for spring

ChatGPT Completions feature:

1. The vivid hues and warm fabric of our newest parade wife Woman Jacket make it an ideal outer layer for transitioning between chilly spring evenings and peaceful sunny afternoons!

2. Feel the enhanced — and lasting — comfort of complete breathability backed by assorted zippier and luxurious buttoning as you move conveniently between holiday errands and everyday tasks with rich style.

ChatGPT Chat Completions feature:

Introducing our latest women's jacket perfect for this coming spring. Made from lightweight materials and designed with versatility and comfort in mind, stay chic and on-trend wherever you go.

Conclusions

In this article, we demonstrated how ChatGPT technology can improve different tasks during the authoring phase on AEM pages with the help of OpenAI's API, which provides a robust set of endpoints that expose useful ChatGPT methods. Moreover, these methods have several parameters that enable developers or authors to tune their results.

In addition, we described how to implement an RTE plugin to extend AEM's authoring tools by making requests to the endpoints provided by OpenAI's API.

Finally, we showed how the RTE plugin can be configured in the Rich Text Editor to extend the text authoring options of any existing AEM component, and we illustrated some examples of the completions that this plugin can provide.

--

--