{"id":34611729,"url":"https://github.com/jinglemansweep/rtbf","last_synced_at":"2026-05-22T23:32:46.537Z","repository":{"id":311184879,"uuid":"1042799874","full_name":"jinglemansweep/rtbf","owner":"jinglemansweep","description":"Right To Be Forgotten","archived":false,"fork":false,"pushed_at":"2025-08-24T22:23:20.000Z","size":129,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-12-26T02:59:36.623Z","etag":null,"topics":["claude-ai","comment","eu","privacy","purge","reddit"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jinglemansweep.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-08-22T15:40:40.000Z","updated_at":"2025-08-24T22:23:23.000Z","dependencies_parsed_at":"2025-08-22T17:56:25.582Z","dependency_job_id":"9489d1c0-b8f3-4a2b-9ec9-dbda907c2848","html_url":"https://github.com/jinglemansweep/rtbf","commit_stats":null,"previous_names":["jinglemansweep/rtbf"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/jinglemansweep/rtbf","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jinglemansweep%2Frtbf","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jinglemansweep%2Frtbf/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jinglemansweep%2Frtbf/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jinglemansweep%2Frtbf/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jinglemansweep","download_url":"https://codeload.github.com/jinglemansweep/rtbf/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jinglemansweep%2Frtbf/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33376126,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-22T21:56:13.512Z","status":"ssl_error","status_checked_at":"2026-05-22T21:56:10.769Z","response_time":265,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["claude-ai","comment","eu","privacy","purge","reddit"],"created_at":"2025-12-24T14:16:22.352Z","updated_at":"2026-05-22T23:32:46.506Z","avatar_url":"https://github.com/jinglemansweep.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# RTBF - Right To Be Forgotten\n\n[![License](https://img.shields.io/badge/License-GPL_v3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0)\n[![Python](https://img.shields.io/badge/Python-3.12+-blue.svg)](https://www.python.org/)\n[![Code Quality](https://github.com/jinglemansweep/rtbf/actions/workflows/code-quality.yml/badge.svg)](https://github.com/jinglemansweep/rtbf/actions/workflows/code-quality.yml)\n[![Docker Build and Push](https://github.com/jinglemansweep/rtbf/actions/workflows/docker-build.yml/badge.svg)](https://github.com/jinglemansweep/rtbf/actions/workflows/docker-build.yml)\n[![Code style: black](https://img.shields.io/badge/Code%20style-black-000000.svg)](https://github.com/psf/black)\n[![Typing: mypy](https://img.shields.io/badge/Typing-mypy-blue.svg)](https://mypy.readthedocs.io/)\n\nA Python tool for automatically managing Reddit comments using a two-stage privacy system. RTBF gives you control over your digital footprint on Reddit.\n\nRTBF first obfuscates comments (replacing content) after a short period, then permanently deletes them after a longer period, providing immediate privacy protection with the option for complete removal.\n\n## ✨ Features\n\n- **Two-Stage Privacy System**: Obfuscate comments first, then delete them permanently after a separate timeout\n- **Flexible Obfuscation**: Replace with custom text, random emojis, or AI-generated content\n- **Priority Handling**: Optimizes API usage when obfuscation and deletion timeouts are equal\n- **Continuous Monitoring**: Runs continuously in the background, checking for expired comments\n- **Rate Limited**: Built-in rate limiting to respect Reddit's API guidelines\n- **Docker Support**: Easy deployment with Docker containers\n- **Configurable**: Configuration options via environment variables\n- **Secure**: No storage of credentials - uses environment variables only\n\n## 🚀 Quick Start\n\n### Prerequisites\n\n- Python 3.11 or higher\n- Reddit account with API access\n- Reddit application credentials (see [Setup](#-setup))\n\n### Installation\n\n#### Using Poetry (Recommended)\n\n```bash\n# Clone the repository\ngit clone https://github.com/jinglemansweep/rtbf.git\ncd rtbf\n\n# Install dependencies with Poetry\npoetry install\n\n# Run the application\npoetry run rtbf\n```\n\n#### Using Docker\n\n```bash\n# Pull the image\ndocker pull ghcr.io/jinglemansweep/rtbf:latest\n\n# Run with environment file\ndocker run -it --env-file .env ghcr.io/jinglemansweep/rtbf:latest\n```\n\n#### Using pip\n\n```bash\n# Clone and install\ngit clone https://github.com/jinglemansweep/rtbf.git\ncd rtbf\npip install .\n\n# Run the application\nrtbf\n```\n\n## ⚙️ Setup\n\n### Two-Stage Privacy System\n\nRTBF uses separate timeouts for obfuscation and deletion:\n\n1. **Obfuscation Stage** (`EXPIRE_MINUTES`): Comments are replaced using the selected strategy\n2. **Destruction Stage** (`DELETE_MINUTES`): Comments are permanently deleted from Reddit\n\n### Obfuscation Strategies\n\nRTBF supports three obfuscation methods:\n\n- **update**: Replaces the comment content with custom text\n- **emoji**: Replaces the comment content with a random common emoji\n- **llm**: Uses AI/LLM to generate contextual replacement text\n\n**Priority Logic:**\n- If `DELETE_MINUTES == EXPIRE_MINUTES`: Comments are deleted immediately (skipping obfuscation)\n- If comment is already obfuscated and deletion time reached: Delete immediately\n- Otherwise: Obfuscate first, then delete when deletion time is reached\n\n### Ignore Flag Feature (\"Forget Never\")\n\nRTBF supports an ignore flag that allows you to protect specific comments from ever being processed. Any comment containing the ignore flag will be permanently skipped, regardless of age or strategy.\n\n- **FLAG_IGNORE**: Comments containing this text are never processed (default: `/fn`)\n- **Use Case**: Add `/fn` to important comments you want to keep forever\n- **Example**: \"This is my best comment ever! /fn\" will never be deleted or modified\n\n### Watermark Feature\n\nWhen using the \"update\" or \"emoji\" strategies, RTBF can append a watermark to replacement text to identify comments that have already been processed. This prevents the tool from repeatedly updating the same comments in future runs. Comments containing the watermark will be automatically skipped.\n\nThe watermark is formatted using Reddit's superscript markdown (e.g., `^(#rtbf)`) to make it less visually prominent while still being detectable.\n\n- **WATERMARK**: The text used to identify processed comments (default: `#rtbf`)\n- **APPEND_WATERMARK**: Whether to automatically append the watermark (default: `true`)\n\n### LLM Strategy\n\nThe LLM strategy uses AI to generate contextual replacements for comments. It supports OpenAI-compatible APIs including OpenAI, OpenRouter, Ollama, and other providers.\n\n**Configuration:**\n- **LLM_MODEL**: Model name (e.g., `gpt-3.5-turbo`, `claude-3-haiku`, `llama2`)\n- **LLM_PROMPT**: Template with `{comment}` placeholder for the original comment\n- **LLM_API_URL**: OpenAI-compatible `/v1/chat/completions` endpoint\n- **LLM_API_KEY**: API key (optional, not needed for Ollama or local providers)\n\n**Example Prompts:**\n- `\"Write the opposite of this: {comment}\"` - Generate contrarian responses\n- `\"Summarize this in one sentence: {comment}\"` - Create brief summaries\n- `\"Rewrite this comment as a haiku: {comment}\"` - Creative transformations\n- `\"Translate this to Spanish: {comment}\"` - Language translation\n\n**Error Handling:**\nIf the LLM API call fails (network issues, invalid API key, etc.), the strategy automatically falls back to using a random emoji instead of leaving the comment unchanged.\n\n**Supported Providers:**\n- **OpenAI**: `https://api.openai.com/v1/chat/completions`\n- **OpenRouter**: `https://openrouter.ai/api/v1/chat/completions`\n- **Ollama**: `http://localhost:11434/v1/chat/completions`\n- **Any OpenAI-compatible API**\n\n### 1. Reddit API Setup\n\n1. Go to [Reddit App Preferences](https://www.reddit.com/prefs/apps)\n2. Click \"Create App\" or \"Create Another App\"\n3. Fill in the details:\n   - **Name**: Choose any name (e.g., \"RTBF Comment Manager\")\n   - **App type**: Select \"script\"\n   - **Description**: Optional\n   - **About URL**: Optional\n   - **Redirect URI**: `http://localhost:8080` (required but not used)\n4. Note down your **Client ID** (under the app name) and **Client Secret**\n\n### 2. Environment Configuration\n\nCreate a `.env` file in the project root:\n\n```bash\n# Required Reddit API credentials\nREDDIT_USERNAME=your_reddit_username\nREDDIT_PASSWORD=your_reddit_password\nREDDIT_CLIENT_ID=your_client_id\nREDDIT_CLIENT_SECRET=your_client_secret\nREDDIT_USER_AGENT=RTBF/1.0 by u/your_username\n\n# Optional configuration (with defaults)\nEXPIRE_MINUTES=120                          # Minutes before obfuscation (2 hours)\nDELETE_MINUTES=1440                         # Minutes before deletion (24 hours)\nSTRATEGY=update                             # Obfuscation method: \"update\", \"emoji\", or \"llm\"\nREPLACEMENT_TEXT=[Comment deleted by user]  # Text to replace with if strategy=update\nLLM_MODEL=gpt-3.5-turbo                     # LLM model (for llm strategy)\nLLM_PROMPT=Rewrite this comment: {comment}  # LLM prompt template with {comment} placeholder\nLLM_API_URL=https://api.openai.com/v1/chat/completions  # OpenAI-compatible API endpoint\nLLM_API_KEY=your_api_key_here               # API key for LLM service (optional, not needed for Ollama)\nWATERMARK=#rtbf                             # Watermark to identify processed comments\nFLAG_IGNORE=/fn                             # Ignore flag - comments with this are never processed\nAPPEND_WATERMARK=true                       # Append watermark to replacement text\nLOG_LEVEL=INFO                              # Logging level (DEBUG, INFO, WARNING, ERROR, CRITICAL)\nCOMMENT_LIMIT=100                           # Maximum comments to retrieve per check\nCHECK_INTERVAL_MINUTES=10                   # Check every 10 minutes\n```\n\n## 📋 Configuration Options\n\n| Variable | Description | Default | Required |\n|----------|-------------|---------|----------|\n| `REDDIT_USERNAME` | Your Reddit username | - | ✅ |\n| `REDDIT_PASSWORD` | Your Reddit password | - | ✅ |\n| `REDDIT_CLIENT_ID` | Reddit app client ID | - | ✅ |\n| `REDDIT_CLIENT_SECRET` | Reddit app client secret | - | ✅ |\n| `REDDIT_USER_AGENT` | User agent string | `comment_manager by u/user` | ❌ |\n| `EXPIRE_MINUTES` | Minutes before comments are obfuscated | `120` | ❌ |\n| `DELETE_MINUTES` | Minutes before comments are permanently deleted | `1440` | ❌ |\n| `STRATEGY` | Obfuscation method: \"update\", \"emoji\", or \"llm\" | `update` | ❌ |\n| `REPLACEMENT_TEXT` | Replacement text for updates (ignored for emoji/llm strategies) | `[Comment deleted by user]` | ❌ |\n| `LLM_MODEL` | LLM model name | `gpt-3.5-turbo` | ❌ |\n| `LLM_PROMPT` | LLM prompt template with {comment} placeholder | `Rewrite this comment: {comment}` | ❌ |\n| `LLM_API_URL` | OpenAI-compatible API endpoint | `https://api.openai.com/v1/chat/completions` | ❌ |\n| `LLM_API_KEY` | API key for LLM service (optional for Ollama) | - | ❌ |\n| `WATERMARK` | Watermark to identify processed comments | `#rtbf` | ❌ |\n| `FLAG_IGNORE` | Ignore flag - comments containing this are never processed | `/fn` | ❌ |\n| `APPEND_WATERMARK` | Append watermark to replacement text | `true` | ❌ |\n| `LOG_LEVEL` | Logging level (DEBUG, INFO, WARNING, ERROR, CRITICAL) | `INFO` | ❌ |\n| `COMMENT_LIMIT` | Maximum number of comments to retrieve per check | `100` | ❌ |\n| `CHECK_INTERVAL_MINUTES` | Minutes between checks | `10` | ❌ |\n\n## 🐳 Docker Usage\n\n### Using Docker Compose\n\nCreate a `docker-compose.yml`:\n\n```yaml\nversion: '3.8'\nservices:\n  rtbf:\n    image: ghcr.io/jinglemansweep/rtbf:latest\n    env_file:\n      - .env\n    restart: unless-stopped\n    container_name: rtbf\n```\n\nRun with:\n```bash\ndocker-compose up -d\n```\n\n### Manual Docker Run\n\n```bash\n# Build locally\ndocker build -t rtbf .\n\n# Run with environment file\ndocker run -d --name rtbf --env-file .env rtbf\n\n# Or with individual environment variables\ndocker run -d --name rtbf \\\n  -e REDDIT_USERNAME=your_username \\\n  -e REDDIT_PASSWORD=your_password \\\n  -e REDDIT_CLIENT_ID=your_client_id \\\n  -e REDDIT_CLIENT_SECRET=your_secret \\\n  -e EXPIRE_MINUTES=120 \\\n  rtbf\n```\n\n## 🔧 Usage\n\n### Running the Application\n\n```bash\n# With Poetry\npoetry run rtbf\n\n# With Python module\npython -m rtbf\n\n# With pip installation\nrtbf\n```\n\n### Example Output\n\n```\n2024-01-15 10:30:00 - INFO - Starting comment manager...\n2024-01-15 10:30:00 - INFO - Configuration: EXPIRE_MINUTES=120, STRATEGY=delete, CHECK_INTERVAL=10\n2024-01-15 10:30:01 - INFO - Authenticated as: your_username\n2024-01-15 10:30:01 - INFO - Checking for comments older than 120 minutes (cutoff: 2024-01-15 08:30:01)\n2024-01-15 10:30:02 - INFO - Found expired comment from 2024-01-15 08:15:30: abc123\n2024-01-15 10:30:03 - INFO - Deleted comment: abc123\n2024-01-15 10:30:03 - INFO - Sleeping for 10 minutes...\n```\n\n## 🛡️ Security \u0026 Privacy\n\n- **No Data Storage**: RTBF doesn't store any of your comments or credentials\n- **Local Processing**: All processing happens locally or in your controlled environment\n- **Environment Variables**: Credentials are managed via environment variables\n- **Rate Limiting**: Built-in delays to respect Reddit's API limits\n- **Open Source**: Full source code available for audit\n\n## ⚠️ Important Notes\n\n1. **Irreversible**: Deleted comments cannot be recovered\n2. **API Limits**: Reddit has rate limits - the tool includes delays to respect them\n3. **New Comments**: Only processes comments older than the configured time\n4. **Active Monitoring**: The tool runs continuously and requires manual stopping\n\n## 🤝 Contributing\n\n1. Fork the repository\n2. Create a feature branch (`git checkout -b feature/amazing-feature`)\n3. Make your changes\n4. Run tests and linting (`poetry run pre-commit run --all-files`)\n5. Commit your changes (`git commit -m 'Add some amazing feature'`)\n6. Push to the branch (`git push origin feature/amazing-feature`)\n7. Open a Pull Request\n\n### Development Setup\n\n```bash\n# Clone and install development dependencies\ngit clone https://github.com/jinglemansweep/rtbf.git\ncd rtbf\npoetry install --with dev\n\n# Install pre-commit hooks\npoetry run pre-commit install\n\n# Run code quality checks\npoetry run black rtbf/\npoetry run flake8 rtbf/\npoetry run mypy rtbf/\n```\n\n## 📝 License\n\nThis project uses the GPL-3.0 license - see the [LICENSE](LICENSE) file for details.\n\n## ⚠️ Disclaimer\n\nThis tool is provided as-is for privacy management purposes. Users are responsible for:\n- Complying with Reddit's Terms of Service\n- Understanding the implications of automated comment deletion\n- Ensuring they have the right to delete their own content\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjinglemansweep%2Frtbf","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjinglemansweep%2Frtbf","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjinglemansweep%2Frtbf/lists"}