DEV Community

Nazma Akter
Nazma Akter

Posted on

Why we treat chat as a product, not a channel

Most creators who sell a paid community run it on rented tools. The payment goes through Stripe or Gumroad, the conversation happens in WhatsApp or Discord, and someone has to remember to remove people when they stop paying.

While building Group Chat for VeloxonHub, we made one decision that most of the design follows from: a group chat is a product, just like a course or a membership.

What "chat as a product" means in practice

A group chat has:

  • Prices. Chat prices are the same price objects the rest of the platform uses, so a room can be sold as a subscription, a one-time purchase or any other pricing model the editor supports. We didn't write separate billing code for chat.
  • Members and entitlement. Who can read and post is decided by entitlement, not by an invite link. When a subscription ends, access ends with it.
  • A public page. Each room gets SEO metadata and a public sales page, so people can find a paid room through search and buy it, just like a course landing page.
  • Plan limits. The number of rooms is a plan limit (5, 20 or unlimited), checked the same way as other products.

The realtime part

Messages are delivered over a socket. History is loaded over REST and the socket pushes new messages. On top of that we built what people expect from a modern chat:

  • reactions, pins, edit and delete
  • voice notes recorded in the browser, plus file attachments
  • mute, read marks, unread badges and online status
  • message reporting that goes into an admin moderation queue

Private 1-to-1 chat and group chat run on one shared chat engine. Creators can sell paid access to themselves as a separate product, and we only maintain one messaging stack.

Two lessons we learned

1. Read state lives in two places. The server stores read marks, and the client keeps local marks so the UI responds instantly. If you update only one of them, the unread badge shows the wrong count. Every path that marks a conversation as read now updates both.

2. Every message write has to go through the live connection. We once added a message action that wrote only through REST. It saved correctly but didn't appear for anyone until they reloaded. Now the socket hook owns the live state, and every write path must go through it.

What it isn't

To be clear about the limits: this is messaging between a creator and their audience, not a Slack replacement. It has no voice or video channels and no nested channels with threads. We left those out on purpose. The goal is a room people pay to join that sits next to the course they bought, not a workplace tool.

Try it

If you sell courses, coaching or a community and you're tired of maintaining a Discord bot just to check who has paid, have a look: https://veloxonhub.com

I'm happy to answer questions in the comments about the entitlement model or the socket setup.

Top comments (0)