← Back to Blog
CommunityeducationOnboardingoperationsdocumentationreporting

How to Host Course Content in a Discord Community and Still Know Who Finished

The boundary between the material and the conversation, and the role based record that gives you a completion number without building anything.

September 6, 2026

Article image
🗒️
How to host course content in a Discord community without losing the completion record: the material sits on one page you own and can measure, the questions and the cohort stay in the server, and a role granted at each stage keeps the record readable. Messages are events, so progress needs a home that reports per person.

The short version

One page you own holds the lessons. The server holds the people talking about them. A single link connects the two, and a role per stage records who is through. Build it that way and the completion number exists before anyone asks for it.

Teams usually start from the other direction, and the reasoning is fair. Members open the server daily and open almost nothing else, so putting the lessons where the attention already is looks like the efficient move. The arrangement survives until the first review, when a straightforward question about how many members completed the training turns out to have no answer anywhere in the system.

Messages are events, roles are state

A server is a stream of messages. Each message says something happened. None of them say anything durable about a person.

Work through what that costs you. You can confirm a lesson was posted, and that is the end of what the platform will tell you. Who opened it, who abandoned it after a minute, who has been stuck on the same configuration step for weeks: none of it is recorded, because none of it is a message.

Reactions get used as a substitute and fail slowly enough to feel like they are working. Some members react out of courtesy. Some react to save something for later and never return. All of the reactions vanish when the message gets edited or reposted, which happens every time the material is corrected.

Roles behave differently, and the difference is the whole opportunity here. A role persists on a member until somebody removes it. That makes it the one part of a server that stores a fact about a person rather than a moment in time.

⚙️
The practical consequence. Anything you will be asked to count belongs somewhere that counts per person. Anything that is genuinely a conversation belongs in the server, where conversation is the native format.

A single test for every piece of material

Run each item past one question. Do you need to know, per person, whether they consumed this?

A yes sends it to a page you control. A no leaves it in the server. Applied honestly, the test sorts an entire program in about ten minutes.

What ends up in the server:

  • Questions about a lesson, in threads rather than a running chat
  • Cohort conversation, introductions, and peer review
  • Office hours and live sessions
  • The announcement that a lesson is live
  • Accountability nudges between members

What ends up on the page you own:

  • Lesson videos and written material
  • The completion record
  • Version history, so a correction replaces the mistake instead of sitting below it
  • Templates, worksheets, and anything downloadable
  • Every figure you will be asked to report

The split is not arbitrary. The first list is people talking, which a server does better than any page. The second list is a record, and records need a home that can be corrected, versioned, and counted.

The build

Step one: write the questions you will be asked

How many started, how many finished, who is stuck and where. Three questions, written before any channel is created. They set the requirements for everything that follows, and they stop you building something elegant that cannot answer them.

Step two: one canonical home, links only

One page, one path, one owner. Channels link to it. Nothing is ever pasted in as a copy, because a copy becomes a competing version within weeks and members trust whichever one they find first.

Step three: a forum channel per module, with a fixed tag set

Threads keep each question separate and searchable in a way a chat channel never manages. Four tags are usually enough: setup, stuck, feedback, finished. A member filters straight to their own situation instead of scrolling through everyone else's.

Step four: roles as the ledger

One role per stage, granted by whoever verifies the work rather than claimed by the member. Read the member list and you can see the shape of the cohort without opening anything else.

Step five: one naming convention, fixed on day one

Channels, roles, and lesson titles carry the same module number. A member learns the pattern once and then navigates the rest without asking. Renaming a live server later is work nobody has time for.

Step six: publish through a webhook

A lesson going live on your page fires the announcement into the server automatically. The announcement stops being a task somebody forgets and becomes a byproduct of publishing.

Step seven: office hours attached to a module

A session named after module three, held the week module three lands, gets attendance. A standing open call gets three people and a lot of silence.

Step eight: one weekly line from each side

Views, completions, and the drop off point come from your page. Open questions and office hours attendance come from the server. Two lines in whatever report your team already writes.

A compact map keeps the whole thing legible to anyone who joins the team later.

lessons        -> your page (one canonical URL per module)
questions      -> #module-N-questions (forum: setup / stuck / feedback / finished)
completion     -> role: "Module N Complete", granted by the reviewer
live layer     -> office hours named after the module of the week
announcements  -> webhook, fired by publishing
reporting      -> page for completions, server for questions

Size changes the answer

At roughly a hundred members you know who finished because you spoke to every one of them personally. Nothing breaks, which is exactly why the habit never gets built at the size where building it is free.

Around a thousand members, hand granted roles start slipping behind and the record goes stale in a way nobody notices for a month.

Around ten thousand, the material has to be findable or the same questions arrive every week, and the forum tag set stops being a nicety.

Approaching a hundred thousand, automation handles routing and role grants, and reporting becomes the constraint. By then, completion either already lives somewhere countable or it does not exist at all.

The cost curve runs the wrong way. This is a single afternoon at the size where nothing hurts, and a migration under live members at the size where it does.

Where this sits in the bigger build

This is one layer of a community operating stack. The others are onboarding and the first forty eight hours, role and channel architecture, support routing and escalation, response time, documentation, automation coverage, and reporting. Every one of them shares the same shape: inexpensive while the community is small, and expensive once members have built habits around it.

Building this layer properly will surface the layers beneath it. A question sitting unanswered for two days in a well organised forum channel is a response time problem wearing a different hat. A member finishing module one with no idea what happens next is a gap between education and onboarding. The course layer is complete work on its own, and it also acts as a diagnostic for what to build next.

Start here

List every piece of teaching material currently living in a channel. Run each one past the single question: do you need to know, per person, whether they consumed it. Move every yes onto one page, leave a link where it used to be, and create the role for the first stage.

An hour of sorting separates a community that teaches from a community that can show its work.


A community that teaches well and records nothing looks identical to a community doing neither, right up until somebody asks. Build the record early and the question stops being uncomfortable. More at danieljeong.org.

Want a properly managed community?

Get Your Free Analysis →