Click here to Skip to main content
15,882,163 members
Articles / Artificial Intelligence / ChatGPT

Chat GPT in JavaScript

Rate me:
Please Sign up or sign in to vote.
5.00/5 (17 votes)
24 May 2023CPOL 73K   2.3K   41   22
Web app to talk to Chat GPT
In this article, I have attempted to create a web page to talk to Chat GPT with speech-to-text and text-to-speech browser capabilities.

Introduction

This application is my attempt to create a smallest client app to talk to Chat GPT in JavaScript. My goal is to demonstrate use Chat GPT API with speech-to-text and text-to-speech browser capabilities. This means that you can talk to your browser and your browser will talk back to you.

Image 1

Using the Code

  1. Get OPENAI_API_KEY from https://beta.openai.com/account/api-keys.
  2. Open ChatGPT.js and add the API Key key to the first line. (Please note that in the real app, this key will need to be encrypted.)

Here is the code. Basically, it uses XMLHttpRequest to post JSON to OpenAI. Endpoint: https://api.openai.com/v1/completions.

Code for ChatGPT.js

JavaScript
var OPENAI_API_KEY = "";
var bTextToSpeechSupported = false;
var bSpeechInProgress = false;
var oSpeechRecognizer = null
var oSpeechSynthesisUtterance = null;
var oVoices = null;

function OnLoad() {
    if ("webkitSpeechRecognition" in window) {
    } else {
        //speech to text not supported
        lblSpeak.style.display = "none";
    }

    if ('speechSynthesis' in window) {
        bTextToSpeechSupported = true;

        speechSynthesis.onvoiceschanged = function () {
            oVoices = window.speechSynthesis.getVoices();
            for (var i = 0; i < oVoices.length; i++) {
                selVoices[selVoices.length] = new Option(oVoices[i].name, i);
            }
        };
    }
}

function ChangeLang(o) {
    if (oSpeechRecognizer) {
        oSpeechRecognizer.lang = selLang.value;
        //SpeechToText()
    }
}

function Send() {

    var sQuestion = txtMsg.value;
    if (sQuestion == "") {
        alert("Type in your question!");
        txtMsg.focus();
        return;
    }

    spMsg.innerHTML = "Chat GPT is thinking...";

    var sUrl = "https://api.openai.com/v1/completions";
    var sModel = selModel.value;// "text-davinci-003";
    if (sModel.indexOf("gpt-3.5-turbo") != -1) {
        //https://openai.com/research/gpt-4
        sUrl = "https://api.openai.com/v1/chat/completions";
    }

    var oHttp = new XMLHttpRequest();
    oHttp.open("POST", sUrl);
    oHttp.setRequestHeader("Accept", "application/json");
    oHttp.setRequestHeader("Content-Type", "application/json");
    oHttp.setRequestHeader("Authorization", "Bearer " + OPENAI_API_KEY)

    oHttp.onreadystatechange = function () {
        if (oHttp.readyState === 4) {
            //console.log(oHttp.status);

            spMsg.innerHTML = "";

            var oJson = {}
            if (txtOutput.value != "") txtOutput.value += "\n";

            try {
                oJson = JSON.parse(oHttp.responseText);
            } catch (ex) {
                txtOutput.value += "Error: " + ex.message
            }

            if (oJson.error && oJson.error.message) {
                txtOutput.value += "Error: " + oJson.error.message;

            } else if (oJson.choices) {
                var s = "";

                if (oJson.choices[0].text) {
                    s = oJson.choices[0].text;

                } else if (oJson.choices[0].message) {
                    //GPT-4
                    s = oJson.choices[0].message.content;
                }

                if (selLang.value != "en-US") {
                    var a = s.split("?\n");
                    if (a.length == 2) {
                        s = a[1];
                    }
                }

                if (s == "") {
                    s = "No response";
                } else {
                    txtOutput.value += "Chat GPT: " + s;
                    TextToSpeech(s);
                }
            }
        }
    };

    var iMaxTokens = 2048;
    var sUserId = "1";
    var dTemperature = 0.5;

    var data = {
        model: sModel,
        prompt: sQuestion,
        max_tokens: iMaxTokens,
        user: sUserId,
        temperature: dTemperature,
        frequency_penalty: 0.0, //Number between -2.0 and 2.0  
                                //Positive value decrease the model's likelihood 
                                //to repeat the same line verbatim.
        presence_penalty: 0.0,  //Number between -2.0 and 2.0. 
                                //Positive values increase the model's likelihood 
                                //to talk about new topics.
        stop: ["#", ";"]        //Up to 4 sequences where the API will stop generating 
                                //further tokens. The returned text will not contain 
                                //the stop sequence.
    }

    //chat GPT-4 gpt-4
    if (sModel.indexOf("gpt-3.5-turbo") != -1) {
        data = {
            "model": sModel,
            "messages": [
                //{
                //    "role": "system",
                //    "content": "You are a helpful assistant."  
                //                assistant messages help store prior responses
                //},
                {
                    "role": "user", //system,user,assistant
                    "content": sQuestion
                }
            ]
        }
    }

    oHttp.send(JSON.stringify(data));

    if (txtOutput.value != "") txtOutput.value += "\n";
    txtOutput.value += "Me: " + sQuestion;
    txtMsg.value = "";
}

function TextToSpeech(s) {
    if (bTextToSpeechSupported == false) return;
    if (chkMute.checked) return;

    oSpeechSynthesisUtterance = new SpeechSynthesisUtterance();

    if (oVoices) {
        var sVoice = selVoices.value;
        if (sVoice != "") {
            oSpeechSynthesisUtterance.voice = oVoices[parseInt(sVoice)];
        }        
    }    

    oSpeechSynthesisUtterance.onend = function () {
        //finished talking - can now listen
        if (oSpeechRecognizer && chkSpeak.checked) {
            oSpeechRecognizer.start();
        }
    }

    if (oSpeechRecognizer && chkSpeak.checked) {
        //do not listen to yourself when talking
        oSpeechRecognizer.stop();
    }

    oSpeechSynthesisUtterance.lang = selLang.value;
    oSpeechSynthesisUtterance.text = s;
    //Uncaught (in promise) Error: A listener indicated an asynchronous response 
    //by returning true, but the message channel closed 
    window.speechSynthesis.speak(oSpeechSynthesisUtterance);
}

function Mute(b) {
    if (b) {
        selVoices.style.display = "none";
    } else {
        selVoices.style.display = "";
    }
}

function SpeechToText() {

    if (oSpeechRecognizer) {

        if (chkSpeak.checked) {
            oSpeechRecognizer.start();
        } else {
            oSpeechRecognizer.stop();
        }

        return;
    }    

    oSpeechRecognizer = new webkitSpeechRecognition();
    oSpeechRecognizer.continuous = true;
    oSpeechRecognizer.interimResults = true;
    oSpeechRecognizer.lang = selLang.value;
    oSpeechRecognizer.start();

    oSpeechRecognizer.onresult = function (event) {
        var interimTranscripts = "";
        for (var i = event.resultIndex; i < event.results.length; i++) {
            var transcript = event.results[i][0].transcript;

            if (event.results[i].isFinal) {
                txtMsg.value = transcript;
                Send();
            } else {
                transcript.replace("\n", "<br>");
                interimTranscripts += transcript;
            }

            var oDiv = document.getElementById("idText");
            oDiv.innerHTML = '<span style="color: #999;">' + 
                               interimTranscripts + '</span>';
        }
    };

    oSpeechRecognizer.onerror = function (event) {

    };
}

Code for the HTML Page ChatGPT.html

HTML
<!DOCTYPE html>
<html>
<head>
    <title>Chat GPT</title>
    <script src="ChatGPT.js?v=15"></script>
</head>
<body onload="OnLoad()">

    <div id="idContainer">
        <textarea id="txtOutput" rows="10" style="margin-top: 10px; 
         width: 100%;" placeholder="Output"></textarea>

        <div>
            <button type="button" onclick="Send()" id="btnSend">Send</button>
            <label id="lblSpeak"><input id="chkSpeak" type="checkbox" 
             onclick="SpeechToText()" />Listen</label>
            <label id="lblMute"><input id="chkMute" type="checkbox" 
             onclick="Mute(this.checked)" />Mute</label>

            <select id="selModel">
                <option value="text-davinci-003">text-davinci-003</option>
                <option value="text-davinci-002">text-davinci-002</option>
                <option value="code-davinci-002">code-davinci-002</option>
                <option value="gpt-3.5-turbo">gpt-3.5-turbo</option>
                <option value="gpt-3.5-turbo-0301">gpt-3.5-turbo-0301</option>
            </select>

            <select id="selLang" onchange="ChangeLang(this)">
                <option value="en-US">English (United States)</option>
                <option value="fr-FR">French (France)</option>
                <option value="ru-RU">Russian (Russia)</option>
                <option value="pt-BR">Portuguese (Brazil)</option>
                <option value="es-ES">Spanish (Spain)</option>
                <option value="de-DE">German (Germany)</option>
                <option value="it-IT">Italian (Italy)</option>
                <option value="pl-PL">Polish (Poland)</option>
                <option value="nl-NL">Dutch (Netherlands)</option>
            </select>

            <select id="selVoices"></select>
            <span id="spMsg"></span>
        </div>

        <textarea id="txtMsg" rows="5" wrap="soft" style="width: 98%; 
         margin-left: 3px; margin-top: 6px" placeholder="Input Text"></textarea>

        <div id="idText"></div>
    </div>

</body>
</html>

Points of Interest

Not all browsers support speech-to-text and text-to-speech. Chrome and Edge seem to support it while Firefox seems to support only text-to-speech.

History

  • 25th December, 2022: Version 1 created
  • 27th December, 2022: Version 2 (added Model selector)
  • 24th May, 2023, Chat GPT4 support

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Web Developer
United States United States
Igor is a business intelligence consultant working in Tampa, Florida. He has a BS in Finance from University of South Carolina and Masters in Information Management System from University of South Florida. He also has following professional certifications: MCSD, MCDBA, MCAD.

Comments and Discussions

 
QuestionCan I use Chat-GPT-in-JavaScript for dall-e-3? Pin
Teptenet FunWorld26-Nov-23 6:09
Teptenet FunWorld26-Nov-23 6:09 
QuestionArticle "ChatGPT in JavaScript" Pin
Member 161103018-Oct-23 17:33
Member 161103018-Oct-23 17:33 
Questionexactly what i was looking for man Pin
Member 1603199817-Jun-23 23:53
Member 1603199817-Jun-23 23:53 
QuestionÑ LETTER CRASH Pin
Tonyamsoft1-Jun-23 11:35
Tonyamsoft1-Jun-23 11:35 
QuestionGetting an error Pin
Devendra Thakkar24-May-23 21:53
Devendra Thakkar24-May-23 21:53 
AnswerRe: Getting an error Pin
gardnerp25-May-23 8:19
gardnerp25-May-23 8:19 
GeneralRe: Getting still an error Pin
Devendra Thakkar25-May-23 18:11
Devendra Thakkar25-May-23 18:11 
GeneralRe: Getting still an error Pin
gardnerp30-May-23 4:47
gardnerp30-May-23 4:47 
QuestionChat GPT in JavaScript Pin
Member 108278727-May-23 20:58
Member 108278727-May-23 20:58 
GeneralMy vote of 5 Pin
Member 108278725-May-23 4:16
Member 108278725-May-23 4:16 
BugTokens field Pin
Woody D14-Apr-23 14:50
Woody D14-Apr-23 14:50 
BugListen checkbox no function Pin
Woody D27-Feb-23 17:22
Woody D27-Feb-23 17:22 
GeneralMy vote of 5 Pin
Georg Miler26-Jan-23 5:03
Georg Miler26-Jan-23 5:03 
QuestionChatGPT is really viable? Pin
Pospai Doru28-Dec-22 22:15
Pospai Doru28-Dec-22 22:15 
AnswerRe: ChatGPT is really viable? Pin
Igor Krupitsky30-Jan-23 9:53
mvaIgor Krupitsky30-Jan-23 9:53 
AnswerRe: ChatGPT is really viable? Pin
f_tom25-May-23 6:56
f_tom25-May-23 6:56 
QuestionChat GPT in JavaScript Pin
Pospai Doru28-Dec-22 0:15
Pospai Doru28-Dec-22 0:15 
SuggestionApart from... Pin
Afzaal Ahmad Zeeshan25-Dec-22 10:07
professionalAfzaal Ahmad Zeeshan25-Dec-22 10:07 
GeneralRe: Apart from... Pin
0x01AA25-Dec-22 11:32
mve0x01AA25-Dec-22 11:32 
QuestionSorry.... Pin
0x01AA25-Dec-22 8:22
mve0x01AA25-Dec-22 8:22 
AnswerRe: Sorry.... Pin
Pospai Doru28-Dec-22 21:25
Pospai Doru28-Dec-22 21:25 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.