Skip to content

HelloLingC/MoonTalk

Repository files navigation

MoonTalk

A modular comment widget with voting for static or dynamic websites.

Quick Start

<div id="moontalk-container"></div>
<script type="module">
  import MoonTalk from 'https://comment.moonlab.top/moontalk.js';

  const widget = new MoonTalk({
    server: 'https://comment.moonlab.top',
    postId: 'my-post-key',
    element: '#moontalk-container',
    theme: 'dark',
    siteName: 'example.com',
    latestCommentsLimit: 5,
  });

  widget.mount();
</script>

Frontend API

Create and mount widget:

const widget = new MoonTalk({
  server: 'https://comment.moonlab.top',
  postId: 'my-post-key',
  element: '#moontalk-container',
  theme: 'auto', // 'auto' | 'light' | 'dark'
  siteName: 'example.com',
  latestCommentsLimit: 5,
  pageSize: 10,
});

await widget.mount();

Backend API (v2)

Create comment

  • POST /api/v2/posts/:postId/comments
  • Body:
{
  "username": "alice",
  "content": "hello world",
  "email": "[email protected]",
  "website": "https://example.com",
  "parent_id": 1,
  "reply_to": 2
}

List comments

  • GET /api/v2/posts/:postId/comments?page=1&limit=10
  • Response envelope:
{
  "data": [
    {
      "id": 1,
      "postId": "my-post-key",
      "parentId": null,
      "replyTo": null,
      "username": "alice",
      "content": "hello",
      "createdAt": "2026-01-01T00:00:00.000Z",
      "hasChildren": true,
      "children": []
    }
  ],
  "meta": {
    "page": 1,
    "limit": 10,
    "totalPages": 1,
    "totalRoots": 1,
    "totalComments": 1
  }
}

Latest comments

  • GET /api/v2/comments/latest?site=example.com&limit=5

RSS feed (latest comments)

  • GET /rss/comments.xml?site=example.com&limit=20
  • Returns RSS 2.0 XML with latest comments for a site (or all sites when site is omitted).
  • limit range: 1-20 (default 5).

Read vote summary

  • GET /api/v2/posts/:postId/votes

Set vote

  • PUT /api/v2/posts/:postId/vote
  • Body: { "value": -1 | 0 | 1 }

Response Contract

Success:

{ "data": {}, "meta": {} }

Error:

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Human readable error",
    "details": {}
  }
}

Content Policy

Comments are plain text only. HTML is not rendered.

Database Migration

Run:

  • /Users/lingc/Projects/nodejs/MoonTalk/db/migrations/001_v2_optimizations.sql

It adds:

  • Unique index for votes on (post_id, ip)
  • Vote value check constraint
  • Query indexes for comments and latest comments

Development

Install dependencies and run server:

pnpm install
pnpm start

Run tests:

pnpm test

About

a simple comment system

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors