Node.js + TypeScript service that listens to Frigate MQTT events and sends direct WhatsApp notifications through OpenClaw.
It sends with openclaw message send. It does not use chat completions, agents, LLM flows, Twilio, or the official WhatsApp Business API.
- Listens to Frigate review MQTT events, normally
frigate/reviews. - Sends a fast WhatsApp alert with a snapshot when available.
- Downloads clips, transcodes them with
ffmpeg, then sends the video as a second WhatsApp message when ready. - Deduplicates repeated MQTT updates for the same Frigate event.
- Cleans temporary image/video files to avoid filling the disk.
- Provides MQTT on/off alert control, with retained state.
- Publishes Home Assistant MQTT Discovery switches:
- one global alert switch;
- one switch for each camera listed in
ALLOWED_CAMERAS.
- Node.js 20 or newer.
pnpm.ffmpeg.- Frigate with MQTT enabled and event media available through its HTTP API.
- OpenClaw installed on the host running this service.
- OpenClaw WhatsApp channel logged in, for example:
openclaw channels login --channel whatsappUbuntu/Debian:
sudo apt update
sudo apt install -y ffmpegmacOS with Homebrew:
brew install ffmpegDocker/containers based on Debian or Ubuntu:
apt-get update
apt-get install -y ffmpegVerify that ffmpeg is available and includes libx264:
ffmpeg -versionThe output should include --enable-libx264. The service uses FFMPEG_BIN=ffmpeg by default; set FFMPEG_BIN=/path/to/ffmpeg if it is installed somewhere else.
Copy the example file and edit it:
cp .env.example .envRequired deployment values:
MQTT_URL=mqtt://<mqtt-host>:1883
MQTT_USERNAME=<mqtt-user>
MQTT_PASSWORD=<mqtt-password>
FRIGATE_BASE_URL=http://<frigate-host>:5000/api
OPENCLAW_TARGET=<E164_OR_GROUP_JID>
OPENCLAW_GROUP_ID=<GROUP_JID_OPTIONAL>
MEDIA_TMP_DIR=/tmp/frigate-openclawCamera controls are generated from:
ALLOWED_CAMERAS=<camera-1>,<camera-2>Use the exact Frigate camera names, for example the value that appears in MQTT as "camera": "...".
OpenClaw destinations:
OPENCLAW_TARGET=<E164_OR_GROUP_JID>
OPENCLAW_GROUP_ID=<GROUP_JID_OPTIONAL>If both are set, every alert and alert-control confirmation is sent to both destinations. At least one of OPENCLAW_TARGET or OPENCLAW_GROUP_ID must be set.
Install dependencies:
pnpm installRun in development:
pnpm devBuild and run:
pnpm run build
pnpm startRun checks:
pnpm run build
pnpm testThe repo includes a sample unit file:
systemd/frigate-openclaw-notifier.service
The unit expects:
WorkingDirectory=/opt/frigate-openclaw-notifier
EnvironmentFile=/etc/frigate-openclaw-notifier.env
ExecStart=/usr/bin/node /opt/frigate-openclaw-notifier/dist/src/index.js
User=frigate-openclaw
Group=frigate-openclaw
Install the service on Ubuntu/Debian:
sudo useradd --system --create-home --shell /usr/sbin/nologin frigate-openclaw
sudo mkdir -p /opt/frigate-openclaw-notifier
sudo cp -a . /opt/frigate-openclaw-notifier
sudo chown -R frigate-openclaw:frigate-openclaw /opt/frigate-openclaw-notifierYou can also run the service with the current user instead. This is useful when OpenClaw is already logged in for that user.
Create the environment file from the example:
sudo cp /opt/frigate-openclaw-notifier/.env.example /etc/frigate-openclaw-notifier.env
sudo nano /etc/frigate-openclaw-notifier.env
sudo chown root:frigate-openclaw /etc/frigate-openclaw-notifier.env
sudo chmod 640 /etc/frigate-openclaw-notifier.envInstall dependencies and build:
cd /opt/frigate-openclaw-notifier
sudo -u frigate-openclaw pnpm install --frozen-lockfile
sudo -u frigate-openclaw pnpm run buildInstall and start the unit:
sudo cp /opt/frigate-openclaw-notifier/systemd/frigate-openclaw-notifier.service /etc/systemd/system/frigate-openclaw-notifier.service
sudo systemctl daemon-reload
sudo systemctl enable --now frigate-openclaw-notifierCheck status and logs:
sudo systemctl status frigate-openclaw-notifier
sudo journalctl -u frigate-openclaw-notifier -fRestart after configuration changes:
sudo systemctl restart frigate-openclaw-notifierIf you keep this repository as the editable working copy, update the installed service with:
pnpm deployThe deploy command syncs this working copy to /opt/frigate-openclaw-notifier,
skipping local-only files such as node_modules, dist, .git, and .env.
It then installs dependencies, runs checks, builds the app, installs the systemd
unit for the current user, and restarts frigate-openclaw-notifier.
The deploy command always uses local .env as the source of truth for service
configuration. On every deploy it copies .env to
/etc/frigate-openclaw-notifier.env, then applies safe permissions.
You can also create it manually:
sudo cp .env.example /etc/frigate-openclaw-notifier.env
sudo nano /etc/frigate-openclaw-notifier.env
sudo chown root:$(id -gn) /etc/frigate-openclaw-notifier.env
sudo chmod 640 /etc/frigate-openclaw-notifier.envTo deploy with a different service account, set SERVICE_USER and
SERVICE_GROUP:
SERVICE_USER=frigate-openclaw SERVICE_GROUP=frigate-openclaw pnpm deployThe service user must be able to run openclaw message send with the WhatsApp session you intend to use. If OpenClaw stores session data in a user home directory, run the OpenClaw WhatsApp login as the same service user or adjust OPENCLAW_BIN and OpenClaw configuration paths accordingly.
Frigate input topic:
frigate/reviews
Configured through:
MQTT_TOPICS=frigate/reviewsHome Assistant direct-to-OpenClaw topic:
frigate-openclaw-notifier/openclaw/send
Configured through:
HOME_ASSISTANT_OPENCLAW_TOPIC=frigate-openclaw-notifier/openclaw/sendExpected payload:
{
"message": "Alerta Home Assistant: porton abierto"
}Recommended MQTT publish settings:
QoS: 1
Retain: false
Home Assistant direct-to-OpenClaw control topics:
frigate-openclaw-notifier/openclaw/set
frigate-openclaw-notifier/openclaw/state
Configured through:
HOME_ASSISTANT_OPENCLAW_CONTROL_COMMAND_TOPIC=frigate-openclaw-notifier/openclaw/set
HOME_ASSISTANT_OPENCLAW_CONTROL_STATE_TOPIC=frigate-openclaw-notifier/openclaw/state
HOME_ASSISTANT_OPENCLAW_DEFAULT_ENABLED=trueAccepted control payloads:
on
off
true
false
1
0
enabled
disabled
{"enabled":true}
{"enabled":false}
Global alert command topic:
frigate-openclaw-notifier/alerts/set
Global alert retained state topic:
frigate-openclaw-notifier/alerts/state
Per-camera command topics are derived from ALLOWED_CAMERAS:
frigate-openclaw-notifier/alerts/cameras/<camera-slug>/set
Per-camera retained state topics:
frigate-openclaw-notifier/alerts/cameras/<camera-slug>/state
Accepted command payloads:
on
off
true
false
1
0
enabled
disabled
{"enabled":true}
{"enabled":false}
The service publishes retained JSON state payloads:
{
"enabled": true,
"updatedAt": "2026-04-14T00:00:00.000Z",
"source": "command"
}Camera state payloads include camera.
MQTT Discovery is enabled by default:
HOME_ASSISTANT_DISCOVERY_ENABLED=true
HOME_ASSISTANT_DISCOVERY_PREFIX=homeassistant
HOME_ASSISTANT_DEVICE_ID=frigate_openclaw_notifier
HOME_ASSISTANT_DEVICE_NAME=Frigate OpenClaw NotifierHome Assistant should show one MQTT device named Frigate OpenClaw Notifier with switches like:
Frigate OpenClaw Alerts
Frigate OpenClaw <camera-1>
Frigate OpenClaw <camera-2>
Discovery config topics:
homeassistant/switch/frigate_openclaw_notifier/alerts/config
homeassistant/switch/frigate_openclaw_notifier/camera_<camera-slug>/config
When alert control is changed through MQTT, the service also confirms over WhatsApp:
Alertas Frigate OpenClaw: ON
Alertas Frigate OpenClaw: OFF
Alertas Frigate OpenClaw <camera>: ON
Alertas Frigate OpenClaw <camera>: OFF
Retained state restored on startup does not send WhatsApp confirmations, to avoid spam.
For frigate/reviews:
- The service logs the review.
- It sends a snapshot alert immediately when available.
- If
SEND_CLIP=true, it downloads the clip for the review detection id with retries. - It transcodes the clip with
ffmpegfor WhatsApp compatibility. - It sends the processed video as a second WhatsApp message.
- It removes the original and processed clip files after the send attempt.
Temporary media is stored in:
MEDIA_TMP_DIR=/tmp/frigate-openclawOld media files are cleaned after:
MEDIA_RETENTION_SECONDS=600Text:
openclaw message send --channel whatsapp --target <TARGET> --message <TEXT> --jsonMedia:
openclaw message send --channel whatsapp --target <TARGET> --media <FILE_OR_URL> --message <CAPTION> --json- Do not commit
.env. - Use
.env.exampleas the public template. - The repository ignores
.env,.env.*, local logs, build output, dependencies, and local planning notes. - MQTT credentials, Frigate URL, OpenClaw target, camera names, and local paths should be supplied through environment variables.
MIT. See LICENSE.