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's just the basics. If you need more deep learning about Go/Golang, you can take the following cheap course:
- Go - The Complete Guide
- NEW-Comprehensive Go Bootcamp with gRPC and Protocol Buffers
- Backend Master Class [Golang + Postgres + Kubernetes + gRPC]
- Complete Microservices with Go
- Backend Engineering with Go
- Introduction to AI and Machine Learning with Go (Golang)
- Working with Concurrency in Go (Golang)
- Introduction to Testing in Go (Golang)
- Design Patterns in Go
- Go Bootcamp: Master Golang with 1000+ Exercises and Projects
Thanks!