# Email Signature Manager A self-hosted, Dockerized Google Workspace email signature manager. Runs as a single container — designed for Unraid but works on any Docker host. ## Features - Pulls user data automatically from Google Workspace Directory API - Renders per-user HTML signatures via Handlebars templates - Pushes signatures directly to Gmail via `sendAs` API (web + mobile) - Nightly batch push via configurable cron schedule - Web admin UI — live template editor with real-time preview - Single-user push for testing and onboarding - SQLite audit log of every push event - Basic auth protected UI - Zero external services — single container, no database server --- ## Environment Variables All secrets and configuration are passed as **environment variables at runtime**. No `.env` file is committed to this repo — see `.env.example` for all variable names and descriptions. | Variable | Description | Default | |---|---|---| | `GOOGLE_ADMIN_EMAIL` | Workspace admin email for Directory API | *(required)* | | `GOOGLE_CUSTOMER_ID` | Use `my_customer` for primary domain | `my_customer` | | `SERVICE_ACCOUNT_KEY_PATH` | Path to sa.json inside container | `/app/secrets/sa.json` | | `ADMIN_USERNAME` | Web UI login username | *(required)* | | `ADMIN_PASSWORD` | Web UI login password | *(required)* | | `PORT` | Internal app port | `3000` | | `CRON_SCHEDULE` | Cron expression for nightly push | `0 2 * * *` | | `NODE_ENV` | Node environment | `production` | ### On Unraid Set each variable directly in the **Docker container template UI** under the "Variables" section. No file needed on the host. ### For Local Development Copy `.env.example` to `.env`, fill in your values, then run: ```bash docker-compose --env-file .env up -d --build ``` --- ## Google Workspace Setup (One-Time) ### 1. Create GCP Project & Enable APIs 1. Go to https://console.cloud.google.com → New Project 2. Enable **Admin SDK API** and **Gmail API** ### 2. Create Service Account 1. APIs & Services → Credentials → Create Credentials → Service Account 2. Name it `email-sig-manager` → Create 3. Open the service account → Keys tab → Add Key → JSON 4. Save the downloaded file as `sa.json` 5. Place it at: `secrets/sa.json` on the Docker host (mounted as a volume, never in git) ### 3. Enable Domain-Wide Delegation 1. Edit the service account → check **Enable Google Workspace Domain-wide Delegation** → Save 2. Note the **Client ID** (long numeric string) ### 4. Authorize Scopes in Google Admin 1. Go to https://admin.google.com 2. Security → Access and data control → API controls → Manage Domain Wide Delegation 3. Add new entry: - **Client ID:** *(your service account client ID)* - **OAuth Scopes:** ``` https://www.googleapis.com/auth/admin.directory.user.readonly,https://www.googleapis.com/auth/gmail.settings.basic ``` --- ## Unraid Deployment ### 1. Clone the repo ```bash cd /mnt/user/appdata git clone https://github.com/YOURUSERNAME/email-sig-manager.git cd email-sig-manager ``` ### 2. Place the service account key ```bash # Copy sa.json to the secrets folder (NOT tracked by git) cp /path/to/sa.json secrets/sa.json ``` ### 3. Add your company logo ``` public/assets/logo.png ``` ### 4. Add container in Unraid Docker UI - **Repository:** *(or build from path)* - **Port:** Map host port → `3000` - **Volumes:** - `/mnt/user/appdata/email-sig-manager/secrets` → `/app/secrets` - `/mnt/user/appdata/email-sig-manager/data` → `/app/data` - `/mnt/user/appdata/email-sig-manager/public/assets` → `/app/public/assets` - **Variables:** Add all variables from the table above ### 5. Build and start ```bash docker-compose up -d --build ``` Or use the Unraid UI to start the container after configuring it. ### Access the UI ``` http://UNRAID-IP:3000 ``` --- ## First Run Checklist - [ ] `secrets/sa.json` is in place on the host - [ ] All environment variables are set in Unraid Docker UI - [ ] Logo placed at `public/assets/logo.png` - [ ] Open UI → Template Editor → preview looks correct - [ ] Push single user (yourself) to verify Gmail signature - [ ] Push to all users --- ## Updating ```bash cd /mnt/user/appdata/email-sig-manager git pull docker-compose up -d --build ``` `secrets/`, `data/`, and any host-managed files are gitignored and unaffected by pulls. --- ## Project Structure ``` email-sig-manager/ ├── src/ │ ├── index.js # Express app entry │ ├── routes/ │ │ ├── admin.js # Template, logs, users API │ │ └── push.js # Signature push logic + batch runner │ ├── services/ │ │ ├── googleAdmin.js # Directory API — fetch all users │ │ ├── gmailApi.js # Gmail sendAs patch │ │ ├── renderer.js # Handlebars template renderer │ │ └── scheduler.js # node-cron nightly job │ └── db/ │ ├── sqlite.js # DB init and connection │ └── audit.js # Audit log read/write ├── templates/ │ └── default.hbs # 2-column HTML signature template ├── public/ │ ├── dashboard.html # Admin dashboard UI │ ├── editor.html # Template editor with live preview │ └── assets/ │ └── logo.png # Company logo (add your own) ├── secrets/ # Gitignored — sa.json goes here ├── data/ # Gitignored — SQLite DB lives here ├── Dockerfile ├── docker-compose.yml ├── package.json └── .env.example # Variable reference — safe to commit ``` --- ## Cron Schedule Reference | Expression | Meaning | |---|---| | `0 2 * * *` | 2:00 AM every day *(default)* | | `0 6 * * *` | 6:00 AM every day | | `0 2 * * 1` | 2:00 AM every Monday | | `0 2 1 * *` | 2:00 AM on the 1st of each month | --- ## Troubleshooting **Container won't start** Run `docker logs email-sig-manager` — most likely a missing env variable or malformed `sa.json`. **"No primary sendAs" error** The user may not have an active Gmail account, or domain-wide delegation scopes weren't saved correctly. **Signatures not showing on mobile** Gmail iOS/Android automatically uses the web signature. Have the user force-close and reopen the app. **Template changes not saving** Verify the container has write access to the `templates/` directory. A `.bak` file is created on every save. --- ## Security Notes - `sa.json` grants impersonation rights to every user in your domain — treat it like a master key - Never commit `sa.json` or a populated `.env` to GitHub - Change `ADMIN_PASSWORD` before first deployment - Consider placing the UI behind HTTPS if accessible outside your LAN