guardmyflair — Devpost Submission


🏷️ Elevator Pitch

Auto-enforces post flair rules — warns, waits, then removes unflair'd posts automatically.


💡 Inspiration

Every Reddit moderator knows the pain: a user submits a post with no flair, the mod team notices it hours later, manually removes it, sends a message explaining why — and then the same user does it again next week. Multiply that across dozens of posts a day on an active subreddit and moderation becomes a second job.

The pain isn't just time. It's inconsistency. Different mods enforce flair rules differently. Some are lenient, some strict. Users get confused because the rules feel arbitrary. New mods don't always know the protocol. The enforcement gap creates frustration on both sides of the mod queue.

We looked at existing PRAW bots — particularly the open-source FM_Flair_Bot built for r/FootballManagerGames — and saw a tool that solved this problem brilliantly, but was locked behind a wall of self-hosting, manual credential management, and Python server maintenance. Only technically skilled mod teams could run it. Everyone else was on their own.

We asked: what if any mod, on any subreddit, regardless of technical skill, could have this running in 60 seconds?

That question became guardmyflair.


⚙️ What It Does

guardmyflair is a fully automated flair enforcement system for Reddit moderators, built on Devvit. It requires zero server setup, zero coding knowledge, and zero ongoing maintenance. Mods install it once, configure it in a settings panel, and it runs silently in the background forever.

The Core Flow

  1. A user submits a post without a flair (or with an invalid flair not in the allowed list)
  2. guardmyflair instantly posts a friendly bot comment listing the available flairs and a countdown — "You have 30 minutes to flair your post"
  3. The user has two options to comply:
    • Flair the post manually using Reddit's built-in flair selector
    • Reply to the bot comment with !flair Discussion — the bot sets the flair instantly, no Reddit UI needed (critical for mobile users)
  4. If the user flairs the post (either way), guardmyflair detects it, deletes its own comment, and approves the post
  5. If the grace period expires with no flair, guardmyflair automatically removes the post, posts a removal explanation, and optionally notifies the mod team via modmail

What Makes It Different From Every Other Flair Tool

No existing Devvit app does all five of these things together:

  • Timed enforcement — not just detection, but scheduled removal after a configurable grace period
  • !flair self-assign command — users fix their own posts without mod intervention, directly from a comment reply
  • Zero server setup — Reddit hosts everything via Devvit; mods never touch a terminal
  • Mod override menu — right-click any post to exempt it from enforcement with one click
  • Works on any subreddit — fully configurable via an in-app settings panel, not hardcoded for one community

It works identically for a 500-member hobby sub and a 2-million-member news sub. The enforcement is consistent, automatic, and fair — every user gets the same grace period, the same instructions, the same outcome.


🔨 How We Built It

guardmyflair is a port of the open-source PRAW bot FM_Flair_Bot (GPL-3.0) to Reddit's Devvit platform, rebuilt from the ground up in TypeScript.

Architecture

The app is entirely background-based — no interactive UI, no custom post types. It consists of seven modules:

  • main.ts — Registers all triggers, scheduler jobs, and mod menu items
  • flairwatcher.ts — Handles the PostSubmit event; detects missing/invalid flairs and kicks off enforcement
  • flairchecker.ts — Pure validation logic; determines if a post's flair is valid, missing, or invalid
  • enforcer.ts — Executes removal, approval, and !flair command handling
  • storage.ts — All Redis reads and writes; tracks pending posts and exemptions
  • notifier.ts — Builds and sends bot comments, removal messages, and modmail
  • overridemenu.ts — Mod context menu for exempting posts and checking status

The Three Key Technical Translations (PRAW → Devvit)

1. Polling loop → Event triggers The original PRAW bot ran subreddit.stream.submissions() — an infinite loop checking for new posts every few seconds. guardmyflair uses Devvit's PostSubmit trigger, which fires instantly the moment a post is created. No polling, no rate limits, no missed posts.

2. SQLite → Redis FM_Flair_Bot stored pending post IDs in a local SQLite database. If the server crashed, the data was gone. guardmyflair uses Devvit's hosted Redis — persistent, fast, and managed entirely by Reddit's infrastructure.

3. time.sleep() loops → Devvit Scheduler The original bot re-checked pending posts in a continuous loop with sleep delays. guardmyflair uses the Devvit Scheduler API to queue a single job per post, timed to fire exactly at the grace period deadline. One job, one execution, no polling.

Stack

  • Language: TypeScript (strict mode)
  • Platform: Devvit (Reddit Developer Platform)
  • Storage: Devvit Redis
  • Scheduling: Devvit Scheduler API
  • Triggers: PostSubmit, CommentSubmit
  • Original bot: FM_Flair_Bot (Python/PRAW) by u/swrj — GPL-3.0

🧱 Challenges We Ran Into

1. Eliminating the Polling Loop

The hardest conceptual shift was moving from a continuous polling model to a pure event-driven one. The original PRAW bot's timer was implicit — it checked the database on every loop iteration. In Devvit, there's no loop. We had to rethink enforcement as: "schedule a future action at the exact moment it needs to happen." The Devvit Scheduler API made this possible, but designing around it required rethinking the entire state machine.

2. The Manual Flair Detection Problem

When a user manually flairs a post (using Reddit's own UI, not the !flair command), Devvit doesn't fire a dedicated "PostFlaired" event. The only way to detect it is to re-check the post's flair when the scheduler job fires. This means a user who flairs their post 5 minutes after submission still has the bot comment visible for the full grace period — a minor UX tradeoff we accepted in favor of architectural simplicity.

3. Flair Template ID Resolution

Setting a post's flair via API requires a flairTemplateId, not just the flair's display name. When a user types !flair Discussion, guardmyflair has to fetch all flair templates for the subreddit, match by name case-insensitively, and extract the ID. This adds an API call to every !flair command — wrapped carefully in error handling to degrade gracefully if the fetch fails.

4. State Cleanup Across Edge Cases

Many edge cases required careful Redis cleanup: posts deleted by the author before the deadline, posts where the scheduler fires but Redis has no record (already resolved), mod-exempted posts where the scheduler still fires. Each required explicit handling to avoid orphaned records or double-actions.


🏆 Accomplishments That We're Proud Of

Turning a self-hosted Python bot into a one-click install. The original FM_Flair_Bot required mods to set up a Python environment, manage Reddit API credentials in a config file, run a server 24/7, maintain a SQLite database, and update the code manually. guardmyflair replaced all of that with a single "Add to Community" button. That's the accomplishment we're most proud of — genuine accessibility for non-technical mod teams.

A flair enforcement system that's fair to users. Most flair enforcement is binary — post gets removed, user gets nothing. guardmyflair gives users a real chance: a clear warning, a specific deadline, and a dead-simple way to fix it from any device. The !flair command means even users on mobile who can't easily access Reddit's flair UI can comply with one comment reply.

Zero infrastructure for mods. Reddit hosts the app. Redis is managed by Reddit. The scheduler is managed by Reddit. Mods configure it with a settings panel that looks like any other app settings page. There is genuinely nothing for a mod to maintain after the initial 60-second setup.

Complete port fidelity. Every feature of the original FM_Flair_Bot is present in guardmyflair — plus five features the original never had: the !flair command, the mod override menu, configurable settings, modmail notifications, and the flair suggestions list in the bot comment.


📚 What We Learned

  • Event-driven thinking is fundamentally different from procedural polling. Building guardmyflair forced a complete mental model shift — instead of "check for X every N seconds," the question becomes "what event signals that X might have happened, and what do I do when it fires?"

  • Redis key design matters. Choosing the right key structure (pending:{postId}, exempt:{postId}) made the storage layer clean and the edge case handling straightforward. A poorly designed schema would have made cleanup logic a nightmare.

  • Graceful degradation is as important as the happy path. The bot comment failing to post shouldn't break flair tracking. The scheduler job should handle a missing Redis record without crashing. Every failure mode needed its own explicit outcome, not just a generic catch block.

  • The Devvit Scheduler is powerful but requires careful design. Once a job is scheduled, it will fire — even if the situation has changed. Every scheduler handler needs to re-validate the current state of the world before acting, not assume the state from when the job was created.


🚀 What's Next for guardmyflair

Flair Statistics Dashboard A mod-facing view showing which flairs are used most, which posts get removed most often, and which users are repeat offenders. Built directly into the mod context menu.

Reminder Comment A second bot comment posted halfway through the grace period ("⏰ Reminder: 15 minutes left to flair your post"). Reduces removals by giving users a second nudge before the deadline.

Appeal Workflow Allow removed users to reply to the removal comment with !appeal to flag the post for manual mod review instead of leaving with no recourse.

Long term — Reddit Developer Funds Once published and adopted by active communities, guardmyflair will qualify for Reddit Developer Funds — rewards for reaching engagement milestones. The goal is to make guardmyflair the default flair enforcement tool across Reddit.


Built for the Reddit Mod Tools & Migrated Apps Hackathon 2026 Original bot: FM_Flair_Bot by u/swrj — https://github.com/swrj/FM_Flair_Bot (GPL-3.0)

Built With

  • devvit
Share this project:

Updates