Discourse Daily Challenges

R23D_Printing
Sat, 21 Mar 2026 19:48:47 +0000
Plugin

| |
| Summary | Run time-limited challenges with leaderboards, automated posts, and badge awards.
| Repository Link | R23DPrinting-group / discourse-daily-challenge · GitLab
| Install Guide | How to install plugins in Discourse

Current Version: 1.5.0 (updated 4/2/2026)
License: MIT

The Story

I run a health and wellness community that recently migrated from Discord to Discourse. On Discord, I’d built a custom bot to run monthly fitness challenges — members would post their daily workouts, the bot tracked check-ins, posted weekly leaderboards, and announced winners at the end of each month. It was one of our most popular features.

After the move to Discourse, members started asking for the challenges back. I looked for an existing plugin and came up empty. So I built one.

What started as a quick solution turned into a full-featured challenge system that honestly works better than the original Discord bot. Since it might be useful to other communities, I’m sharing it here.

What It Does

discourse-daily-challenge lets you run structured, time-limited challenges directly in Discourse. Members check in by posting to a designated topic with a hashtag or photo. The plugin tracks everything automatically.

Core Features

Flexible Check-ins
Members check in by posting in the challenge topic with the configured hashtag or a photo attachment. Challenges can be configured for daily or weekly check-ins. The check-in window is evaluated in the challenge’s configured timezone, so global communities work correctly.

Live Leaderboard & Streaks
The admin dashboard shows real-time standings including total check-ins, current streaks, and completion percentage for every participant. Streak labels automatically reflect the challenge interval (“Day streak” vs “Week streak”).

Automated Leaderboard Posts
Set a day and time for a weekly automated leaderboard post directly to the challenge topic. A final results post is also generated automatically the day after the challenge ends.

Custom Badges
Define a minimum number of check-ins required to “complete” the challenge. Eligible participants automatically receive a custom Discourse badge when the challenge ends. The badge name auto-populates from the topic title.

Multiple Simultaneous Challenges
Run as many challenges as you want at the same time. Each challenge has its own topic, schedule, time zone, badge, and leaderboard.

Archived Challenges
Completed challenges are preserved in an archived accordion view in the dashboard, so you can look back at historical results.

Admin Check-in Management
Admins can manually add or remove check-ins — useful for catching missed posts or resolving disputes.

Manual Leaderboard Trigger
A “Post Leaderboard Now” button lets admins publish a leaderboard update on demand, outside the scheduled window.

Moderator Access
Full site moderators can create, edit, and manage challenges via a dedicated sidebar section. Can be enabled or disabled via site settings.

Category Moderator Access
Category moderators can manage challenges scoped to their assigned categories via a dedicated /challenges route — no admin access required. Can be enabled or disabled independently via site settings.

ChallengeBot DMs
If a bot account is configured, ChallengeBot automatically sends members a confirmation DM after each check-in (with streak info and a link to the topic), reminder DMs when they haven’t checked in for a few days, and responds to commands sent via @mention in challenge topics or directly via Discourse Messages — all responses come via DM. It also detects when a member edits a post to add a hashtag or photo, and counts it as a check-in if within the allowed window. Leaderboard and final results posts are also sent from ChallengeBot instead of the system account.

Installation

Add the following to your containers/app.yml under hooks > after_code > exec > cmd:

- git clone https://gitlab.com/r23dprinting-group/discourse-daily-challenge.git

Then rebuild:

cd /var/discourse && ./launcher rebuild app

After the initial install, future updates can be applied via the in-panel Update button unless otherwise noted in the changelog.

Configuration

Creating a Challenge

Navigate to Admin → Plugins → Challenges → Discourse Challenges and click New Challenge.

Field | Description
Topic ID | The Discourse topic where members will check in. The topic title will auto-populate the badge name field.
Hashtag Trigger | Required hashtag for check-ins (without #, e.g. workout)
Check-in Interval | Daily or weekly check-in mode
Week Start | For weekly challenges: which day starts the week (Sunday, Monday, or Saturday)
Start Date | First day of the challenge (inclusive)
End Date | Last day of the challenge (inclusive)
Challenge Timezone | Timezone for evaluating the check-in window (optional, defaults to UTC)
Check-ins Needed | Minimum check-ins to earn the completion badge
Description | Optional description of the challenge
Enable Weekly Leaderboard Post | Toggle automated weekly leaderboard posts
Post Day of Week | Day of week for the automated leaderboard post
Post Hour | Hour (0–23, in challenge timezone) for the automated leaderboard post
Award Completion Badge | Toggle automatic badge awarding at challenge end
Badge Name | Name of the badge to create and award — auto-populates from the topic title
Enable Reminder DMs | Send reminder DMs to participants who haven’t checked in recently (requires bot username to be configured). Defaults to enabled.

Site Settings

Setting | Default | Description
daily_challenge_enabled | true | Globally enable or disable the plugin
daily_challenge_mod_access_enabled | true | Allow full site moderators to manage challenges
daily_challenge_category_mod_access_enabled | true | Allow category moderators to manage challenges in their assigned categories
daily_challenge_bot_username | "" | Username of the bot account that sends DMs and posts leaderboards

How Check-ins Work

1. A member posts a reply to the challenge topic

2. The post must contain the configured hashtag or a photo attachment

3. The plugin checks whether the member has already checked in during the current period (day or week, depending on the challenge interval)

4. If not, the check-in is recorded and the leaderboard is updated

5. One check-in per member per period is allowed

Admins can view and manage all check-ins from the admin dashboard.

Moderator & Category Mod Access

Full site moderators can access challenge management via a CHALLENGES section in the main sidebar (if daily_challenge_mod_access_enabled is on).

Category moderators can access a scoped version at /challenges/dashboard and /challenges/challenges — they can only see and manage challenges linked to topics in their assigned categories. This requires daily_challenge_category_mod_access_enabled to be on and the user to be assigned as a category moderator via Admin → Categories → [Category] → Moderation.

Setting Up ChallengeBot

ChallengeBot is optional but enables DM features and attributed leaderboard posts. Skip this section if you don’t need DM functionality.

1. SSH into your server and run:

cd /var/discourse
./launcher enter app
rake admin:create

When prompted, enter the bot’s email and a strong password. Answer n to admin privileges.

2. In Admin → Users, find the newly created account and:

Click Approve

Set Trust Level to 1

Update the username to ChallengeBot (or your preferred name)

3. Optionally set a profile picture for the bot account.

4. Go to Admin → Plugins → Challenges → Settings and enter the exact username in the Bot username field. Note: this field is case-sensitive.

ChallengeBot Commands

Members can trigger commands by @mentioning the bot in any active challenge topic, or by sending a direct message to ChallengeBot via their profile. The bot always responds via DM and never posts in topics.

If you’re in multiple active challenges, ChallengeBot will ask you to pick one (or reply A for all).

Command | Description
status | Stats across all active challenges
leaderboard | Current standings for that challenge
streak | Your current streak
checkins | List of all your check-in dates
progress | Check-ins done vs needed, days remaining
help | List all available commands

Rate limited to 10 commands per user per hour.

Note: Set min_personal_message_post_length to 1 in site settings to allow short DM commands like status.

Automated Posts

Weekly Leaderboard

The plugin runs an hourly background job that checks whether it’s time to post the weekly leaderboard. When the configured day + hour arrives (in the challenge timezone), it creates a formatted post in the challenge topic showing the current standings.

Final Results Post

The day after the challenge ends, a final results post is automatically published. It lists all participants, their total check-ins, completion status, and congratulates badge earners.

Database Tables

daily_challenges — Challenge definitions

daily_check_ins — Individual check-in records per user per challenge per period

Compatibility

Discourse 3.x+

Tested on self-hosted installations

Ruby 3.x, Rails 7.x+

Roadmap (v1.6.0)

No specific features planned yet. Have a suggestion? Open an issue on GitLab or reply to this topic.

Changelog
Show Changelog (click for more details)

Feedback & Contributions

This plugin was built to solve a real need in our community, and I’m sharing it in case it helps yours. Issues, PRs, and feature requests are welcome on GitLab.

If you’re running a community where accountability and consistency matter — fitness, language learning, writing, creative habits — daily challenges can be a genuinely powerful engagement tool. I hope this plugin makes it easier to bring that to your Discourse community.

R23DPrinting-group / discourse-daily-challenge · GitLab

74 posts - 5 participants