SYSADMIN_ARCHIVES
⭐ α Centauri A: RA 14h 39m
⭐ α Centauri B: Dec −60° 50′
Distance: 4.37 light-years
System: Triple star
def check_inactive_users():
    if days_inactive > 30:
        remove_user(user_id)
        send_notification()
*/5 * * * * check_new_users.py
0 3 * * * user_manager.py
# cron: 0 3 * * *
GET /api/users
POST /api/notifications
DELETE /api/v2/sharings/{id}
✓ 200 OK
CREATE TABLE user_activity (
  user_id INTEGER PRIMARY KEY,
  last_activity TEXT,
  is_protected INTEGER
);
┌─[Tautulli]────[API]
│       ↓
├─[Scripts]────[Cron]
│       ↓
└─[Plex.tv]───[Users: 61]
SMTP → Gmail → TLS:587
✉ Welcome | Warning | Removal
Status: ✅ Operational
🤖 Status: retired
👥 Active Users: 61
🛡️ Protected: 11
⏱️ Threshold: 30 days

Centauri (Plex) Automation System

Published Oct 2025 · system retired 2026
15 min read
◼ Retired

STATUS: RETIRED

This system no longer runs. It is documented here because building it and deciding to switch it off were both worth writing down, but everything below is written in the present tense and describes a machine that has been turned off.

It was retired for two independent reasons. The first is that it was built against the Plex.tv API — a third-party interface I did not control — and when Plex changed its pricing and policy, continuing to build against it stopped making sense. Roughly all of the integration work became worthless in an afternoon, which is the most useful lesson this project ever produced.

The second reason is less obvious and matters more. This automation existed to solve problems created by scale: detecting inactivity, warning people, removing accounts I had no personal relationship with. When the userbase came back down to close friends and family, that problem stopped existing. I did not rewrite it against Jellyfin’s API; I replaced the parts still worth having with maintained off-the-shelf tools and deleted the rest. Keeping software alive after its requirement has gone is its own kind of debt.

PythonAutomationPlexTautulliCronSQLiteDevOpsAPI Integration

1. System Overview

My Centauri Plex Automation System is a production-grade user lifecycle management platform that I built to handle everything from welcoming new users to automated cleanup of inactive accounts. What started as a simple script grew into a lifecycle suite that ran for 61 users with almost no day-to-day intervention.

I built this system with Python, integrated it with Tautulli for activity tracking, and leveraged the Plex.tv API for user management. It runs autonomously via cron jobs on my server, requiring virtually zero manual intervention.

61
Active Plex Users
4
Python Scripts
30d
Inactivity Threshold

2. Automated Workflows

✅

New User Detection

Checks every 5 minutes via cron. New users receive instant welcome emails with complete onboarding guide.

✅

Activity Tracking

Daily updates from Tautulli API monitoring all user watch history and play counts.

✅

Inactivity Warnings

Automated emails sent at 27 days of inactivity (3-day warning before removal).

✅

Automated Removal

Users removed from Plex after 30 days via DELETE /api/v2/sharings API endpoint.

✅

Email Notifications

Both admin and removed users receive professional notifications with re-join instructions.

✅

Protected User Whitelist

11 friends/family members permanently protected from automated removal.

3. System Architecture

My system consists of four core Python scripts that I orchestrated with cron jobs, backed by a SQLite database for state management, and integrated with Tautulli and Plex.tv APIs.

┌─────────────────────────────────────────────────────────┐
│              TAUTULLI SERVER (Activity Monitor)         │
│  API: http://192.168.1.xxx:8181/api/v2                │
└────────────────┬────────────────────────────────────────┘
                 │ API Calls (every 5 min & daily)
                 ▼
┌─────────────────────────────────────────────────────────┐
│            AUTOMATION SCRIPTS (Python)                  │
│                                                         │
│  check_new_users.py  │  user_manager.py                │
│  (Every 5 minutes)   │  (Daily at 3 AM)                │
│                                                         │
│  • Detect new users  │  • Update activity              │
│  • Send welcome      │  • Send warnings                │
│  • Notify admin      │  • Remove inactive              │
│                                                         │
│  Database: user_activity.db (SQLite)                   │
└────┬──────────────────────────────┬───────────────────┘
     │                               │
     │ SMTP (Gmail)                  │ Plex API
     ▼                               ▼
┌──────────────┐         ┌────────────────────────────┐
│ EMAIL SYSTEM │         │     PLEX.TV API            │
│              │         │  DELETE /api/v2/sharings   │
│ • Welcome    │         │  (Complete unfriending)    │
│ • Warnings   │         │                            │
│ • Removals   │         │                            │
└──────────────┘         └────────────────────────────┘

4. Core Scripts Breakdown

user_manager.py — Main Cleanup Engine

Location: /mnt/app-pool/config/tautulli/scripts/

Schedule: Daily at 3:00 AM (cron)

Functions:

  • Updates activity for all users from Tautulli API
  • Identifies inactive users (>30 days)
  • Sends warning emails (27 days inactive)
  • Removes users via Plex API (DELETE /api/v2/sharings/{userId})
  • Sends notifications to admin AND removed user
  • Cleans up database entries

check_new_users.py — Fast Detection

Schedule: Every 5 minutes (cron)

Purpose: Instant welcome emails without waiting for daily cleanup

  • Lightweight check for new users only
  • Sends instant welcome emails with Centauri branding
  • Notifies admin of new user addition
  • Does NOT do cleanup (separation of concerns)

config.py — Central Configuration

Single source of truth for all configuration:

  • Tautulli API settings
  • Plex server URL and authentication token
  • SMTP/Email configuration (Gmail with TLS)
  • Protected users whitelist (11 users)
  • HTML email templates
  • DRY_RUN mode toggle for testing

5. User Lifecycle Flow

Stage 1: New User Joins

Within 5 minutes, check_new_users.py detects the addition. User receives professional welcome email with complete onboarding guide, Overseerr request system info, and inactivity policy. Admin receives notification.

Stage 2: Active User

Daily user_manager.py updates last_activity timestamp and increments total_plays counter. No action taken. User continues enjoying content seamlessly.

Stage 3: Inactivity Warning (27 Days)

User receives professional warning email: "Watch something in 3 days or you'll be removed." Includes last activity date, days until removal, and admin contact info. Warning flag set in database.

Stage 4: Automated Removal (30+ Days)

User unfriended via Plex API (complete removal, not just library unsharing). Removal email sent to user with clear explanation, re-join instructions via Discord. Admin receives removal confirmation. Database cleaned up.

6. Professional Email Notifications

All emails are professionally branded with Centauri Cinema Network theming, using HTML templates stored in config.py. SMTP via Gmail with TLS encryption ensures reliable delivery.

📧 Welcome Email

Sent to new users within 5 minutes. Includes Plex access guide, Overseerr info, troubleshooting, Discord contact.

⚠️ Inactivity Warning

Sent at 27 days inactive. Professional reminder with 3-day countdown and instructions to stay active.

🚫 Removal Notice

Sent to removed users. Not accusatory—clear explanation with re-join instructions via Discord.

📊 Admin Alerts

Admin receives notifications for new users and removals with full details (username, email, activity).

7. SQLite Database Schema

CREATE TABLE user_activity (
    user_id INTEGER PRIMARY KEY,
    username TEXT UNIQUE,
    email TEXT,
    first_seen TEXT,
    last_activity TEXT,
    total_plays INTEGER DEFAULT 0,
    is_protected INTEGER DEFAULT 0,
    warning_sent INTEGER DEFAULT 0,
    warning_sent_date TEXT
);

-- Current State:
-- 59 users tracked in database
-- 11 protected users (never removed)
-- Automated queries run via cron

Location: /mnt/app-pool/config/tautulli/user_activity.db

Size: ~20KB (minimal overhead)

Access: Python sqlite3 library

8. Production Testing Results

✅ October 29, 2025 — Full System Test

Test User: [REDACTED_USER]

Inactivity: 25 days (manually tested before threshold)

Result: ✅ Successfully removed from Plex

Verification:

  • User removed from Plex shared users list via API
  • DELETE https://plex.tv/api/v2/sharings/[USER_ID] → 200 OK
  • Removal notification sent to admin
  • User entry deleted from SQLite database
  • Complete unfriending confirmed (user cannot access server)

This confirms my system works end-to-end for automated user removal. ✨

9. JBOPS Integration & Future Enhancements

My system leverages insights from JBOPS (Just a Bunch Of Plex Scripts), a comprehensive collection of 50+ automation scripts by Blacktwin. I've cloned the repository locally for reference and future enhancements.

Key Learning: Discovered the correct Plex API endpoint (DELETE /api/v2/sharings) from JBOPS utility/remove_inactive_users.py. This was adapted from the plexapi library's removeFriend() method.

🚀 Planned Enhancements

  • •Kill Transcoding Streams: Prevent server overload by forcing direct play (Plex Pass required)
  • •Stream Limiter: Limit concurrent streams per user to prevent credential sharing
  • •New IP Notifications: Security alerts when users stream from new locations
  • •Recently Aired Alerts: Engage users with new episode notifications
  • •User Location Maps: Visualize where users stream from worldwide

10. Key Technical Achievements

🔧 Hands-off Operation

Zero manual intervention required. System runs autonomously via cron jobs. Only setup and protected user list require human input.

📧 Professional Communications

HTML email templates with Centauri branding. SMTP via Gmail with TLS. Both user-facing and admin notifications.

🔌 API Integration

Tautulli API for activity tracking. Plex.tv API for user management. Complete unfriending via DELETE /api/v2/sharings endpoint.

⚡ Fast Detection

New users detected within 5 minutes. Welcome emails sent instantly. Separation of fast detection and slow cleanup for optimal performance.

🛡️ Protected Users

11 friends/family permanently whitelisted. Prevents accidental removal of VIP users while maintaining automated cleanup for the community.

📊 State Management

SQLite database for persistent state. Tracks 59 users with activity history, warning flags, and protection status. Minimal 20KB footprint.

Final Thoughts

Building my Centauri Plex Automation System was an exercise in production-grade infrastructure automation. What started as "I need to clean up inactive users" evolved into a comprehensive user lifecycle management platform that I designed to handle onboarding, activity tracking, warnings, and automated cleanup with professional communications throughout.

It ran in production, removing inactive users while protecting a protected list and notifying everyone involved. Once configured it needed no daily attention — which is the only claim about its automation level I can actually stand behind, since I never measured one.

Key Takeaway: Automation isn't just about running scripts—it's about building resilient systems that handle edge cases, communicate clearly, and operate reliably without human babysitting. 🚀

System Status: 🟢 Fully Operational

Last Tested: October 29, 2025

Next Cleanup: Daily at 3:00 AM

Powered by Linux, RAID-Z, and sheer stubbornness 🍿