{"id":1466,"date":"2025-04-29T14:25:48","date_gmt":"2025-04-29T12:25:48","guid":{"rendered":"https:\/\/sprintcx.net\/individuelle-tourenplanung-mit-zoho-crm-und-google-maps-api-gestalten\/"},"modified":"2025-04-29T18:35:50","modified_gmt":"2025-04-29T16:35:50","slug":"individuelle-tourenplanung-mit-zoho-crm-und-google-maps-api-gestalten","status":"publish","type":"post","link":"https:\/\/wordpress.sprintcx.net\/de\/individuelle-tourenplanung-mit-zoho-crm-und-google-maps-api-gestalten\/","title":{"rendered":"Individuelle Tourenplanung mit Zoho CRM und Google Maps API gestalten"},"content":{"rendered":"<h2>Ma\u00dfgeschneiderte Tourenplanung in Zoho CRM: Google Maps API statt Standard-Tools<\/h2>\n<p>Stehst Du auch vor der Herausforderung, die Eins\u00e4tze Deiner Au\u00dfendienstteams effizient und flexibel zu planen? Viele Standardl\u00f6sungen oder vollautomatisierte Ans\u00e4tze sto\u00dfen schnell an ihre Grenzen, wenn unvorhersehbare Faktoren wie Materialverf\u00fcgbarkeit, kurzfristige Termin\u00e4nderungen oder sogar das Wetter ins Spiel kommen. Eine starre Planung passt selten zur dynamischen Realit\u00e4t im Servicegesch\u00e4ft. Genau hier setzt dieser Artikel an: Wir zeigen Dir, wie Du eine individuelle, kartenbasierte Tourenplanung direkt in Dein Zoho CRM integrieren kannst, indem Du die Power der Google Maps API nutzt. Statt auf externe Tools wie Root IQ oder starre Automatisierungen zu setzen, baust Du Dir eine L\u00f6sung, die Dir die volle Kontrolle und Flexibilit\u00e4t gibt und sich nahtlos in Deine bestehenden CRM-Prozesse einf\u00fcgt.<\/p>\n<h3>Warum eine individuelle Kartenintegration? Die Herausforderung in der Praxis<\/h3>\n<p>Stell Dir ein typisches Szenario vor: Ein Unternehmen im Bereich technischer Dienstleistungen (z. B. Brandschutz, Solaranlageninstallation, Wartungsservice) muss t\u00e4glich oder w\u00f6chentlich Touren f\u00fcr mehrere Technikerteams planen. Die Auftr\u00e4ge (z.B. als &#8222;Kundenauftr\u00e4ge&#8220; oder &#8222;Service-Tickets&#8220; im Zoho CRM erfasst) haben Adressen, F\u00e4lligkeitsdaten und spezifische Anforderungen (ben\u00f6tigtes Material, Dokumente, Ansprechpartner).<\/p>\n<p>Die Herausforderungen sind vielf\u00e4ltig:<\/p>\n<ul>\n<li><strong>Dynamik:<\/strong> Auftr\u00e4ge m\u00fcssen oft kurzfristig umgeplant werden.<\/li>\n<li><strong>Effizienz:<\/strong> Routen sollen geografisch sinnvoll sein, um Fahrtzeiten zu minimieren.<\/li>\n<li><strong>Informationszugriff:<\/strong> Techniker ben\u00f6tigen unterwegs alle relevanten Auftragsdetails direkt aus der Planung heraus.<\/li>\n<li><strong>Kontrolle:<\/strong> Der Disponent muss die \u00dcbersicht behalten und manuell eingreifen k\u00f6nnen, statt sich auf eine &#8222;Black Box&#8220;-Automatisierung zu verlassen.<\/li>\n<li><strong>Integration:<\/strong> Die Planung soll direkt mit den CRM-Daten verkn\u00fcpft sein, ohne manuellen Datenabgleich zwischen verschiedenen Systemen.<\/li>\n<\/ul>\n<p>Standard-MapView-Funktionen im CRM zeigen zwar Orte an, erlauben aber oft keine interaktive Planung. Externe Tools wie Root IQ m\u00f6gen spezialisiert sein, aber die Integration kann hakelig sein (wie das Beispiel zeigte, bei dem geplante Auftr\u00e4ge von der Karte verschwanden) und es fehlt oft die tiefe Verkn\u00fcpfung zur\u00fcck zum CRM-Datensatz mit allen Details.<\/p>\n<h3>Die L\u00f6sung: Eine ma\u00dfgeschneiderte Google Maps Integration im Zoho CRM Widget<\/h3>\n<p>Wir bauen eine L\u00f6sung, die sich an den St\u00e4rken bew\u00e4hrter Systeme wie GeoCapture orientiert, aber vollst\u00e4ndig in Zoho CRM lebt. Kernst\u00fcck ist ein Zoho CRM Widget, das die Google Maps JavaScript API nutzt.<\/p>\n<p><strong>Ziel:<\/strong> Eine interaktive Karte im CRM, die unverplante Auftr\u00e4ge anzeigt. Per Drag-and-Drop ziehst Du Auftr\u00e4ge auf eine Tour (z.B. einem Techniker f\u00fcr einen bestimmten Tag zugeordnet). Die Karte zeigt die geplante Route, und ein Klick auf einen Marker \u00f6ffnet direkt den verkn\u00fcpften CRM-Datensatz.<\/p>\n<h3>Schritt-f\u00fcr-Schritt Anleitung zur Umsetzung<\/h3>\n<h4>1. Vorbereitung im Zoho CRM<\/h4>\n<ul>\n<li><strong>Google Maps API Key:<\/strong> Du ben\u00f6tigst einen API-Schl\u00fcssel von der Google Cloud Platform. Aktiviere die &#8222;Maps JavaScript API&#8220;, die &#8222;Geocoding API&#8220; und ggf. die &#8222;Directions API&#8220;. Achte auf die <a href=\"https:\/\/developers.google.com\/maps\/documentation\/credentials\" target=\"_blank\" rel=\"noopener noreferrer\">Best Practices zur Absicherung Deines Keys<\/a> (z.B. HTTP-Referrer-Einschr\u00e4nkung auf Deine Zoho-Domain). Beachte auch die <a href=\"https:\/\/developers.google.com\/maps\/billing\/understanding-cost-of-use\" target=\"_blank\" rel=\"noopener noreferrer\">Nutzungskosten<\/a> (es gibt ein monatliches Freikontingent).<\/li>\n<li><strong>CRM-Modul(e) anpassen:<\/strong>\n<ul>\n<li>Im Modul, das Deine Auftr\u00e4ge enth\u00e4lt (z.B. &#8222;Kundenauftr\u00e4ge&#8220;, &#8222;Deals&#8220;, &#8222;Tasks&#8220; oder ein Custom Module), stelle sicher, dass Du Felder f\u00fcr die vollst\u00e4ndige Adresse hast.<\/li>\n<li>F\u00fcge zwei benutzerdefinierte Felder vom Typ &#8222;Dezimalzahl&#8220; hinzu: `Latitude` und `Longitude`.<\/li>\n<li>F\u00fcge ein Nachschlagefeld (Lookup) zu Deinem Modul f\u00fcr &#8222;Touren&#8220; oder &#8222;Techniker&#8220; hinzu (falls nicht schon vorhanden), um einen Auftrag einer Tour\/einem Techniker zuzuordnen.<\/li>\n<li>F\u00fcge ein Feld f\u00fcr den Planungsstatus hinzu (z.B. &#8222;Offen&#8220;, &#8222;Geplant&#8220;, &#8222;Erledigt&#8220;).<\/li>\n<li>Optional: Ein Feld f\u00fcr die Reihenfolge innerhalb einer Tour (`Sequence_Number` vom Typ Zahl).<\/li>\n<\/ul>\n<\/li>\n<li><strong>Automatische Geokodierung einrichten (Deluge Workflow):<\/strong><br \/>Erstelle eine Workflow-Regel im Auftragsmodul, die bei Erstellung oder Bearbeitung der Adresse ausgel\u00f6st wird. Die Aktion ist eine Custom Function (Deluge), die die Adresse an die Google Geocoding API sendet und die zur\u00fcckgegebenen Koordinaten in die Felder `Latitude` und `Longitude` schreibt.\n<pre><code class=\"language-deluge\">\/\/ Deluge Custom Function: GeocodeAddressAndUpdateRecord\n\/\/ Argument: recordId (String) - ID des Auftragsdatensatzes\n\/\/ Erfordert eine Connection \"googlemapsapi\" f\u00fcr die Geocoding API\n\nvoid GeocodeAddressAndUpdateRecord(string recordId)\n{\n    \/\/ Auftragsdatensatz abrufen\n    recordMap = zoho.crm.getRecordById(\"Kundenauftraege\", recordId.toLong()); \/\/ Modul-API-Namen anpassen!\n    \n    \/\/ Adresse zusammenbauen (Beispiel, Felder anpassen!)\n    street = ifnull(recordMap.get(\"Billing_Street\"),\"\");\n    city = ifnull(recordMap.get(\"Billing_City\"),\"\");\n    zip = ifnull(recordMap.get(\"Billing_Code\"),\"\");\n    country = ifnull(recordMap.get(\"Billing_Country\"),\"\");\n    \n    fullAddress = street + \", \" + zip + \" \" + city + \", \" + country;\n    \n    if(!fullAddress.isEmpty() &amp;&amp; fullAddress.length() &gt; 10) \/\/ Nur geokodieren, wenn Adresse vorhanden ist\n    {\n        try \n        {\n            \/\/ Google Geocoding API aufrufen \u00fcber Connection \"googlemapsapi\"\n            \/\/ URL und Parameter pr\u00fcfen: https:\/\/developers.google.com\/maps\/documentation\/geocoding\/requests-geocoding\n            apiUrl = \"https:\/\/maps.googleapis.com\/maps\/api\/geocode\/json\";\n            paramsMap = Map();\n            paramsMap.put(\"address\", fullAddress.urlEncode());\n            \/\/ Dein API Key wird automatisch durch die Connection hinzugef\u00fcgt\n            \n            \/\/ WICHTIG: Erstelle eine Zoho Connection namens \"googlemapsapi\"\n            \/\/ Service: Google Maps\n            \/\/ Scopes: Erlaube Zugriff auf Geocoding API\n            \/\/ Parameter: 'key' mit deinem API Key (wird meist automatisch angeh\u00e4ngt)\n            response = invokeurl\n            [\n                url :apiUrl\n                type :GET\n                parameters:paramsMap\n                connection:\"googlemapsapi\" \/\/ Name Deiner Connection\n            ];\n            \n            \/\/ info response; \/\/ Zum Debuggen\n            \n            jsonResponse = response.toJSON();\n            if(jsonResponse.get(\"status\") == \"OK\")\n            {\n                location = jsonResponse.get(\"results\").get(0).get(\"geometry\").get(\"location\");\n                latitude = location.get(\"lat\");\n                longitude = location.get(\"lng\");\n                \n                \/\/ Update CRM Record\n                updateMap = Map();\n                updateMap.put(\"Latitude\", latitude);\n                updateMap.put(\"Longitude\", longitude);\n                updateResp = zoho.crm.updateRecord(\"Kundenauftraege\", recordId.toLong(), updateMap);\n                info \"Geocoding successful for \" + recordId + \": \" + updateResp;\n            }\n            else\n            {\n                info \"Geocoding failed for \" + recordId + \": \" + jsonResponse.get(\"status\") + \" - \" + jsonResponse.get(\"error_message\");\n            }\n        }\n        catch (e)\n        {\n            info \"Error during Geocoding API call for \" + recordId + \": \" + e;\n        }    \n    }\n    else\n    {\n        info \"Skipping geocoding for \" + recordId + \" due to missing address.\";\n    }\n}<\/code><\/pre>\n<p><em>Wichtig:<\/em> Passe die Feld-API-Namen (`Billing_Street`, `Latitude` etc.) und den Modul-API-Namen (`Kundenauftraege`) an Deine CRM-Konfiguration an. Erstelle die notwendige Zoho Connection f\u00fcr die Google Maps API.<\/p>\n<\/li>\n<\/ul>\n<h4>2. Das Zoho CRM Widget erstellen<\/h4>\n<p>Ein Widget ist eine kleine Webanwendung, die innerhalb von Zoho CRM l\u00e4uft. Hier bauen wir unsere Kartenoberfl\u00e4che.<\/p>\n<ul>\n<li>Gehe zu Setup -&gt; Entwicklerbereich -&gt; Widgets.<\/li>\n<li>Erstelle ein neues Widget (z.B. &#8222;Tourenplaner Karte&#8220;).<\/li>\n<li>Typ: &#8222;Web Tab&#8220; oder f\u00fcr Einbettung in Layouts geeignet.<\/li>\n<li>Hosting: Zoho hostet den Code f\u00fcr Dich.<\/li>\n<li>Du erh\u00e4ltst eine `widget.html`, eine `widget.js` und eine `widget.css` Datei sowie eine `widget_function. deluge` f\u00fcr Backend-Logik.<\/li>\n<\/ul>\n<h4>3. Die Kartenoberfl\u00e4che im Widget (HTML &amp; JavaScript)<\/h4>\n<p>In `widget.html` l\u00e4dst Du die Google Maps API und definierst den Container f\u00fcr die Karte.<\/p>\n<pre><code class=\"language-html\">&lt;!DOCTYPE html&gt;\n&lt;html&gt;\n&lt;head&gt;\n    &lt;title&gt;Tourenplaner Karte&lt;\/title&gt;\n    &lt;link rel=\"stylesheet\" href=\"widget.css\"&gt;\n    &lt;!-- Zoho Widget SDK --&gt;\n    &lt;script src=\"https:\/\/static.zohocdn.com\/crm\/plugin_sdk\/2.1\/plugin-sdk.js\"&gt;&lt;\/script&gt;\n&lt;\/head&gt;\n&lt;body&gt;\n    &lt;div id=\"map\" style=\"height: 500px; width: 100%;\"&gt;&lt;\/div&gt;\n    &lt;!-- Hier k\u00f6nnten noch UI-Elemente f\u00fcr Tourauswahl, etc. hin --&gt;\n\n    &lt;script src=\"widget.js\"&gt;&lt;\/script&gt;\n    &lt;!-- Lade Google Maps API (ersetze YOUR_API_KEY) --&gt;\n    &lt;script async defer\n        src=\"https:\/\/maps.googleapis.com\/maps\/api\/js?key=YOUR_API_KEY&amp;callback=initMap\"&gt;\n    &lt;\/script&gt;\n&lt;\/body&gt;\n&lt;\/html&gt;<\/code><\/pre>\n<p>In `widget.js` initialisierst Du die Karte, rufst eine Deluge-Funktion auf, um die Auftragsdaten zu holen, und zeichnest die Marker.<\/p>\n<pre><code class=\"language-javascript\">\/\/ widget.js\n\nlet map;\nlet markers = []; \/\/ Array, um Marker zu speichern\n\n\/\/ Wird aufgerufen, wenn das Google Maps Script geladen ist\nfunction initMap() {\n    const mapOptions = {\n        center: { lat: 51.1657, lng: 10.4515 }, \/\/ Zentrum Deutschland (anpassen!)\n        zoom: 6,\n    };\n    map = new google.maps.Map(document.getElementById('map'), mapOptions);\n\n    \/\/ Initialisiere Zoho Widget SDK\n    ZOHO.embeddedApp.on(\"PageLoad\", function(data) {\n        console.log(\"Widget loaded:\", data);\n        loadUnassignedJobs(); \/\/ Lade unverplante Auftr\u00e4ge beim Start\n    });\n    ZOHO.embeddedApp.init();\n}\n\n\/\/ Funktion zum Laden unverplanter Auftr\u00e4ge\nfunction loadUnassignedJobs() {\n    \/\/ Rufe Deluge-Funktion 'getUnassignedJobs' auf\n    ZOHO.CRM.FUNCTIONS.execute(\"getUnassignedJobs\", {}) \/\/ Name der Deluge-Funktion\n        .then(function(response) {\n            if (response.code === 'success') {\n                const jobs = JSON.parse(response.details.output);\n                console.log(\"Received jobs:\", jobs);\n                clearMarkers(); \/\/ Bestehende Marker entfernen\n                addJobMarkers(jobs); \/\/ Neue Marker hinzuf\u00fcgen\n            } else {\n                console.error(\"Error fetching jobs:\", response);\n                alert(\"Fehler beim Laden der Auftr\u00e4ge.\");\n            }\n        })\n        .catch(function(error) {\n            console.error(\"Error executing Deluge function:\", error);\n            alert(\"Schwerwiegender Fehler beim Laden der Auftr\u00e4ge.\");\n        });\n}\n\n\/\/ F\u00fcgt Marker f\u00fcr Auftr\u00e4ge zur Karte hinzu\nfunction addJobMarkers(jobs) {\n    jobs.forEach(job =&gt; {\n        \/\/ Pr\u00fcfe, ob Latitude und Longitude g\u00fcltig sind\n        if (job.Latitude &amp;&amp; job.Longitude) {\n            const position = { lat: parseFloat(job.Latitude), lng: parseFloat(job.Longitude) };\n            \n            const marker = new google.maps.Marker({\n                position: position,\n                map: map,\n                title: job.Subject || job.Name || 'Auftrag ' + job.id, \/\/ Titel anpassen\n                draggable: true, \/\/ Wichtig f\u00fcr Drag-and-Drop\n                \/\/ Eigene Daten am Marker speichern (WICHTIG!)\n                jobId: job.id, \n                jobModule: job.module \/\/ z.B. 'Kundenauftraege'\n            });\n\n            \/\/ Klick-Event: \u00d6ffne CRM-Datensatz\n            marker.addListener('click', () =&gt; {\n                console.log(\"Marker clicked, opening CRM record:\", marker.jobId, marker.jobModule);\n                 ZOHO.CRM.UI.Record.open({ Entity: marker.jobModule, RecordID: marker.jobId })\n                    .then(function(data){\n                        console.log(\"Record opened successfully\", data);\n                    })\n                    .catch(function(error){\n                         console.error(\"Error opening record\", error);\n                    });\n            });\n\n            \/\/ Drag-End-Event: Hier wird die Logik zum Zuweisen zu einer Tour ausgel\u00f6st\n            marker.addListener('dragend', (event) =&gt; {\n                 handleMarkerDrop(marker, event.latLng);\n            });\n\n            markers.push(marker);\n        } else {\n            console.warn(\"Skipping job due to missing coordinates:\", job.id, job);\n        }\n    });\n     \/\/ Optional: Marker Clustering hinzuf\u00fcgen bei vielen Markern\n     \/\/ Siehe: https:\/\/developers.google.com\/maps\/documentation\/javascript\/marker-clustering\n}\n\n\/\/ Funktion zum Entfernen aller Marker von der Karte\nfunction clearMarkers() {\n    markers.forEach(marker =&gt; marker.setMap(null));\n    markers = [];\n}\n\n\/\/ Funktion, die aufgerufen wird, wenn ein Marker fallengelassen wird\nfunction handleMarkerDrop(marker, dropPosition) {\n    console.log(`Marker ${marker.jobId} dropped at ${dropPosition.lat()}, ${dropPosition.lng()}`);\n    \n    \/\/ HIER kommt die Logik, um zu bestimmen, auf welche Tour der Marker gezogen wurde.\n    \/\/ Das h\u00e4ngt stark von Deinem UI-Design ab (z.B. Zonen auf der Karte, eine Liste neben der Karte).\n    \/\/ Annahme: Du hast eine Funktion `getTargetTourId(dropPosition)` die die ID der Ziel-Tour liefert.\n    const targetTourId = getTargetTourId(dropPosition); \/\/ Dummy-Funktion\n\n    if (targetTourId) {\n        console.log(`Assigning job ${marker.jobId} to tour ${targetTourId}`);\n        \/\/ Rufe Deluge-Funktion auf, um CRM zu aktualisieren\n         ZOHO.CRM.FUNCTIONS.execute(\"assignJobToTour\", { jobId: marker.jobId, tourId: targetTourId, jobModule: marker.jobModule })\n            .then(function(response){\n                 if(response.code === 'success'){\n                     console.log(\"Job assigned successfully in CRM.\");\n                     \/\/ Optional: Marker von der Karte entfernen oder anders darstellen\n                     marker.setDraggable(false); \/\/ Nicht mehr ziehbar nach Zuweisung\n                     \/\/ marker.setMap(null); \/\/ Oder ganz entfernen\n                 } else {\n                      console.error(\"Error assigning job in CRM:\", response);\n                      alert(\"Fehler beim Zuweisen des Auftrags.\");\n                      \/\/ Marker zur\u00fccksetzen? Oder Fehler anzeigen.\n                 }\n            })\n             .catch(function(error){\n                  console.error(\"Error calling assignJobToTour function:\", error);\n                  alert(\"Schwerwiegender Fehler beim Zuweisen.\");\n             });\n    } else {\n        console.log(\"Marker dropped outside a valid tour area.\");\n        \/\/ Optional: Marker an urspr\u00fcngliche Position zur\u00fccksnappen lassen (komplexer)\n    }\n}\n\n\/\/ Platzhalter - Diese Funktion musst Du basierend auf Deinem UI implementieren!\nfunction getTargetTourId(dropPosition) {\n    \/\/ Beispiel: Pr\u00fcfen, ob die Position innerhalb eines definierten Polygons liegt,\n    \/\/ oder ob der Drop \u00fcber einem HTML-Element f\u00fcr eine Tour stattfand.\n    \/\/ F\u00fcrs Erste geben wir einen Dummy-Wert zur\u00fcck, wenn Du eine Tour-Liste hast.\n    \/\/ const tourListElement = document.getElementById('tour-list'); \n    \/\/ if (\/* Logik, um zu pr\u00fcfen ob Drop \u00fcber Tour-Liste war *\/) { return \/* ID der Tour *\/}\n    \n    \/\/ Einfaches Beispiel: Gib eine feste ID zur\u00fcck zum Testen\n    console.warn(\"getTargetTourId is just a placeholder!\");\n    return \"DUMMY_TOUR_ID_123\"; \/\/ Ersetze dies durch echte Logik!\n}<\/code><\/pre>\n<h4>4. Backend-Logik im Widget (Deluge)<\/h4>\n<pre><code class=\"language-javascript\"><\/code><\/pre>\n<p>In `widget_function.deluge` definierst Du die Funktionen, die von JavaScript aufgerufen werden.<\/p>\n<pre><code class=\"language-javascript\"><\/code><\/pre>\n<pre><code class=\"language-deluge\">\/\/ widget_function.deluge\n\n\/\/ Funktion zum Abrufen unverplanter Auftr\u00e4ge\n\/\/ Passt Kriterien und Felder nach Bedarf an!\nstring getUnassignedJobs()\n{\n    jobList = List();\n    try\n    {\n        \/\/ Beispiel: Hole alle Auftr\u00e4ge im Status 'Offen' ohne zugewiesene Tour\n        \/\/ Passe Modul-API-Namen und Feldnamen an!\n        criteria = \"((Planungsstatus:equals:Offen) and (Tour:isnull))\"; \n        response = zoho.crm.searchRecords(\"Kundenauftraege\", criteria, 1, 200); \/\/ Max 200 pro Aufruf, Paginierung ggf. n\u00f6tig\n        \n        for each record in response\n        {\n            recordMap = Map();\n            recordMap.put(\"id\", record.get(\"id\"));\n            recordMap.put(\"module\", \"Kundenauftraege\"); \/\/ Wichtig f\u00fcr ZOHO.CRM.UI.Record.open\n            recordMap.put(\"Name\", record.get(\"Name\")); \/\/ Auftragsname\/Betreff\n            recordMap.put(\"Subject\", record.get(\"Subject\")); \/\/ Oder Betreff\n            recordMap.put(\"Latitude\", record.get(\"Latitude\"));\n            recordMap.put(\"Longitude\", record.get(\"Longitude\"));\n            \/\/ F\u00fcge weitere ben\u00f6tigte Felder hinzu (z.B. F\u00e4lligkeit)\n            jobList.add(recordMap);\n        }\n        return {\"output\": jobList.toString()}.toString(); \/\/ Gib als JSON-String zur\u00fcck\n    }\n    catch (e)\n    {\n        info \"Error in getUnassignedJobs: \" + e;\n        \/\/ Bessere Fehlerbehandlung f\u00fcr Produktion\n        return {\"error\": \"Failed to fetch jobs\", \"details\": e}.toString(); \n    }\n}\n\n\n\/\/ Funktion zum Zuweisen eines Auftrags zu einer Tour\n\/\/ Erh\u00e4lt jobId, tourId und jobModule vom Frontend\nstring assignJobToTour(map params)\n{\n    jobId = params.get(\"jobId\");\n    tourId = params.get(\"tourId\"); \/\/ Dies ist ggf. die ID des Technikers oder eines Tour-Datensatzes\n    jobModule = params.get(\"jobModule\"); \/\/ z.B. \"Kundenauftraege\"\n    \n    if(jobId == null || tourId == null || jobModule == null)\n    {\n        return {\"error\": \"Missing parameters\"}.toString();\n    }\n\n    try\n    {\n        updateMap = Map();\n        \/\/ Beispiel: Aktualisiere Nachschlagefeld 'Tour' und Status\n        \/\/ Passe Feld-API-Namen an!\n        updateMap.put(\"Tour\", tourId); \/\/ Hier die ID des Tour\/Techniker-Datensatzes eintragen\n        updateMap.put(\"Planungsstatus\", \"Geplant\"); \n        \/\/ Optional: Sequence_Number aktualisieren (komplexer, erfordert Z\u00e4hlung)\n\n        updateResp = zoho.crm.updateRecord(jobModule, jobId.toLong(), updateMap);\n        info \"Assign Job Response: \" + updateResp;\n        \n        if(updateResp.containKey(\"id\"))\n        {\n             return {\"output\": \"success\"}.toString();\n        }\n        else\n        {\n             return {\"error\": \"Failed to update CRM record\", \"details\": updateResp}.toString();\n        }\n    }\n    catch (e)\n    {\n        info \"Error in assignJobToTour: \" + e;\n        return {\"error\": \"Exception during CRM update\", \"details\": e}.toString();\n    }\n}\n\n\/\/ Weitere Funktionen nach Bedarf:\n\/\/ - getTourDetails(tourId): Holt Details einer spezifischen Tour (inkl. bereits zugewiesener Jobs)\n\/\/ - removeJobFromTour(jobId): Setzt den Job wieder auf 'Offen' und entfernt die Tour-Zuordnung\n\/\/ - calculateRoute(tourId): Ruft ggf. die Google Directions API auf, um eine optimierte Route zu berechnen und zu speichern.\n\n<\/code><\/pre>\n<pre><code class=\"language-javascript\"><\/code><\/pre>\n<h3>Tipps und Best Practices<\/h3>\n<pre><code class=\"language-javascript\"><\/code><\/pre>\n<ul>\n<li><strong>API-Kosten im Blick:<\/strong> Geokodierung beim Speichern (statt live) spart API-Aufrufe. \u00dcberwache Deine Google Cloud Platform-Nutzung.<\/li>\n<li><strong>Fehlerbehandlung:<\/strong> Implementiere robuste Fehlerbehandlung sowohl im Deluge-Backend (try-catch) als auch im JavaScript-Frontend (z.B. wenn Geokodierung fehlschl\u00e4gt oder API-Limits erreicht sind).<\/li>\n<li><strong>User Experience (UX):<\/strong> Gestalte das Widget \u00fcbersichtlich. F\u00fcge vielleicht eine Liste der verf\u00fcgbaren Touren\/Techniker hinzu, auf die per Drag-and-Drop gezogen werden kann. Visuelles Feedback (z.B. Farb\u00e4nderung des Markers nach Zuweisung) ist hilfreich.<\/li>\n<li><strong>Skalierbarkeit:<\/strong> Bei sehr vielen Auftr\u00e4gen (&gt; 200-500) auf der Karte kann die Performance leiden. Nutze Google Maps Marker Clustering, um nahe beieinander liegende Punkte zu gruppieren. Implementiere Paginierung beim Laden der Auftr\u00e4ge aus dem CRM via Deluge.<\/li>\n<li><strong>Sicherheit:<\/strong> Sichere Deinen Google Maps API Key so gut wie m\u00f6glich (HTTP-Referrer, ggf. IP-Einschr\u00e4nkungen). Speichere Keys nicht direkt im Frontend-Code. Die Zoho Connection ist hier ein guter Ansatz.<\/li>\n<li><strong>CRM-Struktur:<\/strong> \u00dcberlege Dir gut, wie Du Touren im CRM abbildest. Ein eigenes Modul &#8222;Touren&#8220; mit Verkn\u00fcpfung zu Technikern (Users oder ein eigenes Modul) und einem Related List \/ Subform f\u00fcr die zugeordneten &#8222;Kundenauftr\u00e4ge&#8220; ist oft eine saubere L\u00f6sung. Wie im Gespr\u00e4ch erw\u00e4hnt: Nutze f\u00fcr Listen von verkn\u00fcpften Datens\u00e4tzen (wie Mitarbeiter in einem Team oder Auftr\u00e4ge in einer Tour) eher <strong>Unterformulare (Subforms)<\/strong> statt einfacher Mehrfachauswahl-Felder, da sie strukturierter sind und mehr Informationen pro Eintrag speichern k\u00f6nnen.<\/li>\n<li><strong>Datenkonsistenz:<\/strong> Stelle sicher, dass Status\u00e4nderungen (z.B. von &#8222;Geplant&#8220; zu &#8222;Erledigt&#8220;) korrekt im CRM abgebildet werden, eventuell durch eine weitere Funktion im Widget oder durch manuelle Updates der Techniker.<\/li>\n<\/ul>\n<pre><code class=\"language-javascript\"><\/code><\/pre>\n<h3>Zus\u00e4tzliche Hinweise und Erweiterungen<\/h3>\n<pre><code class=\"language-javascript\"><\/code><\/pre>\n<ul>\n<li><strong>Zoho Flow \/ Webhooks:<\/strong> Nutze Zoho Flow oder Webhooks, um Benachrichtigungen auszul\u00f6sen, wenn eine Tour geplant oder ge\u00e4ndert wird (z.B. E-Mail an den Techniker).<\/li>\n<li><strong>Zoho Analytics:<\/strong> Analysiere die Planungs- und Ausf\u00fchrungsdaten (geplante vs. tats\u00e4chliche Zeiten, Anzahl Auftr\u00e4ge pro Tour etc.) mit Zoho Analytics f\u00fcr tiefere Einblicke.<\/li>\n<li><strong>Mobile Nutzung:<\/strong> Die Techniker k\u00f6nnten \u00fcber die Zoho CRM Mobile App auf ihre geplanten Auftr\u00e4ge zugreifen. Der im CRM gespeicherte Link zur Google Maps Route (falls Du die Directions API nutzt) w\u00e4re hier hilfreich.<\/li>\n<li><strong>Zoho Creator:<\/strong> F\u00fcr noch komplexere UI-Anforderungen oder spezifische Workflows k\u00f6nntest Du sogar eine Zoho Creator App bauen und diese als Widget einbetten.<\/li>\n<\/ul>\n<pre><code class=\"language-javascript\"><\/code><\/pre>\n<h3>Fazit: Mehrwert durch ma\u00dfgeschneiderte Integration<\/h3>\n<pre><code class=\"language-javascript\"><\/code><\/pre>\n<p>Die Erstellung einer benutzerdefinierten Tourenplanung mit der Google Maps API direkt in Zoho CRM ist ein m\u00e4chtiger Ansatz, um die Einschr\u00e4nkungen von Standardl\u00f6sungen zu \u00fcberwinden. Du gewinnst maximale Flexibilit\u00e4t und beh\u00e4ltst die volle Kontrolle \u00fcber den Planungsprozess. Die tiefe Integration stellt sicher, dass alle relevanten Informationen dort verf\u00fcgbar sind, wo sie gebraucht werden \u2013 im CRM und direkt auf der Karte.<\/p>\n<p>Auch wenn die initiale Einrichtung technischen Aufwand erfordert, zahlt sich die Investition durch effizientere Prozesse, zufriedenere Disponenten und Techniker sowie eine bessere Datengrundlage schnell aus. Dieses Beispiel zeigt eindrucksvoll, wie Du durch die Kombination von Zoho-Werkzeugen (CRM, Widgets, Deluge) und externen APIs (Google Maps) hochgradig angepasste und wertsch\u00f6pfende L\u00f6sungen f\u00fcr Dein Unternehmen schaffen kannst.<\/p>\n<pre><code class=\"language-javascript\"><\/code><\/pre>\n<pre><code class=\"language-javascript\"><\/code><\/pre>\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Erhalte volle Kontrolle \u00fcber Deine Au\u00dfendiensttourenplanung in Zoho CRM dank individueller Google Maps API-Integration. Effizient, flexibel und nahtlos integriert!<\/p>\n","protected":false},"author":1,"featured_media":1482,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"ocean_post_layout":"","ocean_both_sidebars_style":"","ocean_both_sidebars_content_width":0,"ocean_both_sidebars_sidebars_width":0,"ocean_sidebar":"","ocean_second_sidebar":"","ocean_disable_margins":"enable","ocean_add_body_class":"","ocean_shortcode_before_top_bar":"","ocean_shortcode_after_top_bar":"","ocean_shortcode_before_header":"","ocean_shortcode_after_header":"","ocean_has_shortcode":"","ocean_shortcode_after_title":"","ocean_shortcode_before_footer_widgets":"","ocean_shortcode_after_footer_widgets":"","ocean_shortcode_before_footer_bottom":"","ocean_shortcode_after_footer_bottom":"","ocean_display_top_bar":"default","ocean_display_header":"default","ocean_header_style":"","ocean_center_header_left_menu":"","ocean_custom_header_template":"","ocean_custom_logo":0,"ocean_custom_retina_logo":0,"ocean_custom_logo_max_width":0,"ocean_custom_logo_tablet_max_width":0,"ocean_custom_logo_mobile_max_width":0,"ocean_custom_logo_max_height":0,"ocean_custom_logo_tablet_max_height":0,"ocean_custom_logo_mobile_max_height":0,"ocean_header_custom_menu":"","ocean_menu_typo_font_family":"","ocean_menu_typo_font_subset":"","ocean_menu_typo_font_size":0,"ocean_menu_typo_font_size_tablet":0,"ocean_menu_typo_font_size_mobile":0,"ocean_menu_typo_font_size_unit":"px","ocean_menu_typo_font_weight":"","ocean_menu_typo_font_weight_tablet":"","ocean_menu_typo_font_weight_mobile":"","ocean_menu_typo_transform":"","ocean_menu_typo_transform_tablet":"","ocean_menu_typo_transform_mobile":"","ocean_menu_typo_line_height":0,"ocean_menu_typo_line_height_tablet":0,"ocean_menu_typo_line_height_mobile":0,"ocean_menu_typo_line_height_unit":"","ocean_menu_typo_spacing":0,"ocean_menu_typo_spacing_tablet":0,"ocean_menu_typo_spacing_mobile":0,"ocean_menu_typo_spacing_unit":"","ocean_menu_link_color":"","ocean_menu_link_color_hover":"","ocean_menu_link_color_active":"","ocean_menu_link_background":"","ocean_menu_link_hover_background":"","ocean_menu_link_active_background":"","ocean_menu_social_links_bg":"","ocean_menu_social_hover_links_bg":"","ocean_menu_social_links_color":"","ocean_menu_social_hover_links_color":"","ocean_disable_title":"default","ocean_disable_heading":"default","ocean_post_title":"","ocean_post_subheading":"","ocean_post_title_style":"","ocean_post_title_background_color":"","ocean_post_title_background":0,"ocean_post_title_bg_image_position":"","ocean_post_title_bg_image_attachment":"","ocean_post_title_bg_image_repeat":"","ocean_post_title_bg_image_size":"","ocean_post_title_height":0,"ocean_post_title_bg_overlay":0.5,"ocean_post_title_bg_overlay_color":"","ocean_disable_breadcrumbs":"default","ocean_breadcrumbs_color":"","ocean_breadcrumbs_separator_color":"","ocean_breadcrumbs_links_color":"","ocean_breadcrumbs_links_hover_color":"","ocean_display_footer_widgets":"default","ocean_display_footer_bottom":"default","ocean_custom_footer_template":"","osh_disable_topbar_sticky":"default","osh_disable_header_sticky":"default","osh_sticky_header_style":"default","osh_sticky_header_effect":"","osh_custom_sticky_logo":0,"osh_custom_retina_sticky_logo":0,"osh_custom_sticky_logo_height":0,"osh_background_color":"","osh_links_color":"","osh_links_hover_color":"","osh_links_active_color":"","osh_links_bg_color":"","osh_links_hover_bg_color":"","osh_links_active_bg_color":"","osh_menu_social_links_color":"","osh_menu_social_hover_links_color":"","ocean_post_oembed":"","ocean_post_self_hosted_media":"","ocean_post_video_embed":"","ocean_link_format":"","ocean_link_format_target":"self","ocean_quote_format":"","ocean_quote_format_link":"post","ocean_gallery_link_images":"on","ocean_gallery_id":[],"footnotes":""},"categories":[1],"tags":[121,309,544,543,107,541,545,191,546,542,190,308,192,181,96,540,233,547],"class_list":["post-1466","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-zoho","tag-api-integration","tag-ausendienststeuerung","tag-benutzerdefinierte-losung","tag-crm-anpassung","tag-deluge","tag-geokodierung","tag-google-geocoding-api","tag-google-maps-api","tag-google-maps-javascript-api","tag-kartenintegration","tag-prozessoptimierung","tag-routenplanung","tag-tourenplanung","tag-workflow-automatisierung","tag-zoho-crm","tag-zoho-crm-widget","tag-zoho-custom-function","tag-zoho-development","entry","has-media"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Individuelle Tourenplanung mit Zoho CRM und Google Maps API gestalten - SprintCX<\/title>\n<meta name=\"robots\" content=\"noindex, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<meta property=\"og:locale\" content=\"de_DE\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Individuelle Tourenplanung mit Zoho CRM und Google Maps API gestalten - SprintCX\" \/>\n<meta property=\"og:description\" content=\"Erhalte volle Kontrolle \u00fcber Deine Au\u00dfendiensttourenplanung in Zoho CRM dank individueller Google Maps API-Integration. Effizient, flexibel und nahtlos integriert!\" \/>\n<meta property=\"og:url\" content=\"https:\/\/wordpress.sprintcx.net\/de\/individuelle-tourenplanung-mit-zoho-crm-und-google-maps-api-gestalten\/\" \/>\n<meta property=\"og:site_name\" content=\"SprintCX\" \/>\n<meta property=\"article:published_time\" content=\"2025-04-29T12:25:48+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-04-29T16:35:50+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/wordpress.sprintcx.net\/wp-content\/uploads\/2025\/04\/1745944361-6810ff292048c.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1408\" \/>\n\t<meta property=\"og:image:height\" content=\"768\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Gregor\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Verfasst von\" \/>\n\t<meta name=\"twitter:data1\" content=\"Gregor\" \/>\n\t<meta name=\"twitter:label2\" content=\"Gesch\u00e4tzte Lesezeit\" \/>\n\t<meta name=\"twitter:data2\" content=\"6\u00a0Minuten\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/wordpress.sprintcx.net\\\/de\\\/individuelle-tourenplanung-mit-zoho-crm-und-google-maps-api-gestalten\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/wordpress.sprintcx.net\\\/de\\\/individuelle-tourenplanung-mit-zoho-crm-und-google-maps-api-gestalten\\\/\"},\"author\":{\"name\":\"Gregor\",\"@id\":\"https:\\\/\\\/wordpress.sprintcx.net\\\/de\\\/#\\\/schema\\\/person\\\/33a4ba085d0b86874d45522b74c193eb\"},\"headline\":\"Individuelle Tourenplanung mit Zoho CRM und Google Maps API gestalten\",\"datePublished\":\"2025-04-29T12:25:48+00:00\",\"dateModified\":\"2025-04-29T16:35:50+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/wordpress.sprintcx.net\\\/de\\\/individuelle-tourenplanung-mit-zoho-crm-und-google-maps-api-gestalten\\\/\"},\"wordCount\":1330,\"publisher\":{\"@id\":\"https:\\\/\\\/wordpress.sprintcx.net\\\/de\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/wordpress.sprintcx.net\\\/de\\\/individuelle-tourenplanung-mit-zoho-crm-und-google-maps-api-gestalten\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/wordpress.sprintcx.net\\\/wp-content\\\/uploads\\\/2025\\\/04\\\/1745944361-6810ff292048c.png\",\"keywords\":[\"API Integration\",\"Au\u00dfendienststeuerung\",\"Benutzerdefinierte L\u00f6sung\",\"CRM-Anpassung\",\"Deluge\",\"Geokodierung\",\"Google Geocoding API\",\"Google Maps API\",\"Google Maps JavaScript API\",\"Kartenintegration\",\"Prozessoptimierung\",\"Routenplanung\",\"Tourenplanung\",\"Workflow-Automatisierung\",\"Zoho CRM\",\"Zoho CRM Widget\",\"Zoho Custom Function\",\"Zoho Development\"],\"articleSection\":[\"Zoho Tutorials\"],\"inLanguage\":\"de\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/wordpress.sprintcx.net\\\/de\\\/individuelle-tourenplanung-mit-zoho-crm-und-google-maps-api-gestalten\\\/\",\"url\":\"https:\\\/\\\/wordpress.sprintcx.net\\\/de\\\/individuelle-tourenplanung-mit-zoho-crm-und-google-maps-api-gestalten\\\/\",\"name\":\"Individuelle Tourenplanung mit Zoho CRM und Google Maps API gestalten - SprintCX\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/wordpress.sprintcx.net\\\/de\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/wordpress.sprintcx.net\\\/de\\\/individuelle-tourenplanung-mit-zoho-crm-und-google-maps-api-gestalten\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/wordpress.sprintcx.net\\\/de\\\/individuelle-tourenplanung-mit-zoho-crm-und-google-maps-api-gestalten\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/wordpress.sprintcx.net\\\/wp-content\\\/uploads\\\/2025\\\/04\\\/1745944361-6810ff292048c.png\",\"datePublished\":\"2025-04-29T12:25:48+00:00\",\"dateModified\":\"2025-04-29T16:35:50+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/wordpress.sprintcx.net\\\/de\\\/individuelle-tourenplanung-mit-zoho-crm-und-google-maps-api-gestalten\\\/#breadcrumb\"},\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/wordpress.sprintcx.net\\\/de\\\/individuelle-tourenplanung-mit-zoho-crm-und-google-maps-api-gestalten\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/wordpress.sprintcx.net\\\/de\\\/individuelle-tourenplanung-mit-zoho-crm-und-google-maps-api-gestalten\\\/#primaryimage\",\"url\":\"https:\\\/\\\/wordpress.sprintcx.net\\\/wp-content\\\/uploads\\\/2025\\\/04\\\/1745944361-6810ff292048c.png\",\"contentUrl\":\"https:\\\/\\\/wordpress.sprintcx.net\\\/wp-content\\\/uploads\\\/2025\\\/04\\\/1745944361-6810ff292048c.png\",\"width\":1408,\"height\":768},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/wordpress.sprintcx.net\\\/de\\\/individuelle-tourenplanung-mit-zoho-crm-und-google-maps-api-gestalten\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/wordpress.sprintcx.net\\\/de\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Individuelle Tourenplanung mit Zoho CRM und Google Maps API gestalten\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/wordpress.sprintcx.net\\\/de\\\/#website\",\"url\":\"https:\\\/\\\/wordpress.sprintcx.net\\\/de\\\/\",\"name\":\"SprintCX\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\\\/\\\/wordpress.sprintcx.net\\\/de\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/wordpress.sprintcx.net\\\/de\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"de\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/wordpress.sprintcx.net\\\/de\\\/#organization\",\"name\":\"SprintCX\",\"url\":\"https:\\\/\\\/wordpress.sprintcx.net\\\/de\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/wordpress.sprintcx.net\\\/de\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/wordpress.sprintcx.net\\\/wp-content\\\/uploads\\\/2025\\\/05\\\/cropped-ChatGPT-Image-6.-Mai-2025-09_53_42.png\",\"contentUrl\":\"https:\\\/\\\/wordpress.sprintcx.net\\\/wp-content\\\/uploads\\\/2025\\\/05\\\/cropped-ChatGPT-Image-6.-Mai-2025-09_53_42.png\",\"width\":846,\"height\":828,\"caption\":\"SprintCX\"},\"image\":{\"@id\":\"https:\\\/\\\/wordpress.sprintcx.net\\\/de\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.linkedin.com\\\/in\\\/gregor-sprint\\\/\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/wordpress.sprintcx.net\\\/de\\\/#\\\/schema\\\/person\\\/33a4ba085d0b86874d45522b74c193eb\",\"name\":\"Gregor\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/890daf3cadca0407ae6752f5d3c0f4a1bbb2ce129b70d5e65fbefcc86deba987?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/890daf3cadca0407ae6752f5d3c0f4a1bbb2ce129b70d5e65fbefcc86deba987?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/890daf3cadca0407ae6752f5d3c0f4a1bbb2ce129b70d5e65fbefcc86deba987?s=96&d=mm&r=g\",\"caption\":\"Gregor\"},\"sameAs\":[\"https:\\\/\\\/sprintcx.net\"],\"url\":\"https:\\\/\\\/wordpress.sprintcx.net\\\/de\\\/author\\\/gregor\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Individuelle Tourenplanung mit Zoho CRM und Google Maps API gestalten - SprintCX","robots":{"index":"noindex","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"og_locale":"de_DE","og_type":"article","og_title":"Individuelle Tourenplanung mit Zoho CRM und Google Maps API gestalten - SprintCX","og_description":"Erhalte volle Kontrolle \u00fcber Deine Au\u00dfendiensttourenplanung in Zoho CRM dank individueller Google Maps API-Integration. Effizient, flexibel und nahtlos integriert!","og_url":"https:\/\/wordpress.sprintcx.net\/de\/individuelle-tourenplanung-mit-zoho-crm-und-google-maps-api-gestalten\/","og_site_name":"SprintCX","article_published_time":"2025-04-29T12:25:48+00:00","article_modified_time":"2025-04-29T16:35:50+00:00","og_image":[{"width":1408,"height":768,"url":"https:\/\/wordpress.sprintcx.net\/wp-content\/uploads\/2025\/04\/1745944361-6810ff292048c.png","type":"image\/png"}],"author":"Gregor","twitter_card":"summary_large_image","twitter_misc":{"Verfasst von":"Gregor","Gesch\u00e4tzte Lesezeit":"6\u00a0Minuten"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/wordpress.sprintcx.net\/de\/individuelle-tourenplanung-mit-zoho-crm-und-google-maps-api-gestalten\/#article","isPartOf":{"@id":"https:\/\/wordpress.sprintcx.net\/de\/individuelle-tourenplanung-mit-zoho-crm-und-google-maps-api-gestalten\/"},"author":{"name":"Gregor","@id":"https:\/\/wordpress.sprintcx.net\/de\/#\/schema\/person\/33a4ba085d0b86874d45522b74c193eb"},"headline":"Individuelle Tourenplanung mit Zoho CRM und Google Maps API gestalten","datePublished":"2025-04-29T12:25:48+00:00","dateModified":"2025-04-29T16:35:50+00:00","mainEntityOfPage":{"@id":"https:\/\/wordpress.sprintcx.net\/de\/individuelle-tourenplanung-mit-zoho-crm-und-google-maps-api-gestalten\/"},"wordCount":1330,"publisher":{"@id":"https:\/\/wordpress.sprintcx.net\/de\/#organization"},"image":{"@id":"https:\/\/wordpress.sprintcx.net\/de\/individuelle-tourenplanung-mit-zoho-crm-und-google-maps-api-gestalten\/#primaryimage"},"thumbnailUrl":"https:\/\/wordpress.sprintcx.net\/wp-content\/uploads\/2025\/04\/1745944361-6810ff292048c.png","keywords":["API Integration","Au\u00dfendienststeuerung","Benutzerdefinierte L\u00f6sung","CRM-Anpassung","Deluge","Geokodierung","Google Geocoding API","Google Maps API","Google Maps JavaScript API","Kartenintegration","Prozessoptimierung","Routenplanung","Tourenplanung","Workflow-Automatisierung","Zoho CRM","Zoho CRM Widget","Zoho Custom Function","Zoho Development"],"articleSection":["Zoho Tutorials"],"inLanguage":"de"},{"@type":"WebPage","@id":"https:\/\/wordpress.sprintcx.net\/de\/individuelle-tourenplanung-mit-zoho-crm-und-google-maps-api-gestalten\/","url":"https:\/\/wordpress.sprintcx.net\/de\/individuelle-tourenplanung-mit-zoho-crm-und-google-maps-api-gestalten\/","name":"Individuelle Tourenplanung mit Zoho CRM und Google Maps API gestalten - SprintCX","isPartOf":{"@id":"https:\/\/wordpress.sprintcx.net\/de\/#website"},"primaryImageOfPage":{"@id":"https:\/\/wordpress.sprintcx.net\/de\/individuelle-tourenplanung-mit-zoho-crm-und-google-maps-api-gestalten\/#primaryimage"},"image":{"@id":"https:\/\/wordpress.sprintcx.net\/de\/individuelle-tourenplanung-mit-zoho-crm-und-google-maps-api-gestalten\/#primaryimage"},"thumbnailUrl":"https:\/\/wordpress.sprintcx.net\/wp-content\/uploads\/2025\/04\/1745944361-6810ff292048c.png","datePublished":"2025-04-29T12:25:48+00:00","dateModified":"2025-04-29T16:35:50+00:00","breadcrumb":{"@id":"https:\/\/wordpress.sprintcx.net\/de\/individuelle-tourenplanung-mit-zoho-crm-und-google-maps-api-gestalten\/#breadcrumb"},"inLanguage":"de","potentialAction":[{"@type":"ReadAction","target":["https:\/\/wordpress.sprintcx.net\/de\/individuelle-tourenplanung-mit-zoho-crm-und-google-maps-api-gestalten\/"]}]},{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/wordpress.sprintcx.net\/de\/individuelle-tourenplanung-mit-zoho-crm-und-google-maps-api-gestalten\/#primaryimage","url":"https:\/\/wordpress.sprintcx.net\/wp-content\/uploads\/2025\/04\/1745944361-6810ff292048c.png","contentUrl":"https:\/\/wordpress.sprintcx.net\/wp-content\/uploads\/2025\/04\/1745944361-6810ff292048c.png","width":1408,"height":768},{"@type":"BreadcrumbList","@id":"https:\/\/wordpress.sprintcx.net\/de\/individuelle-tourenplanung-mit-zoho-crm-und-google-maps-api-gestalten\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/wordpress.sprintcx.net\/de\/"},{"@type":"ListItem","position":2,"name":"Individuelle Tourenplanung mit Zoho CRM und Google Maps API gestalten"}]},{"@type":"WebSite","@id":"https:\/\/wordpress.sprintcx.net\/de\/#website","url":"https:\/\/wordpress.sprintcx.net\/de\/","name":"SprintCX","description":"","publisher":{"@id":"https:\/\/wordpress.sprintcx.net\/de\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/wordpress.sprintcx.net\/de\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"de"},{"@type":"Organization","@id":"https:\/\/wordpress.sprintcx.net\/de\/#organization","name":"SprintCX","url":"https:\/\/wordpress.sprintcx.net\/de\/","logo":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/wordpress.sprintcx.net\/de\/#\/schema\/logo\/image\/","url":"https:\/\/wordpress.sprintcx.net\/wp-content\/uploads\/2025\/05\/cropped-ChatGPT-Image-6.-Mai-2025-09_53_42.png","contentUrl":"https:\/\/wordpress.sprintcx.net\/wp-content\/uploads\/2025\/05\/cropped-ChatGPT-Image-6.-Mai-2025-09_53_42.png","width":846,"height":828,"caption":"SprintCX"},"image":{"@id":"https:\/\/wordpress.sprintcx.net\/de\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.linkedin.com\/in\/gregor-sprint\/"]},{"@type":"Person","@id":"https:\/\/wordpress.sprintcx.net\/de\/#\/schema\/person\/33a4ba085d0b86874d45522b74c193eb","name":"Gregor","image":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/secure.gravatar.com\/avatar\/890daf3cadca0407ae6752f5d3c0f4a1bbb2ce129b70d5e65fbefcc86deba987?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/890daf3cadca0407ae6752f5d3c0f4a1bbb2ce129b70d5e65fbefcc86deba987?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/890daf3cadca0407ae6752f5d3c0f4a1bbb2ce129b70d5e65fbefcc86deba987?s=96&d=mm&r=g","caption":"Gregor"},"sameAs":["https:\/\/sprintcx.net"],"url":"https:\/\/wordpress.sprintcx.net\/de\/author\/gregor\/"}]}},"_links":{"self":[{"href":"https:\/\/wordpress.sprintcx.net\/de\/wp-json\/wp\/v2\/posts\/1466","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.sprintcx.net\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wordpress.sprintcx.net\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.sprintcx.net\/de\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.sprintcx.net\/de\/wp-json\/wp\/v2\/comments?post=1466"}],"version-history":[{"count":3,"href":"https:\/\/wordpress.sprintcx.net\/de\/wp-json\/wp\/v2\/posts\/1466\/revisions"}],"predecessor-version":[{"id":1485,"href":"https:\/\/wordpress.sprintcx.net\/de\/wp-json\/wp\/v2\/posts\/1466\/revisions\/1485"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.sprintcx.net\/de\/wp-json\/wp\/v2\/media\/1482"}],"wp:attachment":[{"href":"https:\/\/wordpress.sprintcx.net\/de\/wp-json\/wp\/v2\/media?parent=1466"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.sprintcx.net\/de\/wp-json\/wp\/v2\/categories?post=1466"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.sprintcx.net\/de\/wp-json\/wp\/v2\/tags?post=1466"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}