In this tutorial, we’ll walk through building a real-time AI chatbot in Go (Golang) that uses WebSockets for low-latency client communication and OpenAI GPT for generating intelligent responses.
Instead of waiting for full responses, we’ll implement streaming, so your chatbot feels fast and interactive — responses appear as they’re generated, token by token.
By the end, you’ll have:
-
A Go WebSocket server that relays user messages to OpenAI GPT and streams responses back.
-
A browser client with live chat UI powered by HTML and JavaScript.
-
A simple but extendable architecture for multi-user real-time AI apps.
Prerequisites
Before starting, make sure you have:
-
Go 1.20+ is installed on your system.
-
An OpenAI API key (set as
OPENAI_API_KEY
). -
Basic knowledge of Go, WebSockets, and JavaScript.
We’ll use the following Go packages:
-
gorilla/websocket – WebSocket server library.
-
sashabaranov/go-openai – popular Go client for OpenAI API.
Project Setup
Create a new folder and initialize a Go module:
mkdir go-ai-chatbot
cd go-ai-chatbot
go mod init github.com/yourusername/go-ai-chatbot
go get github.com/gorilla/websocket
go get github.com/sashabaranov/go-openai
Project structure:
go-ai-chatbot/
├─ cmd/
│ └─ server/main.go
├─ web/
│ └─ index.html
├─ go.mod
└─ README.md
Step 1: Go to the WebSocket Server
Create cmd/server/main.go
:
package main
import (
"context"
"fmt"
"io"
"log"
"net/http"
"os"
"time"
"github.com/gorilla/websocket"
openai "github.com/sashabaranov/go-openai"
)
var upgrader = websocket.Upgrader{
CheckOrigin: func(r *http.Request) bool { return true },
}
type WSMessage struct {
Type string `json:"type"`
Payload string `json:"payload"`
}
func main() {
apiKey := os.Getenv("OPENAI_API_KEY")
if apiKey == "" {
log.Fatal("OPENAI_API_KEY env var is required")
}
client := openai.NewClient(apiKey)
http.HandleFunc("/ws", func(w http.ResponseWriter, r *http.Request) {
handleWS(w, r, client)
})
fs := http.FileServer(http.Dir("./web"))
http.Handle("/", fs)
addr := ":8080"
log.Printf("Server running at %s", addr)
log.Fatal(http.ListenAndServe(addr, nil))
}
func handleWS(w http.ResponseWriter, r *http.Request, client *openai.Client) {
conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
log.Println("Upgrade error:", err)
return
}
defer conn.Close()
ctx := context.Background()
for {
var msg WSMessage
if err := conn.ReadJSON(&msg); err != nil {
log.Println("ReadJSON error:", err)
return
}
if msg.Type == "user_message" {
go handleUserMessage(ctx, conn, client, msg.Payload)
}
}
}
func handleUserMessage(ctx context.Context, conn *websocket.Conn, client *openai.Client, userText string) {
req := openai.ChatCompletionRequest{
Model: openai.GPT3Dot5Turbo,
Messages: []openai.ChatCompletionMessage{
{Role: "system", Content: "You are a helpful assistant."},
{Role: "user", Content: userText},
},
Stream: true,
}
stream, err := client.CreateChatCompletionStream(ctx, req)
if err != nil {
sendError(conn, fmt.Sprintf("Stream error: %v", err))
return
}
defer stream.Close()
for {
response, err := stream.Recv()
if err != nil {
if err == io.EOF {
_ = conn.WriteJSON(WSMessage{Type: "ai_done", Payload: ""})
return
}
sendError(conn, fmt.Sprintf("Recv error: %v", err))
return
}
if len(response.Choices) > 0 {
delta := response.Choices[0].Delta.Content
if delta != "" {
_ = conn.WriteJSON(WSMessage{Type: "ai_delta", Payload: delta})
}
}
}
}
func sendError(conn *websocket.Conn, text string) {
_ = conn.WriteJSON(WSMessage{Type: "error", Payload: text})
time.Sleep(50 * time.Millisecond)
}
Step 2: Browser Client
Create web/index.html
:
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title>Go AI Chatbot</title>
<style>
body { font-family: sans-serif; margin: 20px; }
#log { white-space: pre-wrap; border: 1px solid #ccc; padding: 12px; height: 300px; overflow:auto; }
</style>
</head>
<body>
<h1>AI Chatbot (Go + WebSocket)</h1>
<div id="log"></div>
<input id="input" placeholder="Type a message..." style="width:70%" />
<button id="send">Send</button>
<script>
const log = document.getElementById('log');
const input = document.getElementById('input');
const sendBtn = document.getElementById('send');
const ws = new WebSocket(`${location.origin.replace(/^http/, "ws")}/ws`);
ws.onopen = () => appendLog("[connected]\n");
ws.onmessage = (ev) => {
const msg = JSON.parse(ev.data);
if (msg.type === "ai_delta") {
appendLog(msg.payload);
} else if (msg.type === "ai_done") {
appendLog("\n\n[response complete]\n\n");
} else if (msg.type === "error") {
appendLog("\n[ERROR] " + msg.payload + "\n");
}
};
sendBtn.onclick = sendMessage;
input.addEventListener("keydown", (e) => { if (e.key === "Enter") sendMessage(); });
function sendMessage() {
const text = input.value.trim();
if (!text) return;
appendLog("\nYou: " + text + "\n");
ws.send(JSON.stringify({ type: "user_message", payload: text }));
input.value = "";
}
function appendLog(s) {
log.textContent += s;
log.scrollTop = log.scrollHeight;
}
</script>
</body>
</html>
Step 3: Run and Test
Run the server:
export OPENAI_API_KEY="sk-..."
go run ./cmd/server
Open a browser at http://localhost:8080.
Type a message and watch as the chatbot streams responses live.
Screenshot suggestions for your article:
-
Terminal running the Go server.
-
Browser showing the chat UI.
-
Streaming response in real-time.
Step 4: Improvements
-
Store conversation history per user.
-
Add authentication (e.g., JWT).
-
Use Redis/Postgres for persistence.
-
Deploy behind Nginx with TLS.
-
Add text-to-speech (TTS) or speech-to-text (STT) for a voice-enabled chatbot.
Conclusion
We’ve built a fully functional real-time AI chatbot in Go using WebSockets and OpenAI GPT. This setup ensures low-latency communication and smooth, streaming responses.
With this foundation, you can expand to multi-user support, persistent memory, or even integrate into mobile and desktop clients.
You can find the full source code on our GitHub.
That is just the basics. If you need more deep learning about the Golang (Go) language and frameworks, you can take the following cheap course:
- Real-World GoLang Project: Car Management System
- Building GUI Applications with Fyne and Go (Golang)
- AWS Cognito Using Golang
- Google Go Programming for Beginners (golang)
- Building a module in Go (Golang)
- Go/Golang Professional Interview Questions
Thanks!