AutomationFlowsEmail & Gmail › Auto-create Geotab Zone for New Salesforce Work Order

Auto-create Geotab Zone for New Salesforce Work Order

BySobek @maagic on n8n.io

This workflow connects Salesforce and Geotab to streamline fleet tracking for field service jobs (Work Orders). When a new Work Order is created in Salesforce (with a 'New' status and valid coordinates), it creates a circular geofence zone in Geotab and updates the Work Order…

Webhook trigger★★★★☆ complexity22 nodesHTTP RequestSalesforceMicrosoft Outlook
Email & Gmail Trigger: Webhook Nodes: 22 Complexity: ★★★★☆ Added:

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

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
{
  "id": "c4MGMFdD3nrhySMt",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Auto-Create Geotab Zone for New Salesforce Work Order",
  "tags": [],
  "nodes": [
    {
      "id": "ccd1329c-71ad-48ac-b5cd-a09e3ee7cc22",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1680,
        -500
      ],
      "parameters": {
        "color": 5,
        "width": 1020,
        "height": 260,
        "content": "## Create zone via GeoTab API"
      },
      "typeVersion": 1
    },
    {
      "id": "6284e435-3929-42c7-9712-275d9dbf9941",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1680,
        -1080
      ],
      "parameters": {
        "color": 4,
        "width": 1020,
        "height": 280,
        "content": "## Prepare Data"
      },
      "typeVersion": 1
    },
    {
      "id": "bcd0e739-c12d-4713-8151-08bc4ed58ff9",
      "name": "Salesforce Webhook",
      "type": "n8n-nodes-base.webhook",
      "position": [
        -2240,
        -1000
      ],
      "parameters": {
        "path": "5e194736-f8d7-4eef-9c71-85d264168f3a",
        "options": {
          "rawBody": false
        },
        "httpMethod": "POST",
        "responseMode": "responseNode"
      },
      "typeVersion": 2
    },
    {
      "id": "d1769685-53ba-4817-8acb-a7ff5c62cb7d",
      "name": "Respond to Webhook",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        -2400,
        -1000
      ],
      "parameters": {
        "options": {
          "responseHeaders": {
            "entries": [
              {
                "name": "Content-Type",
                "value": "application/xml"
              }
            ]
          }
        },
        "respondWith": "text",
        "responseBody": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\">\n  <soapenv:Body>\n    <notificationsResponse xmlns=\"http://soap.sforce.com/2005/09/outbound\">\n      <Ack>true</Ack>\n    </notificationsResponse>\n  </soapenv:Body>\n</soapenv:Envelope>"
      },
      "typeVersion": 1.1
    },
    {
      "id": "565627d5-ccf9-4e74-a4be-7c7054bc0359",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "disabled": true,
      "position": [
        -2480,
        -1080
      ],
      "parameters": {
        "color": 6,
        "width": 780,
        "height": 280,
        "content": "## Salesforce Trigger"
      },
      "typeVersion": 1
    },
    {
      "id": "92d0377b-9566-47c7-ba7b-59d11af13ee7",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2480,
        -780
      ],
      "parameters": {
        "color": 7,
        "width": 780,
        "height": 540,
        "content": "## \ud83d\udef0\ufe0f Auto-Create Geotab Zone for New Salesforce Work Order\n\n### \ud83d\udccc What this workflow does\n\nThis automation listens for new **Work Order (Job)** records created in **Salesforce**, and\u2014if the record meets certain conditions\u2014creates a **geofence zone** in **Geotab** at the Work Order\u2019s location.\n\nIt only triggers when:\n\n* The Work Order has a `New` status\n* There is **no existing Geotab Zone ID**\n* The record contains **valid latitude and longitude**\n\nAfter creating the zone, the workflow updates Salesforce with the Geotab Zone ID and sends a confirmation email. If no geo data is available, it notifies the Operations team.\n\n**You can customise this workflow to your needs; for example change Salesforce Object (Opportunity, Account etc).**\n\n### \u2699\ufe0f Required Integrations\n* \u2705 Salesforce (OAuth2)\n* \u2705 Microsoft Outlook (for email notifications)\n* \u2705 Geotab API access\n"
      },
      "typeVersion": 1
    },
    {
      "id": "a277490a-b777-4502-b3b1-efeb4889a31d",
      "name": "Extract required fields",
      "type": "n8n-nodes-base.set",
      "position": [
        -1620,
        -1000
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "74d77b73-9e08-4ce7-b5e2-89fff556a6c2",
              "name": "Id",
              "type": "string",
              "value": "={{ $json.Id }}"
            },
            {
              "id": "ca06a724-d57d-4717-9495-08132fb96a8c",
              "name": "WorkOrderNumber",
              "type": "string",
              "value": "={{ $json.WorkOrderNumber }}"
            },
            {
              "id": "b381c523-da76-43c0-a43d-4f6c0e724d20",
              "name": "Job_Type__c",
              "type": "string",
              "value": "={{ $json.Job_Type__c }}"
            },
            {
              "id": "bdc4c9f0-e6ce-4408-82b5-cf79f1e37fc2",
              "name": "Job_Sub_Type__c",
              "type": "string",
              "value": "={{ $json.Job_Sub_Type__c }}"
            },
            {
              "id": "e0fcdb6d-c0af-490c-ac81-c6515c873a6d",
              "name": "Address.latitude",
              "type": "string",
              "value": "={{ $json.Address.latitude }}"
            },
            {
              "id": "92571b99-e82e-4c35-8707-baeb1d80e7b0",
              "name": "Address.longitude",
              "type": "string",
              "value": "={{ $json.Address.longitude }}"
            },
            {
              "id": "d32277a0-4e4e-48a3-9123-543b3509f177",
              "name": "CreatedDate",
              "type": "string",
              "value": "={{ $json.CreatedDate }}"
            },
            {
              "id": "318c819e-d7b1-4faf-8e7b-2907f6df0c1a",
              "name": "Last_Appointment_Date__c",
              "type": "string",
              "value": "={{ $json.Last_Appointment_Date__c }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "e6bcdcc0-ebd6-423b-a6a7-59e284c38fae",
      "name": "Prepare data for GeoTab",
      "type": "n8n-nodes-base.set",
      "position": [
        -1060,
        -1000
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "c45bb0c8-1ef9-4259-b985-d28be0a43878",
              "name": "Name",
              "type": "string",
              "value": "={{ $json.WorkOrderNumber }}"
            },
            {
              "id": "adfc451e-c84e-480e-9723-312cb85a8c7d",
              "name": "Latitude",
              "type": "string",
              "value": "={{ $json.Address.latitude }}"
            },
            {
              "id": "754cc87f-7e75-4187-80fa-b74dfb91983c",
              "name": "Longitude",
              "type": "string",
              "value": "={{ $json.Address.longitude }}"
            },
            {
              "id": "727937f2-8448-46b3-b9db-9170d2547ceb",
              "name": "Reference",
              "type": "string",
              "value": "={{ $json.Job_Type__c }}"
            },
            {
              "id": "fe9ccc9d-23c9-429a-9d9b-f5445ccf55fc",
              "name": "Comment",
              "type": "string",
              "value": "={{ $json.Job_Sub_Type__c }}"
            },
            {
              "id": "0cae7115-82fb-446b-8a95-3536f926c6b9",
              "name": "ExternalReference",
              "type": "string",
              "value": "={{ $json.Id }}"
            },
            {
              "id": "de07e177-0dca-4d5e-842f-1b8233a02502",
              "name": "ActiveTo",
              "type": "string",
              "value": "={{ $json.Last_Appointment_Date__c }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "dcccefd2-b65b-44ef-86a0-1403f2a8279c",
      "name": "Calculate points",
      "type": "n8n-nodes-base.code",
      "position": [
        -880,
        -1000
      ],
      "parameters": {
        "jsCode": "const inputData = items[0].json;\n\nconst centerLatitude = parseFloat(inputData.Latitude);\nconst centerLongitude = parseFloat(inputData.Longitude);\nconst radius = 200; // Radius in meters (adjust as needed) - Consider making this an input parameter\nconst numPoints = 20; // Number of points on the circle\n\nconst earthRadius = 6371000; // Earth's radius in meters\n\nlet results = [];\n\n\nfor (let i = 0; i < numPoints; i++) {\n    const angle = 2 * Math.PI * i / numPoints;\n    const lat = centerLatitude + (radius / earthRadius) * (180 / Math.PI) * Math.cos(angle);\n    const lon = centerLongitude + (radius / earthRadius) * (180 / Math.PI) * Math.sin(angle)  / Math.cos(centerLatitude * Math.PI / 180);\n    results.push({\n        ...inputData,\n        latitude: lat,\n        longitude: lon\n    })\n}\n\n\n// Create an object with a key called \"result\" to hold the results array\n// this ensure that the the json key points to a valid object in item[0]\nitems[0].json.result = results\n\n//return the updated item\nreturn items;"
      },
      "typeVersion": 2
    },
    {
      "id": "9e4b63fb-597f-448e-80b9-b1f066740a2c",
      "name": "GeoTab authentication",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -1600,
        -420
      ],
      "parameters": {
        "url": "https://my.geotab.com/apiv1/Authenticate",
        "method": "POST",
        "options": {},
        "jsonBody": "{\n  \"method\": \"Authenticate\",\n  \"params\": {\n    \"database\": \"YOUR_GEOTAB_DATABASE_NAME\",\n    \"userName\": \"user@example.com\",\n    \"password\": \"YOUR_GEOTAB_USER_PASSWORD\"\n  }\n}\n",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "e7b80c7d-f5ac-4085-8428-f3b4757a094d",
      "name": "Calculate zone's active dates",
      "type": "n8n-nodes-base.code",
      "position": [
        -1420,
        -420
      ],
      "parameters": {
        "jsCode": "const today = new Date();\ntoday.setUTCHours(0, 0, 0, 0);  // Ensures time is set to 00:00:00.000 UTC\nconst activeFrom = today.toISOString();  // Ensures the string format\n\nconst futureDate = new Date(today);\nfutureDate.setDate(today.getDate() + 60);\nfutureDate.setUTCHours(0, 0, 0, 0);  // Ensures time is set to 00:00:00.000 UTC\nconst activeTo = futureDate.toISOString();  // Ensures the string format\n\nreturn [\n    {\n        json: {\n            activeFrom: activeFrom.split(\".\")[0] + \"Z\",  // Removes milliseconds if necessary\n            activeTo: activeTo.split(\".\")[0] + \"Z\"  // Removes milliseconds if necessary\n        }\n    }\n];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "01adf82d-0894-4f23-816f-beb236a390ef",
      "name": "Create zone in GeoTab",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -1240,
        -420
      ],
      "parameters": {
        "url": "https://my.geotab.com/apiv1",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"method\": \"Add\",\n  \"params\": {\n    \"typeName\": \"Zone\",\n\n    \"entity\": {\n      \"name\": \"{{ $('Prepare data for GeoTab').item.json.Name }}\",\n      \"externalReference\": \"{{ $('Prepare data for GeoTab').item.json.ExternalReference }}\",\n      \"reference\": \"{{ $('Prepare data for GeoTab').item.json.Reference }}\",\n      \"comment\": \"{{ $('Prepare data for GeoTab').item.json.Comment }}\",\n\n      \"groups\": [\n      {\"id\": \"GroupCompanyId\"}\n      ],\n\n      \"activeFrom\": \"{{ $json.activeFrom }}\",\n      \"activeTo\": \"{{ $json.activeTo }}\",\n\n\n      \"points\": [\n        { \"x\": {{ $('Calculate points').item.json.result[0].longitude }}, \"y\": {{ $('Calculate points').item.json.result[0].latitude }}},\n        { \"x\": {{ $('Calculate points').item.json.result[1].longitude }}, \"y\": {{ $('Calculate points').item.json.result[1].latitude }}},\n        { \"x\": {{ $('Calculate points').item.json.result[2].longitude }}, \"y\": {{ $('Calculate points').item.json.result[2].latitude }}},\n        { \"x\": {{ $('Calculate points').item.json.result[3].longitude }}, \"y\": {{ $('Calculate points').item.json.result[3].latitude }}},\n        { \"x\": {{ $('Calculate points').item.json.result[4].longitude }}, \"y\": {{ $('Calculate points').item.json.result[4].latitude }}},\n        { \"x\": {{ $('Calculate points').item.json.result[5].longitude }}, \"y\": {{ $('Calculate points').item.json.result[5].latitude }}},\n        { \"x\": {{ $('Calculate points').item.json.result[6].longitude }}, \"y\": {{ $('Calculate points').item.json.result[6].latitude }}},\n        { \"x\": {{ $('Calculate points').item.json.result[7].longitude }}, \"y\": {{ $('Calculate points').item.json.result[7].latitude }}},\n        { \"x\": {{ $('Calculate points').item.json.result[8].longitude }}, \"y\": {{ $('Calculate points').item.json.result[8].latitude }}},\n        { \"x\": {{ $('Calculate points').item.json.result[9].longitude }}, \"y\": {{ $('Calculate points').item.json.result[9].latitude }}},\n        { \"x\": {{ $('Calculate points').item.json.result[10].longitude }}, \"y\": {{ $('Calculate points').item.json.result[10].latitude }}},\n        { \"x\": {{ $('Calculate points').item.json.result[11].longitude }}, \"y\": {{ $('Calculate points').item.json.result[11].latitude }}},\n        { \"x\": {{ $('Calculate points').item.json.result[12].longitude }}, \"y\": {{ $('Calculate points').item.json.result[12].latitude }}},\n        { \"x\": {{ $('Calculate points').item.json.result[13].longitude }}, \"y\": {{ $('Calculate points').item.json.result[13].latitude }}},\n        { \"x\": {{ $('Calculate points').item.json.result[14].longitude }}, \"y\": {{ $('Calculate points').item.json.result[14].latitude }}},\n        { \"x\": {{ $('Calculate points').item.json.result[15].longitude }}, \"y\": {{ $('Calculate points').item.json.result[15].latitude }}},\n        { \"x\": {{ $('Calculate points').item.json.result[16].longitude }}, \"y\": {{ $('Calculate points').item.json.result[16].latitude }}},\n        { \"x\": {{ $('Calculate points').item.json.result[17].longitude }}, \"y\": {{ $('Calculate points').item.json.result[17].latitude }}},\n        { \"x\": {{ $('Calculate points').item.json.result[18].longitude }}, \"y\": {{ $('Calculate points').item.json.result[18].latitude }}},\n        { \"x\": {{ $('Calculate points').item.json.result[19].longitude }}, \"y\": {{ $('Calculate points').item.json.result[19].latitude }}}\n      ],\n\n      \"visibleOnMap\": true,\n      \"publishToGroups\": [1],\n      \"showStopsInArea\": true\n    },\n\n    \"credentials\": {\n      \"sessionId\": \"{{ $('GeoTab authentication').item.json.result.credentials.sessionId }}\",\n      \"database\": \"YOUR_GEOTAB_DATABASE_NAME\",\n      \"userName\": \"YOUR@EMAIL.COM\"\n    }\n  }\n}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "c16af016-b846-4072-bc4a-fa99eec28e70",
      "name": "Update Salesforce with zone details",
      "type": "n8n-nodes-base.salesforce",
      "position": [
        -1040,
        -420
      ],
      "parameters": {
        "recordId": "={{ $('Get Work Order details').item.json.Id }}",
        "resource": "customObject",
        "operation": "update",
        "customObject": "=WorkOrder",
        "updateFields": {},
        "customFieldsUi": {
          "customFieldsValues": [
            {
              "value": "={{ $json.result }}",
              "fieldId": "GeoTab_ID__c"
            },
            {
              "value": "true",
              "fieldId": "GeoTab_Zone_Created__c"
            }
          ]
        }
      },
      "credentials": {
        "salesforceOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "3e89e6b1-7716-465f-98ba-bed15ec63b5e",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1680,
        -760
      ],
      "parameters": {
        "color": 3,
        "width": 1020,
        "height": 220,
        "content": "## \u26a0\ufe0f Missing Geolocation in Salesforce\n\nThis branch sends an email notification when a Work Order is missing latitude and longitude.\nYou can delete this section alongside \"If has location node\" if your Salesforce trigger already excludes such records."
      },
      "typeVersion": 1
    },
    {
      "id": "d9490f6f-620f-4b95-b861-f74279ba4e58",
      "name": "Wait",
      "type": "n8n-nodes-base.wait",
      "position": [
        -2040,
        -1000
      ],
      "parameters": {
        "amount": 30
      },
      "typeVersion": 1.1
    },
    {
      "id": "e8d8baff-0099-4540-9dea-040b82ef8496",
      "name": "If has location",
      "type": "n8n-nodes-base.if",
      "position": [
        -1400,
        -1000
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "or",
          "conditions": [
            {
              "id": "7d478faa-ef55-4f33-95db-1bb9e83437f0",
              "operator": {
                "type": "string",
                "operation": "notEmpty",
                "singleValue": true
              },
              "leftValue": "={{ $json.Address.latitude }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "cdea4264-3b0e-4f5f-b822-70b0409b5d79",
      "name": "Get Work Order details",
      "type": "n8n-nodes-base.salesforce",
      "notes": "{{ $json.body['soapenv:envelope']['soapenv:body'].notifications.notification.sobject['sf:id'] }}",
      "position": [
        -1880,
        -1000
      ],
      "parameters": {
        "recordId": "={{ $json.body['soapenv:envelope']['soapenv:body'].notifications.notification.sobject['sf:id'] }}",
        "resource": "customObject",
        "operation": "get",
        "customObject": "=WorkOrder"
      },
      "credentials": {
        "salesforceOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "d7614077-3d8e-4a1e-b07e-778a4d058ac7",
      "name": "Email notification  - success",
      "type": "n8n-nodes-base.microsoftOutlook",
      "position": [
        -860,
        -420
      ],
      "parameters": {
        "subject": "=Job zone was created for job number {{ $('Get Work Order details').item.json.WorkOrderNumber }}",
        "bodyContent": "=Hi Sobek,\n\nThe geofence for the job {{ $('Get Work Order details').item.json.WorkOrderNumber }}  has been successfully created in GeoTab.\n\nLink to job in Salesforce:\nhttps://idealresponse.lightning.force.com/lightning/r/WorkOrder/{{ $('Get Work Order details').item.json.Id }}/view\n\nGeoTab Zone link:\nhttps://my.geotab.com/irg/#zones,edit:{{ $('Create zone in GeoTab').item.json.result }}\n\nBest regards,\n\nIRG Ltd\nIT Department\n\n+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n\nJob attribiutes:\nJob ID: {{ $('Get Work Order details').item.json.Id }}\nOpportunity ID: {{ $('Get Work Order details').item.json.Opportunity__c }}\nPrimary Quote ID: {{ $('Get Work Order details').item.json.Primary_Quote_ID__c }}\nQuote Value: {{ $('Get Work Order details').item.json.Quote_value__c }}\nLead Source: {{ $('Get Work Order details').item.json.Lead_Source__c }}\nLead Source Main: {{ $('Get Work Order details').item.json.Lead_Source_Main_Type__c }}\n\nAccount: {{ $('Get Work Order details').item.json.Account_Text__c }}\nContact: {{ $('Get Work Order details').item.json.Contact_Full_Name__c }}\nContact email: {{ $('Get Work Order details').item.json.Contact_Email__c }}\n\nStreet: {{ $('Get Work Order details').item.json.Street }}\nCity: {{ $('Get Work Order details').item.json.City }}\nPostcode: {{ $('Get Work Order details').item.json.PostalCode }}\nLatitude: {{ $('Get Work Order details').item.json.Address.latitude }}\nLongitude: {{ $('Get Work Order details').item.json.Address.longitude }}\n\nSubject: {{ $('Get Work Order details').item.json.Subject }}\nJob Type: {{ $('Get Work Order details').item.json.Job_Type__c }}\nJob Sub Type: {{ $('Get Work Order details').item.json.Job_Sub_Type__c }}\nPayment Terms: {{ $('Get Work Order details').item.json.Payment_Terms_Quote__c }}\n\nOwner's name: {{ $('Get Work Order details').item.json.Owner_name__c }}\nOwner's Job Title: {{ $('Get Work Order details').item.json.Owner_s_Title__c }}\nOwner's Division: {{ $('Get Work Order details').item.json.Owner_s_Division__c }}\nOwners' Email: {{ $('Get Work Order details').item.json.Owner_Email__c }}\n\nJob Description:\n{{ $('Get Work Order details').item.json.Description }}",
        "toRecipients": "=some@email.com",
        "additionalFields": {}
      },
      "credentials": {
        "microsoftOutlookOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2
    },
    {
      "id": "869a3860-a66b-44bb-ac64-622ac582046f",
      "name": "Email notification  - error",
      "type": "n8n-nodes-base.microsoftOutlook",
      "position": [
        -860,
        -720
      ],
      "parameters": {
        "subject": "=Action Required: Missing Geo Location for Job  {{ $('Get Work Order details').item.json.WorkOrderNumber }}",
        "bodyContent": "=THIS IS AUTOMATED MESSAGE. DO NOT RESPOND.\n\nDear {{ $('Get Work Order details').item.json.Owner_name__c }},\n\nThis is an automated notification. Please do not reply to this message.\n\nWe have identified that the geo location data for Work Order #{{ $('Get Work Order details').item.json.WorkOrderNumber }} s missing in Salesforce, likely due to an incomplete or incorrect address. This data is essential for the effective management and execution of our projects.\n\nFor quick access to the job details in Salesforce, please use the following link:\nhttps://USE_YOUR_SALESFORCE_URL-DOMAIN/lightning/r/WorkOrder/{{ $('Get Work Order details').item.json.Id }}/view\n\n\n\nBest regards,\n\nIRG Ltd\nIT Department\n\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\nJob details:\n\nJob ID: {{ $('Get Work Order details').item.json.Id }}\nOpportunity ID: {{ $('Get Work Order details').item.json.Opportunity__c }}\nPrimary Quote ID: {{ $('Get Work Order details').item.json.Primary_Quote_ID__c }}\nQuote Value: {{ $('Get Work Order details').item.json.Quote_value__c }}\nLead Source: {{ $('Get Work Order details').item.json.Lead_Source__c }}\nLead Source Main: {{ $('Get Work Order details').item.json.Lead_Source_Main_Type__c }}\n\nAccount: {{ $('Get Work Order details').item.json.Account_Text__c }}\nContact: {{ $('Get Work Order details').item.json.Contact_Full_Name__c }}\nContact email: {{ $('Get Work Order details').item.json.Contact_Email__c }}\n\nStreet: {{ $('Get Work Order details').item.json.Street }}\nCity: {{ $('Get Work Order details').item.json.City }}\nPostcode: {{ $('Get Work Order details').item.json.PostalCode }}\nLatitude: {{ $('Get Work Order details').item.json.Address.latitude }}\nLongitude: {{ $('Get Work Order details').item.json.Address.longitude }}\n\nSubject: {{ $('Get Work Order details').item.json.Subject }}\nJob Type: {{ $('Get Work Order details').item.json.Job_Type__c }}\nJob Sub Type: {{ $('Get Work Order details').item.json.Job_Sub_Type__c }}\nPayment Terms: {{ $('Get Work Order details').item.json.Payment_Terms_Quote__c }}\n\nOwner's name: {{ $('Get Work Order details').item.json.Owner_name__c }}\nOwner's Job Title: {{ $('Get Work Order details').item.json.Owner_s_Title__c }}\nOwner's Division: {{ $('Get Work Order details').item.json.Owner_s_Division__c }}\nOwners' Email: {{ $('Get Work Order details').item.json.Owner_Email__c }}\n\nJob Description:\n{{ $('Get Work Order details').item.json.Description }}",
        "toRecipients": "user@example.com",
        "additionalFields": {}
      },
      "credentials": {
        "microsoftOutlookOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2
    },
    {
      "id": "e4fa9f14-39b8-4b20-b288-425ceb01f51e",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -640,
        -1080
      ],
      "parameters": {
        "height": 840,
        "content": "### \ud83d\udd10 Credentials to configure\n\nYou must connect or edit the following credentials:\n\n* \ud83d\udd39 **Salesforce Account**\n\n  * Nodes: `Get Work Order details`, `Update Salesforce with zone details`\n\n* \ud83d\udd39 **Outlook Account**\n\n  * Nodes: `Email notification - success`, `Email notification - error`\n\n* \ud83d\udd39 **Geotab API**\n\n  * Node: `GeoTab authentication`\n\n    * Replace `userName`, `password`, and `database` fields in the JSON body\n  * Node: `Create zone in GeoTab`\n\n    * Update the same values at the end of the JSON body (`database`, `userName`)\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "de984466-995e-4ea2-9a43-0d043b9fd5f0",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2740,
        -1080
      ],
      "parameters": {
        "height": 840,
        "content": "### \ud83e\udde9 How the Salesforce trigger works\n\nThis workflow is triggered by **an Outbound Message from Salesforce**.\n\nIn Salesforce Setup, you can configure an **Outbound Message** tied to the **Work Order** object. When a new Work Order is created (or meets specific criteria), Salesforce sends a SOAP request to this workflow's **Webhook URL**.\n\nThe workflow starts by receiving this message and extracting the Work Order ID to retrieve full details using the Salesforce node.\n\n### \u26a0\ufe0f Setup Required in Salesforce\n\n1. Go to **Setup \u2192 Outbound Messages**\n2. Create a new Outbound Message for the **Work Order** object\n3. Add fields as needed (at minimum, `Id`)\n4. Paste the Webhook URL from the **Salesforce Webhook** node in this workflow\n5. Link the Outbound Message to a Workflow Rule or Flow that fires when a **new Work Order is created**\n"
      },
      "typeVersion": 1
    },
    {
      "id": "792ffeb9-24d8-4b1a-8659-fd515c17f1f7",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1460,
        -1040
      ],
      "parameters": {
        "color": 3,
        "height": 200,
        "content": "**Check geolocation data**"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "c8533727-0485-43f8-8efa-86fe44e871e9",
  "connections": {
    "Wait": {
      "main": [
        [
          {
            "node": "Get Work Order details",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If has location": {
      "main": [
        [
          {
            "node": "Prepare data for GeoTab",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Email notification  - error",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Calculate points": {
      "main": [
        [
          {
            "node": "GeoTab authentication",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Salesforce Webhook": {
      "main": [
        [
          {
            "node": "Respond to Webhook",
            "type": "main",
            "index": 0
          },
          {
            "node": "Wait",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create zone in GeoTab": {
      "main": [
        [
          {
            "node": "Update Salesforce with zone details",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "GeoTab authentication": {
      "main": [
        [
          {
            "node": "Calculate zone's active dates",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Work Order details": {
      "main": [
        [
          {
            "node": "Extract required fields",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract required fields": {
      "main": [
        [
          {
            "node": "If has location",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare data for GeoTab": {
      "main": [
        [
          {
            "node": "Calculate points",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Calculate zone's active dates": {
      "main": [
        [
          {
            "node": "Create zone in GeoTab",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update Salesforce with zone details": {
      "main": [
        [
          {
            "node": "Email notification  - success",
            "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 workflow connects Salesforce and Geotab to streamline fleet tracking for field service jobs (Work Orders). When a new Work Order is created in Salesforce (with a 'New' status and valid coordinates), it creates a circular geofence zone in Geotab and updates the Work Order…

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

More Email & Gmail workflows → · Browse all categories →

Related workflows

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

Email & Gmail

This template is built for consultants, agencies, and service businesses that quote custom engagements and want to eliminate the manual work of building, formatting, and delivering pricing proposals.

Microsoft Excel, HTTP Request, Microsoft Outlook
Email & Gmail

Automate WhatsApp communication for recruitment agencies with an interactive, structured customer experience. This workflow handles pricing inquiries, request submissions, tracking, complaints, and hu

HTTP Request, Google Sheets, Gmail +1
Email & Gmail

This template turns Podium's conversation inbox into a full sales CRM with a custom funnel, AI message classification, automated drip follow-ups, daily admin reports, and a live Kanban dashboard. Six

HTTP Request, Google Sheets, Gmail
Email & Gmail

Suspicious_login_detection. Uses postgres, httpRequest, noOp, html. Webhook trigger; 43 nodes.

Postgres, HTTP Request, Gmail +1
Email & Gmail

This n8n workflow is designed for security monitoring and incident response when suspicious login events are detected. It can be initiated either manually from within the n8n UI for testing or automat

Postgres, HTTP Request, Gmail +1