From b2b8daf670a0ef6c796c0113f42792e22e672d88 Mon Sep 17 00:00:00 2001 From: tigattack <10629864+tigattack@users.noreply.github.com> Date: Mon, 2 Nov 2026 21:52:58 +0000 Subject: [PATCH 1/4] feat(privacy): add cog for privacy policy --- README.md | 9 +++++ privacy/__init__.py | 11 ++++++ privacy/info.json | 16 +++++++++ privacy/privacy.py | 52 +++++++++++++++++++++++++++ privacy/privacy_policy.md | 74 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 162 insertions(+) create mode 100644 privacy/__init__.py create mode 100644 privacy/info.json create mode 100644 privacy/privacy.py create mode 100644 privacy/privacy_policy.md diff --git a/README.md b/README.md index 59e6eebd..dd2b311f 100644 --- a/README.md +++ b/README.md @@ -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) @@ -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. @@ -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. diff --git a/privacy/__init__.py b/privacy/__init__.py new file mode 100644 index 00000000..809c06e9 --- /dev/null +++ b/privacy/__init__.py @@ -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()) diff --git a/privacy/info.json b/privacy/info.json new file mode 100644 index 00000000..a7e78ed8 --- /dev/null +++ b/privacy/info.json @@ -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." +} diff --git a/privacy/privacy.py b/privacy/privacy.py new file mode 100644 index 00000000..d621caf3 --- /dev/null +++ b/privacy/privacy.py @@ -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) diff --git a/privacy/privacy_policy.md b/privacy/privacy_policy.md new file mode 100644 index 00000000..4b074187 --- /dev/null +++ b/privacy/privacy_policy.md @@ -0,0 +1,74 @@ +# 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. Other than that, the only content we keep is content you deliberately save (e.g. tags). 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. +- 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). From 1d0d6bb4499c6e6e4148e8f1b05da70a1f949f45 Mon Sep 17 00:00:00 2001 From: tigattack <10629864+tigattack@users.noreply.github.com> Date: Mon, 2 Nov 2026 22:00:10 +0000 Subject: [PATCH 2/4] style(privacy): correct formatting --- privacy/privacy_policy.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/privacy/privacy_policy.md b/privacy/privacy_policy.md index 4b074187..9c567a17 100644 --- a/privacy/privacy_policy.md +++ b/privacy/privacy_policy.md @@ -4,8 +4,7 @@ _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"). +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. From c1b9aac0eb12fab6da9a3cce865cc4c0034ea890 Mon Sep 17 00:00:00 2001 From: tigattack <10629864+tigattack@users.noreply.github.com> Date: Mon, 2 Nov 2026 22:14:14 +0000 Subject: [PATCH 3/4] fix(privacy): clarify message content retention --- privacy/privacy_policy.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/privacy/privacy_policy.md b/privacy/privacy_policy.md index 9c567a17..fed5067c 100644 --- a/privacy/privacy_policy.md +++ b/privacy/privacy_policy.md @@ -32,7 +32,7 @@ This policy explains what data the bot accesses through the Discord API, why, ho ### 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. Other than that, the only content we keep is content you deliberately save (e.g. tags). We do **not** use message content to train machine-learning or AI models. +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 From fb83aca91fe6b433590d1d2e511635e11c2014f7 Mon Sep 17 00:00:00 2001 From: tigattack <10629864+tigattack@users.noreply.github.com> Date: Mon, 2 Nov 2026 22:14:27 +0000 Subject: [PATCH 4/4] fix(privacy): clarify data retention policy for deletion requests --- privacy/privacy_policy.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/privacy/privacy_policy.md b/privacy/privacy_policy.md index fed5067c..3eab59d4 100644 --- a/privacy/privacy_policy.md +++ b/privacy/privacy_policy.md @@ -57,7 +57,7 @@ We do **not** sell, rent, or share your personal data with advertisers or unrela ## 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. +- **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