Skip to content
/ DMAF Public

🧠 Don't Miss A Face β€” Automatically backup WhatsApp photos of your loved ones to Google Photos using AI face recognition

License

Notifications You must be signed in to change notification settings

yhyatt/DMAF

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

105 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

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 🦞 β€’ Features β€’ Quick Start β€’ How It Works β€’ Configuration β€’ Backends β€’ Contributing


🦞 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