pagechat

package module
v0.0.0-...-665c172 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 17, 2026 License: GPL-3.0 Imports: 10 Imported by: 0

README

PageChat

Real-time chat for any website. Drop a script tag on your site and let visitors chat with each other — no accounts, no databases, no third-party services.

CI Go Report Card

Features

  • Per-page chat rooms — visitors on the same URL automatically share a room
  • Built-in UI — beautiful chat interface at / and an embeddable widget for any site
  • Zero configuration — single binary, runs anywhere
  • Profanity filter — built-in content filtering powered by go-away
  • Message history — configurable TTL, served over a REST API
  • Lightweight — no database required, messages stored in-memory
  • Embeddable — use as a standalone server or import as a Go library
  • Production-ready — graceful shutdown, structured logging, health checks, CORS

Quick Start

Binary
# Install
go install github.com/akhil-datla/pagechat/cmd/pagechat@latest

# Run
pagechat --port 8080 --filter
Docker
docker run -p 8080:8080 ghcr.io/akhil-datla/pagechat:latest
From Source
git clone https://github.com/akhil-datla/pagechat.git
cd pagechat
make run

Built-in UI

Start the server and open http://localhost:8080 in your browser to use the full-page chat interface. It includes username selection, message history, connection status, and auto-reconnect.

Embeddable Widget

Add a single script tag to any website to get a floating chat bubble:

<script src="https://your-pagechat-server.com/widget.js"></script>

The widget automatically detects the server URL from the script's src attribute.

Widget Options

Configure via data-* attributes on the script tag:

<script
  src="https://your-pagechat-server.com/widget.js"
  data-position="bottom-left"
  data-theme="dark"
></script>
Attribute Default Options
data-server (auto-detected) Override server URL
data-position bottom-right bottom-right, bottom-left
data-theme light light, dark

Custom Integration

For full control, connect directly via WebSocket:

<script>
  const ws = new WebSocket(
    `ws://localhost:8080/ws?website=${encodeURIComponent(location.href)}`
  );

  ws.onmessage = (event) => {
    const msg = JSON.parse(event.data);
    console.log(`[${msg.username}] ${msg.content}`);
  };

  function sendMessage(username, content) {
    ws.send(JSON.stringify({ username, content }));
  }
</script>
Fetch Message History
const url = encodeURIComponent(location.href);
const res = await fetch(`http://localhost:8080/api/messages?website=${url}`);
const messages = await res.json();

API Reference

Endpoint Method Description
/ GET Built-in chat UI
/widget.js GET Embeddable chat widget script
/ws?website=<url> GET WebSocket connection — joins the room for <url>
/api/messages?website=<url> GET Returns message history as JSON array
/api/health GET Health check — returns {"status": "ok"}
/api/stats GET Server stats — rooms, clients, messages, uptime
Message Format

Send (client → server):

{ "username": "alice", "content": "Hello everyone!" }

Receive (server → client):

{
  "website": "https://example.com/page",
  "username": "alice",
  "content": "Hello everyone!",
  "timestamp": "2024-01-15T10:30:00Z"
}

Configuration

Flag Default Description
--port 8080 Server port
--ttl 24h Message time-to-live
--max-messages 1000 Max messages stored per room
--filter true Enable profanity filter
--version Print version and exit

Use as a Library

package main

import (
    "context"
    "log"
    "time"

    "github.com/akhil-datla/pagechat"
)

func main() {
    srv := pagechat.NewServer(pagechat.Config{
        Addr:          ":9090",
        MessageTTL:    12 * time.Hour,
        MaxMessages:   500,
        ContentFilter: true,
    })

    if err := srv.Start(); err != nil {
        log.Fatal(err)
    }
}

Architecture

┌─────────┐   WebSocket   ┌──────────┐   broadcast   ┌──────┐
│ Client 1 │──────────────▶│          │──────────────▶│Room A│
└─────────┘               │          │               └──────┘
                          │  Server  │
┌─────────┐   WebSocket   │          │   broadcast   ┌──────┐
│ Client 2 │──────────────▶│          │──────────────▶│Room B│
└─────────┘               │   Hub    │               └──────┘
                          │          │
┌─────────┐   REST API    │          │
│ Client 3 │──────────────▶│          │
└─────────┘               └──────────┘
  • Server — HTTP server with graceful shutdown, CORS, and routing
  • Hub — manages rooms, broadcasts messages, stores history
  • Client — WebSocket connection with read/write pumps and keepalive
  • Room — per-website group of connected clients

Development

make test       # Run tests with race detector
make cover      # Generate coverage report
make lint       # Run golangci-lint
make build      # Build binary to bin/
make help       # Show all targets

License

GNU General Public License v3.0


Built by Akhil Datla

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Config

type Config struct {
	// Addr is the TCP address to listen on (default ":8080").
	Addr string

	// MessageTTL is how long messages are kept in history (default 24h).
	MessageTTL time.Duration

	// MaxMessages is the maximum messages stored per room (default 1000).
	MaxMessages int

	// ContentFilter enables profanity filtering on messages (default false).
	ContentFilter bool
}

Config configures a PageChat server.

type Message

type Message struct {
	Website   string    `json:"website"`
	Username  string    `json:"username"`
	Content   string    `json:"content"`
	Timestamp time.Time `json:"timestamp"`
}

Message represents a chat message exchanged in a room.

type Server

type Server struct {
	// contains filtered or unexported fields
}

Server is a PageChat WebSocket chat server.

func NewServer

func NewServer(cfg Config) *Server

NewServer creates a new PageChat server with the given configuration.

func (*Server) Close

func (s *Server) Close()

Close stops the hub cleanup goroutine without shutting down the HTTP server. Useful in tests where httptest.Server manages the listener.

func (*Server) Handler

func (s *Server) Handler() http.Handler

Handler returns the HTTP handler, useful for testing or embedding.

func (*Server) Shutdown

func (s *Server) Shutdown(ctx context.Context) error

Shutdown gracefully shuts down the server.

func (*Server) Start

func (s *Server) Start() error

Start starts the server and blocks until it's shut down.

type Stats

type Stats struct {
	ActiveRooms    int    `json:"active_rooms"`
	ActiveClients  int    `json:"active_clients"`
	StoredMessages int    `json:"stored_messages"`
	Uptime         string `json:"uptime"`
}

Stats contains server statistics.

Directories

Path Synopsis
cmd
pagechat command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL