Skip to content

yhyatt/DMAF

DMAF Logo

🦞 DMAF

Don't Miss A Face

Automated WhatsApp photo & video backup with intelligent face recognition

Never miss a moment with your loved ones — DMAF watches your WhatsApp groups,
recognizes the faces you care about in photos and videos, and backs them up to Google Photos automatically.
Set it up once. After that: zero LLM tokens, minimal cloud costs, fully autonomous.

CI License: MIT Python OpenClaw Skill Contributing

OpenClaw 🦞FeaturesQuick StartHow It WorksConfigurationBackendsContributing


🦞 OpenClaw Friendly

DMAF is designed to be set up and operated entirely by an AI agent. If you use OpenClaw, you can go from zero to a working pipeline with a single prompt.

Install the DMAF skill from ClaWHub (or copy deploy/openclaw-skill/ to your skills directory), then just say:

"Set up DMAF for me. My GCP project ID is [your-project] and my WhatsApp is already connected to OpenClaw."

Your agent will walk through the full setup: GCP project, service account, GCS buckets, reference photos, config, the media sync cron, and the Cloud Scheduler — reading deploy/setup-secrets.md as its guide.

💡 After setup: zero LLM tokens. The ongoing pipeline is a system cron + Cloud Run job — pure infrastructure, no AI calls, no ongoing API cost.

Also friendly for:

  • 🤖 Coding agents (Claude Code, Copilot, Cursor) — AGENTS.md gives full architecture context, test patterns, and common pitfalls
  • 🦾 MCP clients (Claude Desktop, Claude Code, Cursor, Windsurf) — install the MCP server and your AI can trigger_scan(), get_status(), add_person() and more — no gcloud knowledge needed

✨ Features

🔍 Smart Face Recognition

  • Three powerful backends: dlib (CPU-optimized), InsightFace (non-commercial), or AuraFace (Apache 2.0, commercial use OK)
  • Photos & video clips: Scans both images and WhatsApp video clips — stops on first match, uploads the full clip
  • Multi-face detection: Handles group photos and videos with multiple faces
  • Configurable tolerance: Fine-tune matching sensitivity per deployment
  • Advanced detection thresholds: Separate thresholds for training vs. production

🦞 OpenClaw Friendly

  • One-prompt setup: Install the DMAF skill, describe your setup, done
  • WhatsApp media capture: OpenClaw intercepts group photos & videos automatically — no desktop app, no Android required
  • Token-free after setup: The sync cron and Cloud Run pipeline run with zero LLM calls — only minimal GCP infrastructure costs (Cloud Run + GCS, free-tier eligible)
  • Zero-maintenance sync: System cron uploads media to GCS every 30 min, no agent involvement
  • Agent-operable: Trigger scans, view logs, add people — all via shell/gcloud commands any agent can run
  • 🤖 Developer friendly: AGENTS.md with architecture, mocks, pitfalls, CI rules
  • 🦾 Agentic friendly: API-first pipeline, gcloud-scriptable end to end

🔄 Auto-Refresh Training

  • Intelligent updates: Automatically adds high-quality matched frames to known_people every 60 days
  • Smart selection: Picks moderately challenging images (score ≈ 0.65) for best training signal
  • Face cropping: Extracts and saves padded face crops
  • Email notifications: Get notified when training images are added

☁️ Google Photos Integration

  • Automatic uploads: Photos and full video clips backed up seamlessly
  • Album organization: Upload to a named album (recommended — keeps face-matched photos separate from your native camera-roll backup)
  • OAuth2 authentication: Secure, offline token-based access
  • Cloud staging support: Delete source files after upload (ideal for GCS pipelines)

⚡ Efficient & Token-Free

  • Zero LLM tokens after setup: The entire pipeline — sync cron, face recognition, upload — runs without any AI calls
  • Two-layer deduplication: Path-based dedup (fast Firestore lookup) + content SHA-256 dedup — the same photo arriving via multiple WhatsApp groups is only processed and uploaded once; survives container restarts
  • Video early exit: Sampling stops the moment a known face is found — no wasted compute
  • Intelligent retry logic: Exponential backoff for network resilience
  • Scale-to-zero: Cloud Run Job — no cost when idle, GCP free tier eligible

📧 Observability & Monitoring

  • Email alerts: SMTP notifications for errors and borderline recognitions
  • Score tracking: Records similarity scores (0.0–1.0) for every match
  • Configurable timezone: Alert emails show timestamps in your local time (IANA timezone)
  • Batched notifications: Hourly digest prevents inbox spam
  • Event retention: 90-day history with automatic cleanup

🚀 Quick Start

🦞 Have OpenClaw? One prompt away

  1. Install the DMAF skill: clawhub install dmaf — or browse it at clawhub.ai/skills/dmaf
  2. Make sure your WhatsApp channel is linked in OpenClaw
  3. Say to your agent:
Set up DMAF for me. My GCP project ID is [your-project-id] and my WhatsApp 
is already connected to OpenClaw. Walk me through everything.

Your agent reads deploy/setup-secrets.md and deploy/openclaw-integration.md to guide you step by step.

Zero ongoing tokens. Once setup is done, DMAF runs entirely on a system cron + Cloud Run — no LLM involved, no AI API costs — only the minimal GCP infrastructure you already pay for.


🛠️ Manual Setup

Prerequisites

  • Python 3.10 or higher
  • Google Cloud project with Photos Library API enabled
  • WhatsApp media access via one of:
    • OpenClaw integration (iPhone/Android) — ⭐ Recommended, see deploy/openclaw-integration.md
    • WhatsApp Desktop + rclone — Cross-platform
    • Android direct sync — FolderSync Pro, Syncthing

Installation

git clone https://github.com/yhyatt/DMAF.git
cd DMAF

python -m venv .venv && source .venv/bin/activate

# Choose your face recognition backend:
pip install -e ".[auraface]"       # ⭐ Apache 2.0 — commercial OK, zero false positives
pip install -e ".[insightface]"    # High accuracy, non-commercial only
pip install -e ".[face-recognition]"  # CPU-optimized, easiest setup

Setup

  1. Add reference photos of the people to recognize:

    data/known_people/
    ├── Alice/
    │   ├── photo1.jpg
    │   └── photo2.jpg
    └── Bob/
        └── photo1.jpg
    
  2. Configure:

    cp config.example.yaml config.yaml
    # Edit config.yaml — set watch_dirs and recognition backend
  3. Run:

    dmaf --config config.yaml
    # Or: python -m dmaf --config config.yaml
  4. Cloud deployment (GCS + Cloud Run, runs on a schedule, scales to zero): → Follow deploy/setup-secrets.md


🔄 How It Works

graph LR
    A[📱 WhatsApp Groups] -->|OpenClaw captures| B[💾 GCS Staging Bucket]
    B -->|Cloud Scheduler hourly| C[☁️ Cloud Run Job]
    C --> D{🔍 Face Found?}
    D -->|Yes — photo or video| E[📸 Upload to Google Photos]
    D -->|No match| F[⏭️ Skip]
    E --> G[🗄️ Firestore Dedup]
    F --> G
    G -->|path + content SHA256| H[🚫 Never Reprocess]
Loading
  1. Capture — OpenClaw intercepts WhatsApp group media and saves it locally; a system cron (zero LLM tokens) uploads it to GCS every 30 min
  2. Schedule — Cloud Scheduler triggers the Cloud Run job hourly — no agent, no AI cost
  3. Load — Reference photos downloaded from GCS bucket at job startup
  4. Detect — Each file is scanned: images once, videos sampled at 1–2fps with early exit on first match
  5. Upload — Matched photos and full video clips are uploaded to Google Photos
  6. Deduplicate — Two-layer check: (1) path-based Firestore lookup catches already-seen GCS paths; (2) content SHA-256 check catches the same photo arriving via multiple groups or sync paths — face recognition is skipped entirely for known content

⚙️ Configuration

watch_dirs:
  - "gs://your-project-whatsapp-media/"   # GCS staging bucket (cloud)
  - "/path/to/WhatsApp/Images"            # Local directory (dev)

known_people_gcs_uri: "gs://your-project-known-people"

recognition:
  backend: "auraface"      # auraface | insightface | face_recognition
  tolerance: 0.5           # 0.0 (strictest) → 1.0 (loosest)
  min_face_size_pixels: 20

google_photos_album_name: "Family Faces"  # recommended: keeps DMAF uploads separate from camera-roll backup

alerting:
  enabled: true
  timezone: "America/New_York"   # IANA name — used in alert email timestamps
  recipients: ["you@example.com"]

Full annotated template: config.example.yaml | Cloud template: config.cloud.example.yaml


🧠 Face Recognition Backends

Feature AuraFace ⭐ InsightFace face_recognition (dlib)
License ✅ Apache 2.0 (commercial OK) ⚠️ Non-commercial MIT
False Positive Rate 0.0% 🛡️ 1.87% ~11% ⚠️
Accuracy (TPR) 80–85% 82.5% 92.5%
Speed ⚡ Fast (12× vs dlib) ⚡ Fastest 🐢 Slow
GPU Support ✅ CUDA ✅ CUDA ❌ CPU only
Best For 🏆 Production Research Development

Use AuraFace for production — zero false positives means zero privacy violations. Commercial license, no restrictions.

🔌 Extensible Architecture

Adding a new backend is simple:

# src/dmaf/face_recognition/your_backend.py
def load_known_faces(known_root: str, **params): ...
def best_match(known_faces, test_image, **params): ...

Register in factory.py and you're done. See existing backends for examples.


📁 Project Structure

DMAF/
├── src/dmaf/
│   ├── __main__.py           # CLI entrypoint + Uploader (on_match / on_match_video)
│   ├── config.py             # Pydantic settings — all fields with defaults + docs
│   ├── watcher.py            # Core scan loop + file processing helpers
│   ├── video_processor.py    # iter_frames generator, find_face_in_video (early exit)
│   ├── gcs_watcher.py        # GCS helpers: list, download, cleanup
│   ├── database.py           # SQLite (local) + Firestore (cloud) dedup backends
│   ├── known_refresh.py      # Auto-refresh training images
│   ├── alerting/             # Email alert batching and templates
│   └── face_recognition/     # Backend factory: AuraFace, InsightFace, dlib
├── deploy/
│   ├── setup-secrets.md      # 🔑 All credentials setup, start here
│   ├── openclaw-integration.md  # 🦞 OpenClaw media sync guide
│   ├── openclaw-skill/       # 🦞 Installable OpenClaw skill (ClaWHub)
│   ├── mcp-setup.md          # 🔌 MCP server setup (Claude Desktop / Code / Cursor)
│   └── README.md             # GCP deployment walkthrough
├── tests/                    # pytest — mirrors src/dmaf structure
├── AGENTS.md                 # 🤖 Coding agent guide (Claude, Copilot, Cursor)
├── config.example.yaml       # Annotated config template (local dev)
└── config.cloud.example.yaml # Annotated config template (cloud deployment)

🛠️ Development

pip install -e ".[dev,all]"
pre-commit install          # ruff + mypy before every commit

pytest tests/ -v            # Run tests
mypy src/dmaf               # Type check
ruff check src/ tests/      # Lint

See AGENTS.md for architecture decisions, mock patterns, and CI rules.


🗺️ Roadmap

  • Phase A: Core bug fixes (RGB/BGR, caching, retry logic) ✅
  • Phase B: Project restructuring (src layout, Pydantic) ✅
  • Phase C: Unit tests (286 tests, 75%+ coverage) ✅
  • Phase D: Face recognition benchmarking & LOOCV validation ✅
  • Phase D+: Advanced detection tuning & FPR analysis ✅
  • Phase E: CI/CD (GitHub Actions, automated testing) ✅
  • Phase F-prep: Observability & auto-refresh (alerts, score tracking, AuraFace) ✅
  • Phase F: Cloud deployment (GCS + Cloud Run + Firestore) ✅
  • Phase G: Documentation, OpenClaw skill, open-source ready ✅

🤝 Contributing

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

📄 License

MIT License — see LICENSE for details.


🙏 Acknowledgments


Made with 🦀 by yhyatt

Star this repo

Releases

No releases published

Packages

 
 
 

Contributors

Languages