Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ Cogs for the [Red-DiscordBot](https://github.com/Cog-Creators/Red-DiscordBot/)-b
- [onboarding\_role](#onboarding_role)
- [Penis](#penis)
- [Phishingdetection](#phishingdetection)
- [Privacy](#privacy)
- [prometheus\_exporter](#prometheus_exporter)
- [Purge](#purge)
- [Quotes](#quotes)
Expand Down Expand Up @@ -89,6 +90,7 @@ A massive thank you to [all who've helped with this project](https://github.com/
- **[onboarding\_role](#onboarding_role):** Apply a role to users who complete onboarding.
- **[Penis](#penis):** Allows users to check the size of their penis.
- **[Phishingdetection](#phishingdetection):**
- **[Privacy](#privacy):** Displays the bot's privacy policy.
- **[prometheus\_exporter](#prometheus_exporter):** Exposes a HTTP endpoint for exporting guild metrics in Prometheus format.
- **[Purge](#purge):** This will purge users based on criteria.
- **[Quotes](#quotes):** Allows users to quote other users' messages in a quotes channel.
Expand Down Expand Up @@ -340,6 +342,13 @@ This cog allows users to check the size of their penis.

This cog automatically deletes any messages containing suspected phishing/scam links. This information is sourced from [phish.sinking.yachts](https://phish.sinking.yachts/)

### Privacy

This cog displays the bot's privacy policy, read from a markdown file embedded in the cog ([`privacy/privacy_policy.md`](privacy/privacy_policy.md)). Edit that file to update the policy.

- `[p]privacy` - Display the privacy policy as a paginated embed.
- `/privacy` - Same as above, as a slash command.

### Purge

This cog will purge users that hold no roles as a way to combat accounts being created and left in an un-verified state.
Expand Down
11 changes: 11 additions & 0 deletions privacy/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from redbot.core.bot import Red
from redbot.core.utils import get_end_user_data_statement

from .privacy import Privacy

__red_end_user_data_statement__ = get_end_user_data_statement(__file__)


async def setup(bot: Red):
"""Base setup function"""
await bot.add_cog(Privacy())
16 changes: 16 additions & 0 deletions privacy/info.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"author": [
"tigattack"
],
"short": "Display the bot's privacy policy.",
"description": "Serves the bot's privacy policy, viewable in Discord via the `[p]privacy` command or `/privacy` slash command. Edit `privacy/privacy_policy.md` in LabBot-Cogs to update the policy text.",
"disabled": false,
"name": "privacy",
"tags": [
"info",
"privacy"
],
"install_msg": "Usage: `[p]privacy` or `/privacy`. Edit `privacy/privacy_policy.md` in LabBot-Cogs to update the policy text.",
"min_bot_version": "3.5.1",
"end_user_data_statement": "This cog does not store any data about users. It only displays a static, pre-written privacy policy document."
}
52 changes: 52 additions & 0 deletions privacy/privacy.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
"""discord red-bot privacy policy cog"""

import logging
from pathlib import Path

import discord
from redbot.core import commands
from redbot.core.utils.chat_formatting import pagify
from redbot.core.utils.views import SimpleMenu

log = logging.getLogger("red.rhomelab.privacy")

POLICY_FILE = Path(__file__).parent / "privacy_policy.md"
EMBED_PAGE_LENGTH = 3900


class Privacy(commands.Cog):
"""Display the bot's privacy policy."""

def __init__(self) -> None:
pass

@staticmethod
def _read_policy() -> str | None:
try:
text = POLICY_FILE.read_text(encoding="utf-8").strip()
except OSError as error:
log.error("Could not read privacy policy file at %s: %s", POLICY_FILE, error)
return None
return text or None

@commands.hybrid_command(name="privacy")
async def privacy(self, ctx: commands.Context) -> None:
"""Show the bot's privacy policy."""
policy = self._read_policy()
if policy is None:
await ctx.send("Sorry, the privacy policy is currently unavailable. Please contact a moderator.")
return

chunks = list(pagify(policy, delims=["\n\n", "\n"], page_length=EMBED_PAGE_LENGTH))
total = len(chunks)
colour = await ctx.embed_colour()
pages: list[dict[str, str | discord.Embed] | discord.Embed | str] = [
discord.Embed(
title="LabBot Privacy Policy",
description=chunk,
colour=colour,
).set_footer(text=f"Page {index}/{total}")
for index, chunk in enumerate(chunks, start=1)
]

await SimpleMenu(pages, timeout=180).start(ctx)
73 changes: 73 additions & 0 deletions privacy/privacy_policy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# LabBot Privacy Policy

_Last updated: 2 November 2026_

## Who this covers

LabBot ("the bot", "we", "us") is a self-hosted moderation and community-utility Discord bot operated by the **r/Homelab Discord moderation team**. It runs on the open-source [Red-DiscordBot](https://github.com/Cog-Creators/Red-DiscordBot) ("Red") framework with custom ([LabBot-Cogs](https://github.com/rHomelab/LabBot-Cogs)) and third-party extensions ("cogs").

This policy explains what data the bot accesses through the Discord API, why, how long we keep it, how it is secured, and how you can access or delete it. It applies to the LabBot instance operated by the r/Homelab moderation team.

## Summary

- We collect only the data needed to run moderation and community features.
- We **do not** sell your data, share it with advertisers, or use it to train AI/ML models.
- Message content is used **transiently** for moderation (anti-phishing, channel rules, keyword auto-replies) and to process commands; we do not build profiles from your messages.
- Presence/activity is only ever stored as **anonymous aggregate counts**, never tied to an individual.
- Data is stored on our own infrastructure and is **encrypted at rest**.

## What data we access and why

### Data from your use of the bot

- **Commands you run.** When you invoke a command, the bot processes your message and may log the command name, channel, and timestamp for moderation accountability.
- **Opt-in account links & content.** If you use the Last.fm feature, we store the Last.fm username you choose to link to your Discord account. If you set reminders, we store the reminder text and time you provide. Tags/custom messages you create are stored with your user ID as creator/owner.

### Data used for moderation & community features

- **Moderation notes & warnings.** Moderators can record notes/warnings about a user. Each record contains the subject user's ID, the moderator-written text, the moderator's ID and name, and a timestamp. These are retained for ongoing moderation purposes.
- **Moderation case logs.** Moderation actions (e.g. timeouts, mutes, bans) are logged via Red's modlog and an extended mod-log cog, including the affected user's ID, the responsible moderator, a reason, and timestamps. When a message is deleted, its content may be logged to a moderator-only channel in Discord so moderators can review it for abuse, spam, or ban evasion.
- **Role & onboarding state.** To assign roles and send welcomes correctly, we store lists of member IDs who have completed onboarding, who have already been welcomed, and temporarily the roles a member held while in our "timeout" state, so they can be restored afterwards.
- **Purge exclusions.** User IDs that moderators have exempted from automated pruning of accounts that never verified.

### Message content

LabBot uses Discord's Message Content intent to: scan messages for known phishing/scam links and remove them; enforce per-channel content rules (length, required/forbidden media, account/guild age); respond to configured keyword triggers; and process prefix commands. Message content is processed in real time and is **not** retained to build profiles. When a message is deleted, our moderation tooling may log its content to a moderator-only channel in Discord so moderators can review it for abuse, spam, or ban evasion. It is not stored outside Discord and is not used to profile you. We do not otherwise retain message content. We do **not** use message content to train machine-learning or AI models.

### Presence & activity

LabBot uses the Presence intent only to produce **anonymous, aggregate counts** (for example, how many members are online/idle/offline, or how many are playing/streaming/listening). These counts contain no usernames, user IDs, or any per-user information, and no individual's presence or activity is stored or profiled. They are displayed as community activity graphs that members can view at https://labbot.tiga.tech.

## How your data is stored and secured

All persistent data is stored in the bot's own database on infrastructure we control. Data is **encrypted at rest.** Where off-site backups are used, they are also encrypted. Access is limited to the bot operators.

## Data retention

Moderation and operational data is retained for as long as it is needed for moderation and community management. In some cases this is indefinite, because historical moderation context remains relevant. You may request deletion at any time (see below). Anonymous aggregate statistics are not linked to you and are retained as long as they are useful.

## Third-party services & components

- **Self-hosted monitoring.** Anonymous aggregate statistics are stored in our own Prometheus instance and displayed via our own Grafana instance, accessible at https://labbot.tiga.tech. These are not third-party SaaS and the data is not shared externally.
- **Phishing blocklist.** The anti-phishing feature downloads a list of known scam domains from phish.sinking.yachts. Your messages are checked locally on our server and are **never** sent to that service.
- **Third-party cogs.** LabBot runs community-maintained cogs (e.g. Last.fm, reminders, moderation logging). Each handles only the data described above.

We do **not** sell, rent, or share your personal data with advertisers or unrelated third parties.

## Your rights: accessing and deleting your data

- **See what's stored:** run `^mydata whatdata` in the server (replace `^` with the bot's prefix) to see information about the data the bot's cogs hold about you.
- **Request deletion:** run `^mydata forgetme`, or contact the r/Homelab moderation team. The moderation team actions deletion requests; some records are removed manually, but genuine erasure requests are honored. Once a request is actioned, the data is removed from the live bot, but copies in encrypted backups persist until those backups expire after a short retention period.
- Data needed to keep the community safe (e.g. active ban/evasion evidence) may be retained where we have a legitimate interest, consistent with Discord's Developer Policy and Terms.

## Children's privacy

LabBot is not directed at children. You must meet Discord's minimum age requirements to use Discord and this bot. We do not knowingly collect data from anyone under the applicable minimum age.

## Changes to this policy

We may update this policy as the bot's features change. Material changes will be announced in the server and reflected by the "last updated" date above.

## Contact

Questions or data requests: contact the r/Homelab moderation team via the Discord server (https://discord.gg/homelab).
Loading