{
  "id": "bR9W4OXo1sOiCXLK90bBw",
  "name": "Prey Webhooks \u2014 AI Alert + Event Log",
  "tags": [],
  "nodes": [
    {
      "id": "1044e2b9-4ccb-4b29-af49-0eb49791e9d1",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        0,
        0
      ],
      "parameters": {
        "width": 480,
        "height": 816,
        "content": "## Prey Webhooks \u2014 AI Alert + Event Log\n\n### How it works\n\nThis workflow receives Prey webhook events and routes them based on event type. Missing-device events are formatted for AI analysis, summarized or assessed with Claude, sent to Slack, and then logged. Other routed events are formatted directly and appended to the same Google Sheets event log.\n\n### Setup steps\n\n- Configure the Prey webhook URL to point to the n8n Webhook node's production URL.\n- Set up Anthropic credentials for the Claude chat model used by the AI Agent.\n- Connect Slack credentials and choose the channel or recipient for alert messages.\n- Connect Google Sheets credentials and configure the target spreadsheet, sheet, and columns for timestamp, event_type, device_id, and device_name.\n- Review the Switch node rules so Prey event types are routed to the correct alert or logging branch.\n\n### Customization\n\nAdjust the Switch routing rules for additional Prey event types, update the AI Agent prompt or model behavior for different alert wording, change the Slack destination, or expand the Google Sheets fields captured in the Set nodes."
      },
      "typeVersion": 1
    },
    {
      "id": "3b14833b-3d23-4917-aa8b-b68ccb1be47b",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        560,
        32
      ],
      "parameters": {
        "color": 7,
        "width": 432,
        "height": 336,
        "content": "## Receive and route\n\nThe left-side entry cluster accepts incoming Prey webhook payloads and branches them by event type so missing-device alerts and general event logging can follow different paths."
      },
      "typeVersion": 1
    },
    {
      "id": "610c27de-f36e-400c-9c45-5c9f6f9a3e2e",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1120,
        0
      ],
      "parameters": {
        "color": 7,
        "width": 704,
        "height": 480,
        "content": "## Analyze and alert\n\nThis upper middle cluster prepares key alert fields, sends them to Claude through the Anthropic chat model, and posts the resulting AI-assisted alert to Slack."
      },
      "typeVersion": 1
    },
    {
      "id": "78594fff-6320-4a96-bb23-90bfebc07552",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1872,
        0
      ],
      "parameters": {
        "color": 7,
        "width": 544,
        "height": 640,
        "content": "## Format and log events\n\nThe right-side logging cluster formats both regular routed events and missing-device alert events into a consistent record, then appends them to Google Sheets for tracking."
      },
      "typeVersion": 1
    },
    {
      "id": "40313d5c-64f1-4529-b348-60b13a08fa59",
      "name": "When Prey Event Posted",
      "type": "n8n-nodes-base.webhook",
      "position": [
        608,
        208
      ],
      "parameters": {
        "path": "prey-events",
        "options": {},
        "httpMethod": "POST",
        "authentication": "basicAuth"
      },
      "credentials": {
        "httpBasicAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2
    },
    {
      "id": "0432d475-bf7c-49b0-bbc1-ff60fc1f09e0",
      "name": "Route by Event Type",
      "type": "n8n-nodes-base.switch",
      "position": [
        848,
        208
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "outputKey": "Device Missing",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "51b2bfb7-0822-47f0-8762-5467f475e881",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.body.event_type }}",
                    "rightValue": "device_missing"
                  }
                ]
              },
              "renameOutput": true
            }
          ]
        },
        "options": {
          "fallbackOutput": "extra"
        }
      },
      "typeVersion": 3.3
    },
    {
      "id": "282e375d-902d-4988-9a93-5963f80717bb",
      "name": "Set Alert Data Fields",
      "type": "n8n-nodes-base.set",
      "position": [
        1168,
        160
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "1c64003c-e177-4b29-b750-02e73c59d0d3",
              "name": "event_type",
              "type": "string",
              "value": "={{ $json.body.event_type }}"
            },
            {
              "id": "4245e0f4-7f74-4d18-9628-58b0bcd42e86",
              "name": "device_key",
              "type": "string",
              "value": "={{ $json.body.body.device.key }}"
            },
            {
              "id": "2b004630-2c57-4b68-b661-86b8117c99c4",
              "name": "device_name",
              "type": "string",
              "value": "={{ $json.body.body.device.name }}"
            },
            {
              "id": "2e2377dd-e8e9-41d1-8889-2c19e15ebbde",
              "name": "user_name",
              "type": "string",
              "value": "={{ $json.body.body.device.user?.name || '' }}"
            },
            {
              "id": "8a8970d9-4614-46f3-96d2-fa2275311caf",
              "name": "user_email",
              "type": "string",
              "value": "={{ $json.body.body.device.user?.email || '' }}"
            },
            {
              "id": "4d2de8df-1d30-4dd3-a891-ed2a759242ac",
              "name": "lat",
              "type": "string",
              "value": "={{ $json.body.body.device.location?.lat ?? null }}"
            },
            {
              "id": "1ae76461-983f-4100-b035-46faef07c5fe",
              "name": "lng",
              "type": "string",
              "value": "={{ $json.body.body.device.location?.lng ?? null }}"
            },
            {
              "id": "5a0bb59e-1562-487f-8c72-3d0a7c679970",
              "name": "maps_url",
              "type": "string",
              "value": "={{ $json.body.body.device.location ? 'https://maps.google.com/?q=' + $json.body.body.device.location.lat + ',' + $json.body.body.device.location.lng : '' }}"
            },
            {
              "id": "005f79d8-5872-491f-9f4b-62552769c7b6",
              "name": "reported_at",
              "type": "string",
              "value": "={{ $json.body.occurred_at || $now.toISO() }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "41701a6d-7926-446d-8be3-b76b7056fb55",
      "name": "Content Analysis Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        1376,
        160
      ],
      "parameters": {
        "text": "=You are a device security analyst. A device managed by Prey has just been reported as missing.\n\nDevice Information:\n- Name: {{ $json.device_name }}\n- Owner: {{ $json.user_name || 'Unknown' }}{{ $json.user_email ? ' (' + $json.user_email + ')' : '' }}\n- Last known location: {{ $json.lat ? $json.lat + ', ' + $json.lng : 'Not available (device had no GPS fix at time of report)' }}\n- Reported at: {{ $json.reported_at }}\n\nWrite a concise, professional 3-sentence security alert for the IT team that:\n1. States which device went missing and who it belongs to\n2. Describes the location context (or notes that location is unavailable and the device may be offline)\n3. Recommends immediate actions (e.g., activate remote lock via Prey, contact the device owner, check Prey activity logs)\n\nTone: professional, urgent, actionable. Do not include raw coordinates \u2014 use plain-language descriptions.",
        "options": {},
        "promptType": "define"
      },
      "typeVersion": 3
    },
    {
      "id": "6f209faf-d8b4-4f53-b28c-9ed75f1fb67b",
      "name": "Claude Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatAnthropic",
      "position": [
        1376,
        336
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "claude-sonnet-4-5-20250929",
          "cachedResultName": "Claude Sonnet 4.5"
        },
        "options": {}
      },
      "credentials": {
        "anthropicApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "42f33b62-179f-4b0a-87ae-17ccb9e197f8",
      "name": "Post Alert to Slack",
      "type": "n8n-nodes-base.slack",
      "position": [
        1680,
        160
      ],
      "parameters": {
        "text": "=:rotating_light: *Missing Device Alert*\n\n*Device:* {{ $('Set Alert Data Fields').item.json.device_name }}\n*Owner:* {{ $('Set Alert Data Fields').item.json.user_name || 'Unknown' }}{{ $('Set Alert Data Fields').item.json.user_email ? ' (' + $('Set Alert Data Fields').item.json.user_email + ')' : '' }}\n\n*AI Analysis:*\n{{ $json.output }}\n\n{{ $('Set Alert Data Fields').item.json.maps_url ? ':round_pushpin: <' + $('Set Alert Data Fields').item.json.maps_url + '|View Last Known Location on Maps>' : ':round_pushpin: _Location not available \u2014 device had no GPS fix at time of report_' }}",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "id",
          "value": "YOUR_SLACK_CHANNEL_ID"
        },
        "otherOptions": {}
      },
      "credentials": {
        "slackApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "94a1226d-8bcc-4f59-9a7b-cc8cf30f5a47",
      "name": "Set Log Entry Fields",
      "type": "n8n-nodes-base.set",
      "position": [
        2016,
        480
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "4090cf01-e32b-4fbe-acf6-c4345329707c",
              "name": "timestamp",
              "type": "string",
              "value": "={{ $json.body.occurred_at || $now.toISO() }}"
            },
            {
              "id": "7e50377a-522e-4203-a05d-3090be704c5a",
              "name": "event_type",
              "type": "string",
              "value": "={{ $json.body.event_type }}"
            },
            {
              "id": "98ae90b1-1405-4aec-96ee-958b03867013",
              "name": "device_id",
              "type": "string",
              "value": "={{ $json.body.body.device.key }}"
            },
            {
              "id": "507a4667-c2fb-43f4-94fe-568a186fe611",
              "name": "device_name",
              "type": "string",
              "value": "={{ $json.body.body.device.name }}"
            },
            {
              "id": "6bb77c12-3137-45c1-8061-0f598f80a2a4",
              "name": "user_name",
              "type": "string",
              "value": "={{ $json.body.body.device.user?.name || '' }}"
            },
            {
              "id": "fbc521c7-0f5f-426e-a7bc-bac34e7b64ca",
              "name": "user_email",
              "type": "string",
              "value": "={{ $json.body.body.device.user?.email || '' }}"
            },
            {
              "id": "d2b90dac-9faa-47a9-a093-46da024b01fe",
              "name": "details",
              "type": "string",
              "value": "={{ JSON.stringify($json.body.body) }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "4299db96-72ab-4c8e-a663-941bf715622c",
      "name": "Append Log to Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        2272,
        320
      ],
      "parameters": {
        "columns": {
          "value": {},
          "schema": [],
          "mappingMode": "autoMapInputData",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "url",
          "value": "https://docs.google.com/spreadsheets/d/YOUR_SPREADSHEET_ID/edit"
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "208cf9a3-43a6-4b2c-9465-83b0101088bd",
      "name": "Prepare Missing Event Log",
      "type": "n8n-nodes-base.set",
      "position": [
        1920,
        160
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "2b30b6dc-572a-4345-bf2e-f1f8d65fa16b",
              "name": "timestamp",
              "type": "string",
              "value": "={{ $('Set Alert Data Fields').item.json.reported_at }}"
            },
            {
              "id": "bc45cf08-bee5-4aca-80c4-0def9f3d4341",
              "name": "event_type",
              "type": "string",
              "value": "device_missing"
            },
            {
              "id": "e12fafc7-a606-49a0-85f3-8ec3edf0f64b",
              "name": "device_id",
              "type": "string",
              "value": "={{ $('Set Alert Data Fields').item.json.device_key }}"
            },
            {
              "id": "ea54c106-bdc5-4425-894d-1fddac3d315b",
              "name": "device_name",
              "type": "string",
              "value": "={{ $('Set Alert Data Fields').item.json.device_name }}"
            },
            {
              "id": "735c46f9-f25c-4a5a-aed1-bff1ce64ed51",
              "name": "user_name",
              "type": "string",
              "value": "={{ $('Set Alert Data Fields').item.json.user_name }}"
            },
            {
              "id": "3af61d3f-018e-4afb-a674-6547a4723e2b",
              "name": "user_email",
              "type": "string",
              "value": "={{ $('Set Alert Data Fields').item.json.user_email }}"
            },
            {
              "id": "14e0e0ce-ddc1-45d1-990d-c8a84c563d8f",
              "name": "details",
              "type": "string",
              "value": "=Missing event \u2014 AI alert sent to Slack{{ $('Set Alert Data Fields').item.json.maps_url ? '. Maps: ' + $('Set Alert Data Fields').item.json.maps_url : '. No location data.' }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    }
  ],
  "active": false,
  "settings": {
    "availableInMCP": false,
    "executionOrder": "v1"
  },
  "versionId": "95da040c-15f8-4a3f-a9db-22d0fb20be2f",
  "connections": {
    "Claude Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Content Analysis Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Post Alert to Slack": {
      "main": [
        [
          {
            "node": "Prepare Missing Event Log",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Route by Event Type": {
      "main": [
        [
          {
            "node": "Set Alert Data Fields",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Set Log Entry Fields",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Log Entry Fields": {
      "main": [
        [
          {
            "node": "Append Log to Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Alert Data Fields": {
      "main": [
        [
          {
            "node": "Content Analysis Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Content Analysis Agent": {
      "main": [
        [
          {
            "node": "Post Alert to Slack",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "When Prey Event Posted": {
      "main": [
        [
          {
            "node": "Route by Event Type",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Missing Event Log": {
      "main": [
        [
          {
            "node": "Append Log to Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}