[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"academy-blogs-en-1-1-all-reply-message-websocket-chat-all--*":3,"academy-blog-translations-tfjiw54rh3j333a":99},{"data":4,"page":87,"perPage":87,"totalItems":87,"totalPages":87},[5],{"alt":6,"collectionId":7,"collectionName":8,"content":9,"cover_image":10,"cover_image_path":11,"created":12,"created_by":13,"expand":14,"id":94,"keywords":95,"locale":69,"published_at":96,"scheduled_at":13,"school_blog":91,"short_description":97,"status":89,"title":6,"updated":98,"updated_by":13,"slug":92,"views":93},"EP.52 Adding a Reply to Message Feature in WebSocket Chat","sclblg987654321","school_blog_translations","\u003Cp>In this article, we’ll guide you through adding a \"Reply to Message\" feature in WebSocket Chat. This feature will enable users to reply to messages they’ve already sent. By doing so, it allows for better message threading and improves the overall organization of the chat.\u003C\u002Fp>\u003Cp>&nbsp;\u003C\u002Fp>\u003Ch2>Steps to add message reply feature in WebSocket Chat:\u003C\u002Fh2>\u003Col>\u003Cli>\u003Ch3>Why the reply feature is necessary in WebSocket Chat?\u003C\u002Fh3>\u003Cul>\u003Cli>Allows users to reply to specific messages, creating organized conversations.\u003C\u002Fli>\u003Cli>Provides context for replies, making the chat more structured.\u003C\u002Fli>\u003C\u002Ful>\u003C\u002Fli>\u003Cli>\u003Ch3>The structure of a reply system in WebSocket Chat\u003C\u002Fh3>\u003Cul>\u003Cli>Connecting the replied message with the original message.\u003C\u002Fli>\u003Cli>Handling the data properly in both the backend and frontend.\u003C\u002Fli>\u003C\u002Ful>\u003C\u002Fli>\u003Cli>\u003Ch3>How to add the \"Reply to Message\" feature in WebSocket Server\u003C\u002Fh3>\u003Cul>\u003Cli>We’ll update the server to handle the replying functionality.\u003C\u002Fli>\u003Cli>Sending and broadcasting the reply to all connected clients.\u003C\u002Fli>\u003C\u002Ful>\u003C\u002Fli>\u003Cli>\u003Ch3>How to update the Frontend UI with reply buttons and display replies\u003C\u002Fh3>\u003Cul>\u003Cli>Adding a \"Reply\" button in the frontend for users to click and respond.\u003C\u002Fli>\u003Cli>Showing the replies in a user-friendly format.\u003C\u002Fli>\u003C\u002Ful>\u003C\u002Fli>\u003Cli>\u003Ch3>Testing the feature\u003C\u002Fh3>\u003Cul>\u003Cli>Testing the feature by sending a message and replying to it in real-time.\u003C\u002Fli>\u003C\u002Ful>\u003C\u002Fli>\u003C\u002Fol>\u003Ch3>&nbsp;\u003C\u002Fh3>\u003Ch2>Code Example for Adding Reply to Message in WebSocket Chat\u003C\u002Fh2>\u003Col>\u003Cli>\u003Ch3>Database Update (Database)\u003C\u002Fh3>\u003C\u002Fli>\u003C\u002Fol>\u003Cp>First, we need to update the database to support message replies by adding a column \u003Ccode inline=\"\">reply_to_message_id\u003C\u002Fcode> to link the reply to the original message.\u003C\u002Fp>\u003Cpre>\u003Ccode class=\"language-plaintext language-sql\">ALTER TABLE chat_messages ADD COLUMN reply_to_message_id INT REFERENCES chat_messages(id);\n\u003C\u002Fcode>\u003C\u002Fpre>\u003Col start=\"2\">\u003Cli>\u003Ch3>WebSocket Server Code (Backend)\u003C\u002Fh3>\u003C\u002Fli>\u003C\u002Fol>\u003Cp>Next, we update the WebSocket Server to handle replies by allowing users to reply to specific messages and notifying all connected clients.\u003C\u002Fp>\u003Cpre>\u003Ccode class=\"language-plaintext language-go\">package main\n\nimport (\n    \"database\u002Fsql\"\n    \"encoding\u002Fjson\"\n    \"fmt\"\n    \"net\u002Fhttp\"\n    \"sync\"\n\n    \"github.com\u002Fgorilla\u002Fwebsocket\"\n    _ \"github.com\u002Flib\u002Fpq\"\n)\n\ntype ReplyRequest struct {\n    MessageID   int    `json:\"messageID\"`\n    Sender      string `json:\"sender\"`\n    NewContent  string `json:\"newContent\"`\n    ReplyToID   int    `json:\"replyToID\"`\n}\n\ntype ReplyResponse struct {\n    MessageID   int    `json:\"messageID\"`\n    NewContent  string `json:\"newContent\"`\n    Sender      string `json:\"sender\"`\n    ReplyToID   int    `json:\"replyToID\"`\n}\n\nvar (\n    clients   = make(map[*websocket.Conn]bool)\n    broadcast = make(chan ReplyResponse)\n    mu        sync.Mutex\n    db        *sql.DB\n)\n\nfunc handleReplyMessage(w http.ResponseWriter, r *http.Request) {\n    conn, _ := upgrader.Upgrade(w, r, nil)\n    defer conn.Close()\n    clients[conn] = true\n\n    for {\n        var request ReplyRequest\n        err := conn.ReadJSON(&amp;request)\n        if err != nil {\n            delete(clients, conn)\n            break\n        }\n\n        \u002F\u002F Insert the replied message into the database\n        _, err = db.Exec(\"INSERT INTO chat_messages (content, sender, reply_to_message_id) VALUES ($1, $2, $3)\", request.NewContent, request.Sender, request.ReplyToID)\n        if err == nil {\n            broadcast &lt;- ReplyResponse{MessageID: request.MessageID, NewContent: request.NewContent, Sender: request.Sender, ReplyToID: request.ReplyToID}\n        }\n    }\n}\n\nfunc notifyClients() {\n    for {\n        msg := &lt;-broadcast\n        for client := range clients {\n            err := client.WriteJSON(msg)\n            if err != nil {\n                client.Close()\n                delete(clients, client)\n            }\n        }\n    }\n}\n\nfunc main() {\n    http.HandleFunc(\"\u002Fws\", handleReplyMessage)\n    go notifyClients()\n    fmt.Println(\"WebSocket Server Running on Port 8080\")\n    http.ListenAndServe(\":8080\", nil)\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\u003Col start=\"3\">\u003Cli>\u003Ch3>Frontend Code (Client)\u003C\u002Fh3>\u003C\u002Fli>\u003C\u002Fol>\u003Cp>Now, we’ll add a \"Reply\" button in the frontend so users can reply to specific messages.\u003C\u002Fp>\u003Cpre>\u003Ccode class=\"language-javascript\">const socket = new WebSocket(\"ws:\u002F\u002Flocalhost:8080\u002Fws\");\nconst chatContainer = document.getElementById(\"chat-container\");\n\nsocket.onmessage = (event) =&gt; {\n    const data = JSON.parse(event.data);\n    const messageElement = document.getElementById(`msg-${data.messageID}`);\n    if (data.replyToID) {\n        messageElement.innerHTML = `${data.sender} replied: ${data.newContent}`;\n    }\n};\n\nfunction sendReplyRequest(messageID, newContent, replyToID) {\n    socket.send(JSON.stringify({ messageID, sender: \"JohnDoe\", newContent, replyToID }));\n}\n\nfunction displayMessage(id, sender, content) {\n    const msgElement = document.createElement(\"p\");\n    msgElement.id = `msg-${id}`;\n    msgElement.innerText = `${sender}: ${content}`;\n    \n    const replyButton = document.createElement(\"button\");\n    replyButton.innerText = \"Reply\";\n    replyButton.onclick = () =&gt; {\n        const newContent = prompt(\"Reply to this message:\", content);\n        if (newContent) sendReplyRequest(id, newContent, id);\n    };\n    \n    msgElement.appendChild(replyButton);\n    chatContainer.appendChild(msgElement);\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\u003Cp>&nbsp;\u003C\u002Fp>\u003Chr>\u003Cp>&nbsp;\u003C\u002Fp>\u003Ch3>Challenge:\u003C\u002Fh3>\u003Cp>Try adding a \u003Cstrong>message follow-up feature\u003C\u002Fstrong> that will allow users to track replies to messages they've responded to!\u003C\u002Fp>\u003Cp>&nbsp;\u003C\u002Fp>\u003Cp>\u003Cstrong>Next EP:\u003C\u002Fstrong>\u003Cbr>In the next episode, we’ll explore \u003Cstrong>adding a feature to follow up on replies\u003C\u002Fstrong>, so users can easily track and follow conversations they’re part of!\u003C\u002Fp>","76_11zon_b4telzuh2v.webp","https:\u002F\u002Ftwsme-r2.tumwebsme.com\u002Fsclblg987654321\u002Fvucrvpad4des1xv\u002F76_11zon_b4telzuh2v.webp","2026-03-04 08:48:50.663Z","",{"keywords":15,"locale":63,"school_blog":73},[16,23,28,33,38,43,48,53,58],{"collectionId":17,"collectionName":18,"created":19,"created_by":13,"id":20,"name":21,"updated":22,"updated_by":13},"sclkey987654321","school_keywords","2026-03-04 08:48:46.903Z","wqd5lairiftowzr","Frontend","2026-04-10 16:13:54.137Z",{"collectionId":17,"collectionName":18,"created":24,"created_by":13,"id":25,"name":26,"updated":27,"updated_by":13},"2026-03-04 08:44:53.062Z","puutdnxuitnxxgq","Backend","2026-04-10 16:12:51.264Z",{"collectionId":17,"collectionName":18,"created":29,"created_by":13,"id":30,"name":31,"updated":32,"updated_by":13},"2026-03-04 08:20:11.547Z","ey3puyme01a9bsw","Go","2026-04-10 16:07:25.893Z",{"collectionId":17,"collectionName":18,"created":34,"created_by":13,"id":35,"name":36,"updated":37,"updated_by":13},"2026-03-04 08:20:33.316Z","ln1ntwattzmxo0o","programming","2026-04-10 16:07:27.299Z",{"collectionId":17,"collectionName":18,"created":39,"created_by":13,"id":40,"name":41,"updated":42,"updated_by":13},"2026-03-04 08:48:36.524Z","e4ajo6uxyr7u8et","WebSocket Feature","2026-04-10 16:13:50.796Z",{"collectionId":17,"collectionName":18,"created":44,"created_by":13,"id":45,"name":46,"updated":47,"updated_by":13},"2026-03-04 08:48:36.198Z","2bk87nwjgolgc4t","Chat App Development","2026-04-10 16:13:50.662Z",{"collectionId":17,"collectionName":18,"created":49,"created_by":13,"id":50,"name":51,"updated":52,"updated_by":13},"2026-03-04 08:48:49.845Z","vu733qy3r1193v2","Reply to Message","2026-04-10 16:13:54.819Z",{"collectionId":17,"collectionName":18,"created":54,"created_by":13,"id":55,"name":56,"updated":57,"updated_by":13},"2026-03-04 08:46:14.782Z","v0mhensk18fofru","WebSocket Chat","2026-04-10 16:13:10.563Z",{"collectionId":17,"collectionName":18,"created":59,"created_by":13,"id":60,"name":61,"updated":62,"updated_by":13},"2026-03-04 08:34:00.920Z","ecac9y661or1xka","WebSocket","2026-04-10 16:08:05.227Z",{"code":64,"collectionId":65,"collectionName":66,"created":67,"flag":68,"id":69,"is_default":70,"label":71,"updated":72},"en","pbc_1989393366","locales","2026-01-22 11:00:02.726Z","twemoji:flag-united-states","qv9c1llfov2d88z",false,"English","2026-04-10 15:42:46.825Z",{"category":74,"collectionId":75,"collectionName":76,"created":13,"expand":77,"id":91,"slug":92,"updated":13,"views":93},"wqxt7ag2gn7xcmk","pbc_2105096300","school_blogs",{"category":78},{"blogIds":79,"collectionId":80,"collectionName":81,"created":82,"created_by":13,"id":74,"image":83,"image_alt":13,"image_path":84,"label":85,"name":86,"priority":87,"publish_at":88,"scheduled_at":13,"status":89,"updated":90,"updated_by":13},[],"sclcatblg987654321","school_category_blogs","2026-03-04 08:33:53.210Z","59ty92ns80w_15oc1implw.png","https:\u002F\u002Ftwsme-r2.tumwebsme.com\u002Fsclcatblg987654321\u002Fwqxt7ag2gn7xcmk\u002F59ty92ns80w_15oc1implw.png",{"en":86,"th":86},"Golang The Series",1,"2026-03-16 04:39:38.440Z","published","2026-04-25 02:32:15.470Z","tfjiw54rh3j333a","reply-message-websocket-chat",227,"vucrvpad4des1xv",[20,25,30,35,40,45,50,55,60],"2025-06-18 04:47:08.099Z","Learn how to add a \"Reply to Message\" feature in WebSocket Chat, allowing users to reply to any message they've already sent. This feature helps to improve the chat app by allowing message threading and provides a more organized user experience.","2026-05-06 08:38:23.610Z",{"th":92,"en":92}]