3033fc0de2
- Custom Plausible events: Pricing Click, Chat Toggle, Chat Message Sent, FAQ Toggle, Speedrun Nav, Mobile Menu Toggle, Scroll Depth (25/50/75/100%) - Weekly Insights section on launch dashboard with visitor/pageview/bounce rate/visit duration/top pages/top referrers + analysis cards - data/insights.json for storing weekly analytics summaries - scripts/check-plausible-email.py — finds latest Plausible email via IMAP - Cron job: every Mon 09:00 PYST, reads Plausible email, writes insights, analyzes and implements improvements
89 lines
2.7 KiB
Python
Executable File
89 lines
2.7 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""Check for Plausible analytics email and output raw content for cron analysis."""
|
|
|
|
import json
|
|
import re
|
|
import subprocess
|
|
import sys
|
|
from datetime import datetime
|
|
from pathlib import Path
|
|
|
|
HERE = Path(__file__).resolve().parent.parent
|
|
INSIGHTS_FILE = HERE / "data" / "insights.json"
|
|
|
|
|
|
def run_cmd(*args, timeout=30):
|
|
result = subprocess.run(args, capture_output=True, text=True, timeout=timeout)
|
|
if result.returncode != 0:
|
|
return None, result.stderr
|
|
return result.stdout, None
|
|
|
|
|
|
def find_plausible_email():
|
|
"""Find the latest Plausible-related email in inbox."""
|
|
out, err = run_cmd("himalaya", "envelope", "list", "--page", "1", "--page-size", "30")
|
|
if not out:
|
|
return None, None
|
|
|
|
best_id, best_subject = None, ""
|
|
current_id, current_subject = None, ""
|
|
for line in out.splitlines():
|
|
# himalaya format: "ID | DATE | FROM | SUBJECT"
|
|
if "|" not in line:
|
|
continue
|
|
parts = [p.strip() for p in line.split("|")]
|
|
if len(parts) < 4:
|
|
continue
|
|
try:
|
|
current_id = int(parts[0])
|
|
except ValueError:
|
|
continue
|
|
current_subject = parts[-1] if len(parts) >= 4 else ""
|
|
|
|
subj_lower = current_subject.lower()
|
|
score = 0
|
|
if "plausible" in subj_lower:
|
|
score += 10
|
|
if "weekly" in subj_lower and ("report" in subj_lower or "analytics" in subj_lower or "stats" in subj_lower):
|
|
score += 5
|
|
if "analytics" in subj_lower and "summary" in subj_lower:
|
|
score += 5
|
|
if "site" in subj_lower and ("stats" in subj_lower or "report" in subj_lower):
|
|
score += 3
|
|
|
|
if score > 0 and score >= (10 if best_id is None else 0):
|
|
best_id = current_id
|
|
best_subject = current_subject
|
|
|
|
return best_id, best_subject
|
|
|
|
|
|
def main():
|
|
email_id, subject = find_plausible_email()
|
|
|
|
if email_id is None:
|
|
print("No Plausible email found in inbox.", file=sys.stderr)
|
|
# Still update last_check timestamp
|
|
insights = {}
|
|
if INSIGHTS_FILE.exists():
|
|
with open(INSIGHTS_FILE) as f:
|
|
insights = json.load(f)
|
|
insights["last_check"] = datetime.now().strftime("%Y-%m-%d %H:%M")
|
|
with open(INSIGHTS_FILE, "w") as f:
|
|
json.dump(insights, f, indent=2)
|
|
sys.exit(0)
|
|
|
|
content, err = run_cmd("himalaya", "message", "read", str(email_id))
|
|
if not content:
|
|
print(f"Failed to read email {email_id}: {err}", file=sys.stderr)
|
|
sys.exit(0)
|
|
|
|
print(f"=== Plausible Email Found ===")
|
|
print(f"Subject: {subject}")
|
|
print(f"Email ID: {email_id}")
|
|
print(f"=== Full Content ===")
|
|
print(content[:6000])
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main() |