# How Webhook Event Notifications Are Triggered for Motion Detection and Recording in AtomCam Tools

> Learn how AtomCam Tools triggers webhook event notifications for motion detection and recording. Discover the process of log parsing and JSON payload posting.

- Repository: [Mitsuru Nakada/atomcam_tools](https://github.com/mnakada/atomcam_tools)
- Tags: how-to-guide
- Published: 2026-03-07

---

**AtomCam Tools triggers webhook event notifications by piping specially-formatted log lines to a FIFO file (`/var/run/atomapp`), where an awk script parses motion detection, recording, and timelapse events and POSTs JSON payloads to a configured URL via curl.**

The `mnakada/atomcam_tools` repository implements a lightweight, log-driven notification system that keeps the core camera firmware decoupled from networking logic. Instead of direct HTTP calls from C components, the system writes tagged messages to a named pipe and relies on [`overlay_rootfs/scripts/webhook.sh`](https://github.com/mnakada/atomcam_tools/blob/main/overlay_rootfs/scripts/webhook.sh) to dispatch `alarmEvent`, `recordEvent`, and `timelapseEvent` notifications when enabled in the configuration.

## Motion Detection Webhook Notifications

Motion detection events originate from either the hardware motion sensor or the onboard AI algorithm. When triggered, these components write specific log patterns to the FIFO that [`webhook.sh`](https://github.com/mnakada/atomcam_tools/blob/main/webhook.sh) monitors.

### Log Pattern Matching

The awk script in [`overlay_rootfs/scripts/webhook.sh`](https://github.com/mnakada/atomcam_tools/blob/main/overlay_rootfs/scripts/webhook.sh) listens for three distinct regex patterns to identify motion alarms:

```awk
/\[aiAlgo\] start/ { 
    if(ENV["WEBHOOK_ALARM_EVENT"] == "on") Post("alarmEvent"); 
}
/alarm_event_handle.*timestamp/ { 
    if(ENV["WEBHOOK_ALARM_EVENT"] == "on") Post("alarmEvent"); 
}
/(alarm_event_handle).*== readly to alarm ==/ { 
    if(ENV["WEBHOOK_ALARM_EVENT"] == "on") Post("alarmEvent"); 
}

```

When any pattern matches and `WEBHOOK_ALARM_EVENT` is set to `"on"`, the script invokes the internal `Post()` function.

### JSON Payload Construction

The `Post()` function constructs a minimal JSON object and dispatches it via curl:

```awk
system("curl -X POST -m 3 -H 'Content-Type: application/json' \
       -d '{\"type\":\"alarmEvent\", \"device\":\"" HOSTNAME "\"}' \
       " INSECURE_FLAG ENV["WEBHOOK_URL"] " > /dev/null 2>&1")

```

The resulting payload sent to the webhook URL is:

```json
{"type":"alarmEvent", "device":"my-atomcam"}

```

## Recording Finish Webhook Notifications

Regular recordings generate notifications through a different path. When a one-minute recording segment completes, the `atom_patch/bin/mv` helper handles file movement from temporary storage to `/media/mmc/record/`.

### Trigger Condition in the Move Helper

After successfully moving the MP4 file, the mv script checks environment variables before dispatching:

```sh
if [ "$WEBHOOK_URL" != "" ] && [ "$WEBHOOK_RECORD_EVENT" = "on" ]; then
    LD_LIBRARY_PATH=/tmp/system/lib:/tmp/system/usr/lib \
    /tmp/system/lib/ld.so.1 /tmp/system/bin/curl -X POST -m 3 \
    -H "Content-Type: application/json" \
    -d "{\"type\":\"recordEvent\", \"device\":\"${HOSTNAME}\"${STORAGE}}" \
    $INSECURE_FLAG $WEBHOOK_URL > /dev/null 2>&1
fi

```

The `STORAGE` variable appends optional file location metadata (`sdcardFile` or `cifsFile`) to the payload, allowing the receiver to locate the saved video immediately.

## Timelapse Webhook Notifications

Timelapse events are generated directly from the C library [`libcallback/timelapse.c`](https://github.com/mnakada/atomcam_tools/blob/main/libcallback/timelapse.c). The code prints specially-formatted strings to stdout that travel through the same FIFO pipeline.

### Event Emission in timelapse.c

The timelapse module emits status updates using printf statements:

```c
printf("[webhook] time_lapse_event %s %d/%d %d\n",
       ProcessingInfo.mp4File,
       ProcessingInfo.count,
       ProcessingInfo.numOfTimes,
       ScheduleNo);

printf("[webhook] time_lapse_finish %s %d/%d %d\n", ...);

```

### awk Processing

In [`webhook.sh`](https://github.com/mnakada/atomcam_tools/blob/main/webhook.sh), lines 88-91 capture these tags:

```awk
/\[webhook\] time_lapse_event/ {
    if(ENV["WEBHOOK_TIMELAPSE_EVENT"] == "on") 
        Post("timelapseEvent", "\"" $0 "\"");
}

```

The payload includes the raw log line containing the file path and progress counters, enabling external systems to track timelapse completion status.

## Configuration and Enablement

All webhook behavior is controlled via environment variables stored in [`/tmp/hack.ini`](https://github.com/mnakada/atomcam_tools/blob/main//tmp/hack.ini). The Web UI ([`web/source/vue/Setting.vue`](https://github.com/mnakada/atomcam_tools/blob/main/web/source/vue/Setting.vue)) exposes toggles for each event type:

```vue
<SettingSwitch i18n="event.webhook.alarm" v-model="config.WEBHOOK_ALARM_EVENT" />
<SettingSwitch i18n="event.webhook.recordingSave" v-model="config.WEBHOOK_RECORD_EVENT" />

```

When a user enables a switch, the corresponding `WEBHOOK_ALARM_EVENT`, `WEBHOOK_RECORD_EVENT`, or `WEBHOOK_TIMELAPSE_EVENT` variable is set to `"on"`. The [`webhook.sh`](https://github.com/mnakada/atomcam_tools/blob/main/webhook.sh) script reads these variables at startup and applies them to its pattern matching logic.

## Summary

- **Motion detection** triggers `alarmEvent` webhooks when `alarm_event_handle` or `[aiAlgo] start` patterns appear in the FIFO and `WEBHOOK_ALARM_EVENT` is enabled.
- **Recording completion** triggers `recordEvent` webhooks via the `atom_patch/bin/mv` helper when `WEBHOOK_RECORD_EVENT` is set to `"on"`.
- **Timelapse progress** triggers `timelapseEvent` webhooks from [`libcallback/timelapse.c`](https://github.com/mnakada/atomcam_tools/blob/main/libcallback/timelapse.c) when `WEBHOOK_TIMELAPSE_EVENT` is active.
- All notifications are dispatched by [`overlay_rootfs/scripts/webhook.sh`](https://github.com/mnakada/atomcam_tools/blob/main/overlay_rootfs/scripts/webhook.sh) using curl to the URL defined in `WEBHOOK_URL`.
- Configuration persists in [`hack.ini`](https://github.com/mnakada/atomcam_tools/blob/main/hack.ini) and is managed through the Vue-based Web UI settings panel.

## Frequently Asked Questions

### What URL format does AtomCam Tools expect for webhooks?

The system expects a standard HTTP or HTTPS URL assigned to the `WEBHOOK_URL` environment variable. The curl command in [`webhook.sh`](https://github.com/mnakada/atomcam_tools/blob/main/webhook.sh) appends this URL directly to the POST request without additional path manipulation, so the endpoint should be prepared to receive POST requests at the root of the provided address.

### Can I receive the actual file path in the recording webhook?

Yes. When `WEBHOOK_RECORD_EVENT` is enabled, the `atom_patch/bin/mv` helper appends a `STORAGE` variable to the JSON payload containing either `"sdcardFile":"/path/to/file"` or `"cifsFile":"/path/to/file"` depending on where the MP4 was saved. Parse the `recordEvent` payload to extract the location.

### Why does the motion detection use three different regex patterns?

The three patterns—`alarm_event_handle.*timestamp`, `alarm_event_handle.*== readly to alarm ==`, and `\[aiAlgo\] start`—cover different firmware paths. The hardware motion detector and AI algorithm write slightly different log formats to `/var/run/atomapp`. The awk script in [`webhook.sh`](https://github.com/mnakada/atomcam_tools/blob/main/webhook.sh) watches for all three to ensure reliable detection regardless of which subsystem triggered the alarm.

### Is there a way to test webhooks without waiting for actual motion?

You can manually write to the FIFO pipe to simulate events. As root, execute `echo "alarm_event_handle test timestamp" > /var/run/atomapp` while [`webhook.sh`](https://github.com/mnakada/atomcam_tools/blob/main/webhook.sh) is running with `WEBHOOK_ALARM_EVENT=on`. This forces the awk script to match the pattern and dispatch a test `alarmEvent` to your configured URL.