AutomationFlowsAI & RAG › Real-time Pulsepoint Emergency Alerts to Imessage with AI Summaries

Real-time Pulsepoint Emergency Alerts to Imessage with AI Summaries

ByDavid Harvey @xtgy on n8n.io

This n8n template fetches real-time emergency incident alerts from PulsePoint for a specific agency and delivers them directly to any phone number via iMessage using the Blooio API. It's designed to keep users informed with clear, AI-summarized reports of emergency activity near…

Event trigger★★★★☆ complexityAI-powered11 nodesHTTP RequestAgentOpenAI Chat
AI & RAG Trigger: Event Nodes: 11 Complexity: ★★★★☆ AI nodes: yes Added:

This workflow corresponds to n8n.io template #5533 — we link there as the canonical source.

This workflow follows the Agent → HTTP Request recipe pattern — see all workflows that pair these two integrations.

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "07757d09-129a-48f0-9a11-965ac480c490",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1020,
        -340
      ],
      "parameters": {
        "width": 880,
        "height": 1000,
        "content": "## Using the n8n HTTP Request Node to Send a Blooio.com Message\n\nFollow these steps to configure your existing HTTP Request node in n8n so you can send SMS or email via the Blooio.com API.\n\n---\n\n### 1. Open Your HTTP Request Node\n\n- In your workflow, click on the HTTP Request node you\u2019ve already added (e.g. **Send Message**).\n\n---\n\n### 2. Set Up the Request\n\n| Field                 | Value                                              |\n|-----------------------|----------------------------------------------------|\n| **Request Method**    | `POST`                                             |\n| **URL**               | `https://api.blooio.com/send-message`              |\n| **Response Format**   | `JSON`                                             |\n| **Body Content Type** | `JSON (application/json)`                          |\n\n---\n\n### 3. Add Required Headers\n\nAdd three headers exactly as shown:\n\n```text\nAccept:        application/json\nAuthorization: Bearer YOUR_TOKEN_HERE\nContent-Type:  application/json"
      },
      "typeVersion": 1
    },
    {
      "id": "75f418c3-3f51-4be0-812b-57077fefbcb8",
      "name": "Send Message",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1080,
        460
      ],
      "parameters": {
        "url": "https://api.blooio.com/send-message",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "sendHeaders": true,
        "authentication": "genericCredentialType",
        "bodyParameters": {
          "parameters": [
            {
              "name": "identifier",
              "value": "=+11111111111"
            },
            {
              "name": "message",
              "value": "={{ $json.output }}"
            }
          ]
        },
        "genericAuthType": "httpBearerAuth",
        "headerParameters": {
          "parameters": [
            {
              "name": "accept",
              "value": "application/json"
            }
          ]
        }
      },
      "credentials": {
        "httpBearerAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "d9285e13-a035-4ba1-a9ff-3c512715e192",
      "name": "When clicking \u2018Execute workflow\u2019",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        40,
        40
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "f90fe9a1-d266-479a-b2f4-bbb047afc46c",
      "name": "Schedule Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        40,
        240
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "minutes",
              "minutesInterval": 60
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "0fc5a46b-17a4-42e8-941c-fd5c1df53600",
      "name": "AI Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        700,
        460
      ],
      "parameters": {
        "text": "={{$input}}",
        "options": {
          "systemMessage": "Your only purpose is to brief the user on what is happening around them. Be concise. Use emojis and tell them what's happening around them. Give them a full report like\nWhat is happening, where, the time, units and the status of the units"
        },
        "promptType": "define"
      },
      "typeVersion": 2
    },
    {
      "id": "dab24453-cb4b-499e-917c-428a2e579ee1",
      "name": "Merge all",
      "type": "n8n-nodes-base.code",
      "position": [
        340,
        480
      ],
      "parameters": {
        "jsCode": "const allIncidents = items.map(item => item.json);\n\nreturn [\n  {\n    json: {\n      incidents: allIncidents\n    }\n  }\n];"
      },
      "typeVersion": 2
    },
    {
      "id": "fe7343f7-1b42-48f4-9a80-121e1596f3e2",
      "name": "If",
      "type": "n8n-nodes-base.if",
      "position": [
        520,
        480
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "ae6c4ed0-033e-4fba-8472-77293d616a00",
              "operator": {
                "type": "array",
                "operation": "lengthGt",
                "rightType": "number"
              },
              "leftValue": "={{ $json.incidents }}",
              "rightValue": 0
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "4bcdb173-a75b-4b6a-8d79-30115b853e94",
      "name": "OpenAI Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        720,
        640
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "o4-mini",
          "cachedResultName": "o4-mini"
        },
        "options": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "9c308697-6b1b-4475-a1d0-fdad0b562bdd",
      "name": "Get alerts",
      "type": "n8n-nodes-base.code",
      "position": [
        300,
        240
      ],
      "parameters": {
        "jsCode": "const crypto = require('crypto');\nconst fetch = require('node-fetch');\n\n// Step 1: Fetch encrypted PulsePoint incident data\nconst url = \"https://api.pulsepoint.org/v1/webapp?resource=incidents&agencyid=19100\";\nconst response = await fetch(url);\nconst data = await response.json();\n\n// Step 2: Decrypt response\nconst ct = Buffer.from(data.ct, \"base64\");\nconst iv = Buffer.from(data.iv, \"hex\");\nconst salt = Buffer.from(data.s, \"hex\");\n\nconst e = \"CommonIncidents\";\nconst password =\n  e[13] +\n  e[1] +\n  e[2] +\n  \"brady\" +\n  \"5\" +\n  \"r\" +\n  e.toLowerCase()[6] +\n  e[5] +\n  \"gs\";\n\n// Key derivation (Python-style)\nlet key = Buffer.alloc(0);\nlet block = null;\nwhile (key.length < 32) {\n  const hasher = crypto.createHash(\"md5\");\n  if (block) hasher.update(block);\n  hasher.update(Buffer.from(password, \"utf8\"));\n  hasher.update(salt);\n  block = hasher.digest();\n  key = Buffer.concat([key, block], key.length + block.length);\n}\nkey = key.slice(0, 32);\n\n// Decrypt\nconst decipher = crypto.createDecipheriv(\"aes-256-cbc\", key, iv);\nlet decrypted = decipher.update(ct);\ndecrypted += decipher.final(\"utf8\");\n\nconst cleanedOutput = decrypted\n  .slice(1, decrypted.lastIndexOf('\"'))\n  .replace(/\\\\\"/g, '\"');\nconst finalData = JSON.parse(cleanedOutput);\nconst active = finalData.incidents.active;\n\n// Step 3: Use static data to track seen incident IDs\nconst workflowStaticData = $getWorkflowStaticData('global');\n\nif (!workflowStaticData.hasOwnProperty('seenIncidentIDs')) {\n  workflowStaticData.seenIncidentIDs = [];\n}\n\nconst seenIDs = workflowStaticData.seenIncidentIDs;\nconst newIncidents = active.filter(i => !seenIDs.includes(i.ID));\nconst newIDs = newIncidents.map(i => i.ID);\n\n// Update static data and prune to last 100 entries\nworkflowStaticData.seenIncidentIDs = [...new Set([...seenIDs, ...newIDs])].slice(-100);\n\n// Incident call type mapping\nconst incidentCodeMapping = {\n  ME: \"Medical Emergency\",\n  IFT: \"Interfacility Transfer\",\n  CA: \"Canceled Assignment\",\n  ER: \"Emergency Response\",\n  CMA: \"Community Medical Assistance\",\n  VEG: \"Vegetation Fire\",\n  TC: \"Traffic Collision\",\n  OI: \"Other Incidents\",\n  AA: \"Auto Aid\",\n  MU: \"Mutual Aid\",\n  ST: \"Strike Team\",\n  AE: \"Aircraft Emergency\",\n  AES: \"Aircraft Emergency Standby\",\n  AC: \"Aircraft Crash\",\n  LZ: \"Landing Zone\",\n  FULL: \"Full Assignment\",\n  AF: \"Appliance Fire\",\n  CHIM: \"Chimney Fire\",\n  CB: \"Controlled Burn / Prescribed Fire\",\n  ELF: \"Electrical Fire\",\n  FIRE: \"Fire\",\n  GAS: \"Gas Main\",\n  HC: \"Hazardous Condition\",\n  MCI: \"Multi Casualty Incident\",\n  FLW: \"Flood Warning\",\n  TOW: \"Tornado Warning\",\n  TSW: \"Tsunami Warning\",\n  EQ: \"Earthquake\",\n  RL: \"Residential Lockout\",\n  VL: \"Vehicle Lockout\",\n  CL: \"Commercial Lockout\",\n  SF: \"Structural Fire\",\n  OD: \"Overdose\",\n  HM: \"Hazardous Materials Incident\",\n  MA: \"Medical Alert\",\n  ES: \"Emergency Services\",\n  AR: \"Animal Rescue\",\n  ELR: \"Elevator Rescue\",\n  USAR: \"Urban Search and Rescue\",\n  VS: \"Vessel Sinking\",\n  TCE: \"Expanded Traffic Collision\",\n  TCT: \"Traffic Collision Involving Train\",\n  RTE: \"Railroad/Train Emergency\",\n  IF: \"Illegal Fire\",\n  MF: \"Marine Fire\",\n  OF: \"Outside Fire\",\n  PF: \"Pole Fire\",\n  GF: \"Garbage Fire\",\n};\n\n// Unit dispatch status mapping (example)\nconst statusMapping = {\n  ER: \"En Route\",\n  OS: \"On Scene\",\n  AR: \"At Hospital / Released\",\n  TR: \"Transporting\",\n  TA: \"Taking Assignment\",\n  CA: \"Canceled\",\n  CL: \"Cleared\",\n};\n\nreturn newIncidents.map((incident) => {\n  const callTypeCode = incident.PulsePointIncidentCallType;\n  const callType = incidentCodeMapping[callTypeCode] || callTypeCode;\n\n  const units = incident.Unit.map((unit) => ({\n    UnitID: unit.UnitID,\n    Status: statusMapping[unit.PulsePointDispatchStatus] || unit.PulsePointDispatchStatus,\n    ClearedAt: unit.UnitClearedDateTime || null,\n  }));\n\n  return {\n    json: {\n      ID: incident.ID,\n      Type: callType,\n      Address: incident.FullDisplayAddress,\n      Time: incident.CallReceivedDateTime,\n      Location: {\n        Lat: incident.Latitude,\n        Lng: incident.Longitude,\n      },\n      Units: units,\n    },\n  };\n});\n\n"
      },
      "typeVersion": 2
    },
    {
      "id": "8adc042a-87a7-4586-9afc-957a7ca4b578",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -320,
        -40
      ],
      "parameters": {
        "color": 3,
        "width": 500,
        "height": 1100,
        "content": "> \ud83d\udea8 **Quick Preview:**  \n> ![Emergency Alerts Flow](https://i.imgur.com/SDh1bG3.png)  \n> This visual shows the Emergency Alerts \u2192 iMessage workflow in action. It pulls real-time PulsePoint incidents, summarizes them with AI, and sends friendly updates straight to your phone. Use it as a reference when setting up or tweaking the flow.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "26a5f634-3f48-477a-b063-e03ec9eb0b0c",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        240,
        -20
      ],
      "parameters": {
        "width": 640,
        "height": 220,
        "content": "> \ud83d\udfe2 **Getting Started Guide:**  \n> Want emergency alerts sent straight to your phone in plain English?  \n> Here's what you need before launching this workflow:\n> \n> 1. \ud83d\udd11 **PulsePoint Agency ID** \u2013 Find yours [here](https://web.pulsepoint.org)  \n> 2. \ud83d\udcf2 **Blooio API key** \u2013 Set up messaging via [blooio.com](https://blooio.com)  \n> 3. \ud83e\udd16 **OpenAI API Key** \u2013 Get yours [here](https://platform.openai.com/account/api-keys)  \n> 4. \u260e\ufe0f **Your Phone Number** \u2013 Add it in international format (e.g., `+1234567890`)\n> \n> Once these are in place, plug your details into the appropriate nodes and you're live! \ud83d\ude80\n"
      },
      "typeVersion": 1
    }
  ],
  "connections": {
    "If": {
      "main": [
        [
          {
            "node": "AI Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Agent": {
      "main": [
        [
          {
            "node": "Send Message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge all": {
      "main": [
        [
          {
            "node": "If",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get alerts": {
      "main": [
        [
          {
            "node": "Merge all",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Schedule Trigger": {
      "main": [
        [
          {
            "node": "Get alerts",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "AI Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "When clicking \u2018Execute workflow\u2019": {
      "main": [
        [
          {
            "node": "Get alerts",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

Credentials you'll need

Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

This n8n template fetches real-time emergency incident alerts from PulsePoint for a specific agency and delivers them directly to any phone number via iMessage using the Blooio API. It's designed to keep users informed with clear, AI-summarized reports of emergency activity near…

Source: https://n8n.io/workflows/5533/ — original creator credit. Request a take-down →

More AI & RAG workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

AI & RAG

K&S-Media Downloadliste SQL. Uses httpRequest, agent, googleSheets, lmChatOpenAi. Event-driven trigger; 97 nodes.

HTTP Request, Agent, Google Sheets +3
AI & RAG

🎯 Create viral TikToks, Shorts, Reels, podcasts, and ASMR videos in minutes — all on autopilot.

OpenAI, HTTP Request, Form Trigger +7
AI & RAG

Generate AI viral videos with NanoBanana & VEO3, shared on socials via Blotato 2. Uses @blotato/n8n-nodes-blotato, googleSheets, lmChatOpenAi, toolThink. Event-driven trigger; 94 nodes.

@Blotato/N8N Nodes Blotato, Google Sheets, OpenAI Chat +9
AI & RAG

RAG CHATBOT Main. Uses telegram, telegramTrigger, lmChatOpenAi, n8n-nodes-mcp. Event-driven trigger; 87 nodes.

Telegram, Telegram Trigger, OpenAI Chat +8
AI & RAG

The best content automation template in the market is now even better—with “deep research” on time-sensitive topics\! Unlike most n8n content automation templates that are mainly for “demo purposes,”

OpenAI, HTTP Request, XML +11