Try our conversational search powered by Generative AI!

Aniket
Feb 27, 2023
  1569
(0 votes)

ChatGPT/OpenAI integration for text generation using Prompt in Optimizely

Here's how you can use a simple publishing event to generate content using OpenAI.

The code is pretty simple - I will avoid getting into too many details as Tomas has done a wonderful job of explaining it in his blog post here:
https://www.gulla.net/en/blog/integrating-generative-ai-in-optimizely-cms-a-quick-test-with-openai/

...And from Allan here:
https://www.codeart.dk/blog/2022/11/ai-assisted-content-creation---in-optimizely-cms--commerce-ai-series---part-2/ 

Here's sample code which has been requested by a few people. 

namespace ClientName.CMS.Features.Sample
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net.Http;
    using System.Threading.Tasks;
    using System.Web;
    using EPiServer;
    using EPiServer.Core;
    using EPiServer.Framework;
    using EPiServer.Framework.Initialization;
    using EPiServer.ServiceLocation;
    using Newtonsoft.Json;
    using ClientName.CMS.Features.Basics.RichTextBlock.Models;
    using ClientName.Common.Features.Foundation.Threading.Utilities;

    [InitializableModule]
    [ModuleDependency(typeof(EPiServer.Web.InitializationModule))]
    public class OpenAIBlockInitialization : IInitializableModule
    {
        private static readonly HttpClient _client = new HttpClient();
        private readonly string _apiKey = "YOUR API KEY GOES HERE"; // You can generate it here: https://platform.openai.com/account/api-keys

        public void Initialize(InitializationEngine context)
        {
            // Add initialization logic, this method is called once after CMS has been initialized
            var contentEvents = ServiceLocator.Current.GetInstance<IContentEvents>();
            contentEvents.PublishingContent += ContentEvents_PublishingContent;
        }

        public async Task<dynamic> SendRequestAsync(string model, string prompt, int maxTokens)
        {
            var requestUrl = "https://api.openai.com/v1/engines/" + model + "/completions";
            var requestData = new
            {
                prompt = prompt,
                max_tokens = maxTokens
            };
            var jsonRequestData = JsonConvert.SerializeObject(requestData);
            var requestContent = new StringContent(jsonRequestData, System.Text.Encoding.UTF8, "application/json");

            _client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", _apiKey);

            var response = await _client.PostAsync(requestUrl, requestContent);
            response.EnsureSuccessStatusCode();

            var responseContent = await response.Content.ReadAsStringAsync();
            var responseData = JsonConvert.DeserializeObject<dynamic>(responseContent);

            return responseData;
        }

        private void ContentEvents_PublishingContent(object sender, EPiServer.ContentEventArgs e)
        {
            try
            {
                if (e.Content != null)
                {
                    if (e.Content is RichTextBlock richTextBlock)
                    {
                        var blockData = e.Content as RichTextBlock;

                        string textToOpenAI = blockData.OpenAIPrompt;

                        // Call Open AI and get results
                        var response = AsyncHelper.RunSync(async () => await SendRequestAsync("text-davinci-003", textToOpenAI, 3000));

                        blockData.OpenAIGeneratedText = response?.choices[0]?.text;
                    }
                }
            }
            catch (Exception ex)
            {
                // Optinal logging
            }
        }

        public void Uninitialize(InitializationEngine context)
        {
            // Add uninitialization logic
            var contentEvents = ServiceLocator.Current.GetInstance<IContentEvents>();
            contentEvents.PublishingContent -= ContentEvents_PublishingContent;
        }
    }
}

AsyncHelper class to run async method synchronously (due to initialization functions limitations)

namespace ClientName.Common.Features.Foundation.Threading.Utilities
{
    using System;
    using System.Threading;
    using System.Threading.Tasks;

    public static class AsyncHelper
    {
        private static readonly TaskFactory TaskFactory =
            new TaskFactory(CancellationToken.None, TaskCreationOptions.None, TaskContinuationOptions.None, TaskScheduler.Default);

        /// <summary>
        /// Executes an async Task method which has a void return value synchronously
        /// USAGE: AsyncUtil.RunSync(() => AsyncMethod());
        /// </summary>
        /// <param name="task">Task method to execute</param>
        public static void RunSync(Func<Task> task) => TaskFactory.StartNew(task).Unwrap().GetAwaiter().GetResult();

        /// <summary>
        /// Executes an async Task<T> method which has a T return type synchronously
        /// USAGE: T result = AsyncUtil.RunSync(() => AsyncMethod<T>());
        /// </summary>
        /// <typeparam name="TResult">Return Type</typeparam>
        /// <param name="task">Task<T> method to execute</param>
        /// <returns></returns>
        public static TResult RunSync<TResult>(Func<Task<TResult>> task) =>
            TaskFactory.StartNew(task).Unwrap().GetAwaiter().GetResult();
    }
}

Happy coding!

Feb 27, 2023

Comments

Please login to comment.
Latest blogs
A day in the life of an Optimizely Developer - Enabling Opti ID within your application

Hello and welcome to another instalment of A Day In The Life Of An Optimizely developer, in this blog post I will provide details on Optimizely's...

Graham Carr | May 9, 2024

How to add a custom property in Optimizely Graph

In the Optimizely CMS content can be synchronized to the Optimizely Graph service for it then to be exposed by the GraphQL API. In some cases, you...

Ynze | May 9, 2024 | Syndicated blog

New Security Improvement released for Optimizely CMS 11

A new security improvement has been released for Optimizely CMS 11. You should update now!

Tomas Hensrud Gulla | May 7, 2024 | Syndicated blog

Azure AI Language – Key Phrase Extraction in Optimizely CMS

In this article, I demonstrate how the key phrase extraction feature, offered by the Azure AI Language service, can be used to generate a list of k...

Anil Patel | May 7, 2024 | Syndicated blog

Webinar: Get Started with AI within Optimizely CMS

Join us for the webinar "Get Started with AI in Optimizely CMS" on Wednesday, May 8th. Don't forget to register!

Luc Gosso (MVP) | May 7, 2024 | Syndicated blog

Search & Navigation: Indexing job new features

From Episerver.Find version 16.1.0, we introduced some new features that make the indexing job in CMS more flexible and efficient: Support continuo...

Vinh Cao | May 7, 2024