Skip to content

CMI Hubspot Schnittstelle

Die CMI Hubspot Schnittstelle ist ein .NET 8.0 Service, der in regelmässigen Abständen mit Hilfe von GraphQL Kontaktdaten aus der KV, und mit Hilfe der HubSpot Rest API Kontaktdaten von Hubspot lädt, vergleicht und synchronisiert.

Die bidirektionale Schnittstelle nutzt für die Authentifizierung bei Hubspot einen API Key und bei der KV den STS "Impersonification" oder "Client Credentials Grant" Login. Alle dafür relevanten Daten können in der "appsettings.json" eingestellt werden.

Inhaltsverzeichnis

Allgemeines

  • Status: In Entwicklung
  • Fachliche Ansprechperson: Sabine Walther, Patrick Siegenthaler
  • Technische Ansprechperson: Luca Güttinger
  • Nur für speziellen Kunde: ja, nur Intern

Aufgabe

Die Aufgabe der Schnittstelle ist es, Kontakte zwischen HubSpot und KV zu synchronisieren. In der KV werden Kontakte, MarketingFlags, HubSpotAbos und Adressen erstellt. Die Schnittstelle kann komplett unabhängig von der KV und Hubspot betrieben werden, sie muss aber die Möglichkeit haben, die nötigen Endpunkte zu erreichen (siehe Abschnitt Endpunkte).

Strategische_Einordnung

Entwicklung ausschliesslich für interne Zwecke. Soll nicht für Kunden bereitgestellt werden.

Technisches

Eigenschaften

Die Komponente erfüllt folgende Eigenschaften:

  • Stateless: nein (nicht notwendig)
  • Skalierbar/Multiinstanzfähig: nein (nicht notwendig)
  • Mehrmandantenfähig: nein (nicht notwendig)
  • Laufzeitverhalten: durchgängig laufender Service

Es kann in der appsettings.json eingestellt werden in welchem Intervall die Applikation die Daten synchronisiert. Die Applikation wird beim Starten direkt einmal versuchen zu synchronisieren.

Services

Folgende Services verwendet die Komponente:

Service Version Anbindung Protokoll Standardports Verfügbarkeit Fehlertoleranzklasse
HubSpot REST API ??? on request http/s 80/443 muss Fehlermeldung
CMI Server WebApi >= V20.0 on request http/s 10003,10004 muss Fehlermeldung
CMI STS 2/3 on request http/s 443 muss Fehlermeldung

Fehlertoleranz

Die Schnittstelle läuft unabhängig vom CMI Server Service und der HubSpot REST API. Falls etwas nicht erreichbar ist, wird die Applikation Fehler ausgeben, aber sie wird weiterlaufen.

Endpunkte

Die Hubspot Schnittstelle spricht folgende Endpunkte an:

KV

POST - {sts url}/identity/connect/token

POST - {server service base url}/api/core/Save/InsertOrUpdate

POST - {server service base url}/api/core/GraphQl/Execute

HubSpot

GET - {Hubspot base URL}/crm/v3/objects/contacts

GET - {Hubspot base URL}/email/public/v1/subscriptions/timeline

GET - {Hubspot base URL}/email/public/v1/subscriptions

GET - {Hubspot base URL}/owners/v2/owners/

POST -{Hubspot base URL}/contacts/v1/contact/batch/

PUT - {Hubspot base URL}/email/public/v1/subscriptions/{mail}

DELETE - {Hubspot base URL}/crm/v3/objects/contacts/{id}

Module

Die HubSpot Schnittstelle verfügt über ein Modul System, dass es erlaubt, dass das Synchronisieren von Daten komplett unabhängig von der eigentlichen Schnittstelle passiert, das ist der Grund, warum die Applikation bei einem Fehler nicht abstürzt.

Technologiestack

Folgende Technologien werden eingesetzt: * ASP.NET 8.0 * GraphQL

Installation

Systemvoraussetzungen

Folgende Komponenten müssen auf dem System installiert/vorhanden sein: * ASP.NET 8.0 Runtime

ServerService

Im Server Service müssen zwei dinge eingestellt sein:

  1. Im Metatool.ini File muss folgendes eingestellt sein, damit die Schnittstelle speichern kann:
[MobileFirst]
RunModes=Save

KPF

  1. Es muss ein KPF bei dem Server eingespielt sein, das sehr ähnlich ist wie das, dass in der KV hinterlegt ist, es muss nicht genau das sein, aber die TypeDefinitions "CustomMarketingFlag" und "CustomHubSpotAbo" müssen genau gleich existieren mit denselben Feldern wie in der KV.
    Das KPF der KV kann mithilfe eines Statusreports in der KV geholt werden. (Menü -> Hilfe -> Statusreport Anlegen; Menü -> Hilfe -Statusreporte Anzeigen)

HubSpot Umgebung einrichten

Man benötigt einen HubSpot Account. Mit diesem Account kann man dann ein test Account machen: https://legacydocs.hubspot.com/docs/faq/how-do-i-create-a-test-account

Wenn man einen Solchen Test Account erstellt hat sollte die Website ungefähr so aussehen: https://puu.sh/GcUAO/3a4578ca78.png

Danach klickt man auf das Zahnrad oben rechts, dort auf Properties und dann schauen ob alle eigenschaften die in der contactsync.json Datei hinterlegt sind Existieren, das Property Guid muss man mit sicherheit neu erstellen.

Danach geht man in der Seite auf "Marketing -> Email -> Subscription Types" hier kann man beispiel Marketing Flags erstellen. Wenn diese erstellt sind muss man sie auch in der KV hinterlegen. MarketingFlags sind einfache Stammdaten die man wie normale Stammdaten erstellen kann. Die Subscription ID muss man via Request an Hubspot hohlen. https://api.hubapi.com/email/public/v1/subscriptions?hapikey=

HubSpot

Die Schnittstelle muss als Windows Service installiert werden:

sc.exe create <name> binPath= "<path to .exe file>"

Build

Es ist ein Build Prozess eingerichtet, der sehr ähnlich ist wie der Standard Build Prozess für andere Web Services. Es werden automatisch Builds erstellt, wenn in den Master gemerged wird(Release), wenn in den develop gemerged wird (CI) und wenn pull Requests in den develop erstellt werden(CI). Der Build Prozess ist gleich wie im Metatool, siehe hier im Wiki.

Die Builds sind im Verzeichnis B:\05_Versionen_Komponenten\hubspot-cmi abgelegt.

Konfigurationsmöglichkeiten

Achtung: Breaking-Changes zwischen Version 1 und 2 bei der Konfiguration. Siehe Migrationspfad weiter unten.

appsettings.json

Das Log Level sollte, nur wenn notwendig auf Debug gestellt werden, da bei dem Log Level Debug viele Personenbezogenen Daten geloggt werden.

Für ein lokales System sieht die appsettings.json so aus:

{
  "HubSpotService": {
    "Modules": {
      "ContactSync": {
        "Interval": 1,
        "TimeUnit": "Minute",
        "Save": true
      }
    },
    "HubSpot": {
      "BaseUrl": "https://api.hubapi.com/",
      "ApiKey": "3efaed22-f234-428a-b4f8-66655a5d03cf"
    },
    "ServerService": {
      "PrivateUrl": "http://localhost:10003/",
      "User": "ads",
      "Password": "123"
    },
    "Sts": {
      "Enabled": true,
      "Authority": "http://sts.cmiaxioma.local/",
      "Client_Secret": "tlustme",
      "Client_id": "hubspot",
      "Acr_Values": "cmi_ag_lgu_local"
    }
  },
  "Serilog": {
    "MinimumLevel": {
      "Default": "Debug",
      "Override": {
        "Microsoft": "Warning",
        "System": "Warning"
      }
    },
    "WriteTo": [
      {
        "Name": "RollingFile",
        "Args": {
          "restrictedToMinimumLevel":"Information",
          "pathFormat": "C:\\temp\\logs\\hubspot-service-info-{Date}.txt"
        }
      }
    ]
  },
  "AllowedHosts": "*"
}

Der Bereich "WriteTo" und der Bereich "Serilog" sind die standard Serilog Konfigurationen. Für Weitere Informationen bezüglich Serilog siehe: https://github.com/serilog/serilog-settings-configuration

Config Key Bedeutung
Modules Alle im Programm registrierten Module. Alle Module haben werte die gesetzt werden müssen
Interval Die zu wartende Zeit zwischen jedem Interval.
TimeUnit die TimeUnit in der der Intervall angegeben ist. "Day", "Hour", "Minute", "Second", "Millisecond"
Save Wenn dieser Wert auf true ist, speichert die Applikation Änderungen, wenn nicht wird sie in einem Ordner namens "Save" gespeichert mit folgender Syntax:< obj guid>: < mail> -> < field name> : < field value > - < obj version>
HubSpot Alle Konfigurationen die etwas mit HubSpot zu tun haben
BaseUrl Die URL für die Rest calls in die Hupbspot API
ApiKey Der Hubspot Api Key, mehr informationen hier: https://knowledge.hubspot.com/integrations/how-do-i-get-my-hubspot-api-key
ServerService Alle Konfigurationen die etwas mit dem Server Service zu tun haben.
PrivateUrl Die URL für den Server Service und der private Port
User username eines Benutzers mit den Benötigten berechtigungen. Der Benutzer braucht folgende rechte: "Basis", "HubSpot Abos lesen" (KPF), "HubSpot Abos verwalten" (KPF), "Kontakt verwalten", "Stammdaten und deren Erben verwalten"
Password* Das Password für den oben angegeben Benutzer, dieses Feld ist nur dann notwendig, wenn die Applikation ohne STS laufen soll.
STS Standart STS einstellungen.
Enabled Aktiviert die STS Authentifizierung. Ansonsten wird eine BuiltIn Authentifizierung am CMI Server durchgeführt.
Authority Die Url unter der der STS erreichbar ist. Tokens.
Client_Secret Das Secret das in der Config des STS angegeben ist.
Acr_Values CMI STS 2: Die ID des API Servers, ebenfalls in Config des STS zu finden.
Client_Id CMI STS 3: Optional, Standardwert is hubspot. Client ID mit der das Token beim STS abgefragt wird.

'*' nicht obligatorische Felder

contactsync.json

Die ContactSync Config wird dafür benötigt, die internen Namen in der Schnittstelle auf die Felder in den jeweiligen Systemen zu Mappen. So kann man umstellen, dass die Schnittstelle andere Felder vergleicht.

Die Config besteht aus zwei Objekten, einmal das Objekt "Cmi" und einmal das Objekt "HubSpot". Die Keys müssen immer gleich bleiben, Falls Felder umbenannt werden können sie hier angepasst werden. Es ist zu beachten, dass das Daten laden vom Axioma aktuell mit einer fest im Code integrierten ist und deswegen diese Werte anzupassen riskant ist. Im Hubspot Bereich ist es möglich die Values anzupassen.

Die Standardkonfiguration dieser Datei für die Testumgebung ist so:

{  
  "Cmi": {  
    "Guid": "Guid",  
    "Email": "Email",  
    "Vorname": "Vorname",  
    "Nachname": "Name",  
    "Organisation": "Organisation",  
    "Anrede": "Anrede",  
    "Funktion": "Funktion",  
    "Adresse.Adresszeile": "Strasse",  
    "Adresse.Plz": "Plz",  
    "Adresse.Land": "Land",  
    "Adresse.Ort": "Ort",  
    "Tel": "TelefonGeschaeft",  
    "HubSpotScore": "CustomHubSpotScore",  
    "OptOut": "CustomHubSpotOptout",  
    "OptOutAm": "CustomHubSpotOptOutAm",  
    "subscription.optOut": "CustomOptOut",  
    "subscription.optOutAm": "CustomOptOutAm",  
    "subscription.id": "",
    "subscription.optouths": ""
  },  
  "HubSpot": {  
    "Guid": "guid",  
    "Email": "email",  
    "Vorname": "firstname",  
    "Nachname": "lastname",  
    "Organisation": "company",  
    "Anrede": "salutation",  
    "Funktion": "job_function",  
    "Adresse.Adresszeile": "address",  
    "Adresse.Plz": "zip",  
    "Adresse.Land": "country",  
    "Adresse.Ort": "city",  
    "Tel": "phone",  
    "HubSpotScore": "hubspotscore",
    "subscription.optouths": "",
    "OptOut": ""
  }  
}

Troubleshooting

Could not obtain STS-Token "error":"invalid_grant","error_description":

Mögliche Fehler: - STS kann den Server Service nicht erreichen - Anmeldedaten Falsch

Migrationspfad von Version 1 zu Version 2

In der Konfiguration in der Sektion Sts die Eigenschaftennamen anpassen:

** Version 1 **

    "Sts": {
      "Enabled": true,
      "StsTokenEndpoint": "http://sts.cmiaxioma.local/",
      "Secret": "tlustme",
      "ApiServerId": "cmi_ag_lgu_local"
    }

** Version 2 **

    "Sts": {
      "Enabled": true,
      "Authority": "http://sts.cmiaxioma.local/",
      "Client_Secret": "tlustme",
      "Acr_Values": "cmi_ag_lgu_local"
    }

Changelog

v.4.0

  • Framework Update von .Net 6 auf .Net 8