How to build AI Chatbot in ASP.NET Core using ChatGPT?

ChatGPT known as Chat Generative Pre-trained Transformer, is an artificial intelligent chatbot from OpenAI. ChatGPT is much more advanced than traditional chatbots, as it has been trained on a massive amount of data. ChatGPT is popular due to it's powerful features, but not limited to: 

  • Natural language processing.
  • Contextual understanding of your followup converseation.
  • Understand in multiple languages of your queries.
  • Wide knowledge base.
  • Ability to scale with deep learning.
  • Support of multimodal - text, image and voice.

ChatGPT from OpenAI

If you would like to bring the capabilities of ChatGPT to your custom ASP.NET Core application, here are the details how you can do the same.

Here are I am going to describe you about creating the Chat BOT applicaiton which sends the user query to ChatGPT, get the response, and show the same in Chat interface. For this, you need to take 3 step process. Signup OpenAI for API key to accept queries from your application, Create custom Chat API in your application and chat interface for query conversations.

Step 1 (Get OpenAI API Key)

Go to OpenAI developer overview site, and here is the link:

https://platform.openai.com/overview

After you sign up, navigate to View API keys page from the user account menu.

OpenAI View API keys

You will be redirected to API keys page as shown below.


OpenAI Create new secret key

Click on the Create new secret key button to generate the API key. Once the key is generated don’t forget to copy and save it in editors like notepad, etc. Once you close the below API key generated dialog, you will not see it API key again. If you lose it, you will have to regenerate the API key again.


OpenAI API key generated

Step 2 (Create Chat API)

Since I am going to have chat API and chat user interface in single application in this example, let’s pick ASP.NET Core Web App (MVC) application. You can still go for two different applications, one is Chat API for business logic and another is Front End application for presentation logic.

Go to visual studio and create ASP.NET Core Web App (MVC) application called ASPNETCoreChatGPT


In this example I am using .NET 7.0

Install the below packages to support Swagger and CORS middleware.

DotNET Swagger Packages
After above packages are installed, add the Swagger to application builder services as show below:
 
var builder = WebApplication.CreateBuilder(args); 
builder.Services.AddControllersWithViews(); 
builder.Services.AddEndpointsApiExplorer(); 
builder.Services.AddSwaggerGen(); 
 
builder.Services.AddCors(options => { options.AddPolicy("AllowAllOrigins"builder => { builder.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader(); }); }); 
 
var app = builder.Build(); 
app.UseSwagger(); 
app.UseSwaggerUI(); 
app.UseStaticFiles(); 
 
app.UseRouting(); 
app.UseAuthorization(); 
app.MapControllerRoute(name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); 
app.UseCors("AllowAllOrigins"); 
app.Run();

Create model classes called, ChatRequest and ChatResponse as shown below:

public class ChatRequest
{
    public string model { getset; }
    public Message[] messages { getset; }
}
public class Message
{
    public string role { getset; }
    public string content { getset; }
}


public class HttpChatGPTResponse
{
    public bool Success { getset; }
    public string Data { getset; }
    public string Error { getset; }
}
public class ChatResponse
{
    public string id { getset; }
    public string _object { getset; }
    public int created { getset; }
    public Choice[] choices { getset; }
    public Usage usage { getset; }
}
public class Usage
{
    public int prompt_tokens { getset; }
    public int completion_tokens { getset; }
    public int total_tokens { getset; }
}
public class Choice
{
    public int index { getset; }
    public Message message { getset; }
    public string finish_reason { getset; }
}

Now create a controller called ChatGPTController.cs to have the AskChatGPT API method.

Here is the AskChatGPT API code to accept the query as input, pass it on to ChatGPT and send the query response back to API caller.
 
[ApiController]
public class ChatGPTController : ControllerBase
{
    [HttpPost]
    [Route("AskChatGPT")]
    public async Task<IActionResult> AskChatGPT([FromBody] string query)
    {
        string chatURL = "https://api.openai.com/v1/chat/completions";
        string apiKey = "YOUR_OpenAI_API_KEY_FROM_STEP1";
 
        StringBuilder sb = new StringBuilder();
        HttpClient oClient = new HttpClient();
 
        oClient.DefaultRequestHeaders.Add("Authorization"$"Bearer {apiKey}");
        ChatRequest oRequest = new ChatRequest();
        oRequest.model = "gpt-3.5-turbo";
        Message oMessage = new Message();
        oMessage.role = "user";
        oMessage.content = query;
        oRequest.messages = new Message[] { oMessage };
 
        string oReqJSON = JsonConvert.SerializeObject(oRequest);
 
        HttpContent oContent = new StringContent(oReqJSON, Encoding.UTF8, "application/json");
        HttpResponseMessage oResponseMessage = await oClient.PostAsync(chatURL, oContent);
 
        if (oResponseMessage.IsSuccessStatusCode)
        {
            string oResJSON = await oResponseMessage.Content.ReadAsStringAsync();
            ChatResponse oResponse = JsonConvert.DeserializeObject<ChatResponse>(oResJSON);
 
            foreach (Choice c in oResponse.choices)
            {
                sb.Append(c.message.content);
            }
 
            HttpChatGPTResponse oHttpResponse = new HttpChatGPTResponse()
            {
                Success = true,
                Data = sb.ToString()
            };
 
            return Ok(oHttpResponse);
        }
        else
        {
            return BadRequest();
        }
    }
}

Now run the application, to launch the API in Swagger UI and perform some tests there. Here is the sample URL to view the APIs in Swagger.

http://localhost:5064/swagger/index.html (Note: port number may be different in your application)

 View APIs in Swagger UI


Step 3 (Create Chat Interface)

Since both Chat API and Chat Interface are in the same application, create another controller in the above Chat API project with name called HomeController.cs if it is already exists by default, let’s use the same.

Home Controller doesn’t have any logic and it is used to just render the chat interface view. Below is the Home Controller template code with index action method:
 

[pre class="brush:csharp; toolbar: true;" title="HomeController.cs"] public class HomeController : Controller { public IActionResult Index() { return View(); } } [/pre]


Now create a View called Index.cshtml for Home Controller’s default Index action method.

Here is the HTML for Chat interface UI:


<section class="msger">
    <header class="msger-header">
        <div class="msger-header-title">
            <i class="fas fa-comment-alt" /> ChatGPT
        </div>
        <div class="msger-header-options">
            <span>
                <i class="fas fa-cog" />
            </span>
        </div>
    </header>
    <main class="msger-chat"> </main>
    <form class="msger-inputarea">
        <input id="messageInput" type="text" class="msger-input" placeholder="Enter your query..." />
        <button id="sendButton" class="msger-send-btn">Send</button>
    </form>
</section> 

And, here is the JavaScript code required to accept the query from user, send it to our Chat API built above and present the response.
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.4/jquery.min.js" />
<script type="text/javascript">
    const imgBOT = "/images/bot.png";
    const imgPerson = "/images/user.png";
    const nameBOT = "ChatGPT";
    const namePerson = "Srinivas";
 
    $(function () {
        addChatMessage(nameBOT, imgBOT, "right""Hey! How may I help you?");
 
        $('#sendButton').click(function () {
            var message = $('#messageInput').val(); askChatGPT(message);
            $('#messageInput').val(''); return false;
        });
        function askChatGPT(message) {
            addChatMessage(namePerson, imgPerson, "left", message);
 
            $.ajax({
                url: '/AskChatGPT', type: 'POST', data: JSON.stringify(message), async: true, contentType: 'application/json', success: function (response) {
                    addChatMessage(nameBOT, imgBOT, "right", response.data);
                    $('.imgLoader').hide();
                }
            });
        }
 
        function addChatMessage(name, img, side, text) {
            const msgHTML = ` <div class="msg ${side}-msg">
                        <div class="msg-img" style="background-image: url(${img})"/>
                        <div class="msg-bubble">
                            <div class="msg-info">
                                <div class="msg-info-name">${name}</div>
                                <div class="msg-info-time">${formatDate(new Date())}</div>
                            </div>
                            <div class="msg-text">${text}</div>
                        </div>
                    </div> `; $(".msger-chat").append($(msgHTML)); if (side == "left") {
                var loaderHTML = `<div id="dvLoader">
                        <img class="imgLoader" src="/images/loader.gif"/>
                    </div>`; $(".msger-chat").append($(loaderHTML));
            } $(".msger-chat").scrollTop($(".msger-chat").scrollTop() + 500); return false;
        }
 
        function formatDate(date) {
            const h = "0" + date.getHours(); const m = "0" + date.getMinutes(); return `${h.slice(-2)}:${m.slice(-2)}`;
        }
    });</script> 

And finally, here are the CSS styles required for Chat interface for better look. This is for sample purpose only; you can have your own custom styles for much better look and feel of Chat interface.
 
<style type="text/css">
    :root {
        --body-bg: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
        --msger-bg: #fff;
        --border: 2px solid #ddd;
        --left-msg-bg: #ececec;
        --right-msg-bg: #579ffb;
    }
 
    html {
        box-sizingborder-box;
    }
 
    **:before, *:after {
        margin0;
        padding0;
        box-sizinginherit;
    }
 
    body {
        displayflex;
        justify-contentcenter;
        align-itemscenter;
        height100vh;
        background-imagevar(--body-bg);
        font-familyHelvetica, sans-serif;
    }
 
    .msger {
        displayflex;
        flex-flowcolumn wrap;
        justify-contentspace-between;
        width100%;
        max-width867px;
        margin25px 10px;
        heightcalc(100% - 50px);
        bordervar(--border);
        border-radius5px;
        backgroundvar(--msger-bg);
        box-shadow0 15px 15px -5px rgba(0, 0, 0, 0.2);
    }
 
    .msger-header {
        displayflex;
        justify-contentspace-between;
        padding10px;
        border-bottomvar(--border);
        background#eee;
        color#666;
    }
 
    .msger-chat {
        flex1;
        overflow-yauto;
        padding10px;
    }
 
        .msger-chat::-webkit-scrollbar {
            width6px;
        }
 
        .msger-chat::-webkit-scrollbar-track {
            background#ddd;
        }
 
        .msger-chat::-webkit-scrollbar-thumb {
            background#bdbdbd;
        }
 
    .msg {
        displayflex;
        align-itemsflex-end;
        margin-bottom10px;
    }
 
        .msg:last-of-type {
            margin0;
        }
 
    .msg-img {
        width50px;
        height50px;
        margin-right10px;
        background#ddd;
        background-repeatno-repeat;
        background-positioncenter;
        background-sizecover;
        border-radius50%;
    }
 
    .msg-bubble {
        max-width450px;
        padding15px;
        border-radius15px;
        backgroundvar(--left-msg-bg);
    }
 
    .msg-info {
        displayflex;
        justify-contentspace-between;
        align-itemscenter;
        margin-bottom10px;
    }
 
    .msg-info-name {
        margin-right10px;
        font-weightbold;
    }
 
    .msg-info-time {
        font-size0.85em;
    }
 
    .left-msg .msg-bubble {
        border-bottom-left-radius0;
    }
 
    .right-msg {
        flex-directionrow-reverse;
    }
 
        .right-msg .msg-bubble {
            backgroundvar(--right-msg-bg);
            color#fff;
            border-bottom-right-radius0;
        }
 
        .right-msg .msg-img {
            margin0 0 0 10px;
        }
 
    .msger-inputarea {
        displayflex;
        padding10px;
        border-topvar(--border);
        background#eee;
    }
 
        .msger-inputarea * {
            padding10px;
            bordernone;
            border-radius3px;
            font-size1em;
        }
 
    .msger-input {
        flex1;
        background#ddd;
    }
 
    .msger-send-btn {
        margin-left10px;
        backgroundrgb(0, 196, 65);
        color#fff;
        font-weightbold;
        cursorpointer;
        transitionbackground 0.23s;
    }
 
        .msger-send-btn:hover {
            backgroundrgb(0, 180, 50);
        }
 
    .msger-chat {
        background-color#fcfcfe;
    }
 
    .imgLoader {
        height100px;
        positionrelative;
        left55px;
        top-40px;
    }
</style> 

Now, run your application and call the Index method of Home Controller, then you should see the chat interface as below, and start asking questions to ChatGPT right from your application itself.

Chatbot User Interface

You can even download the entire source code project, and feel free to make the necessary changes as you wish.




Hope this helps you to understand the classic integration of ChatGPT with ASP.NET Core MVC application. The process of integration is same for any other technology application. And in my next article I will try to describe on how to integrate the above custom ASP.NET Core Chat API in Angular UI component as a front layer for chat interface.

Happy coding...!

No comments:

Powered by Blogger.