HCL Connections: Prüfen wer Touchpoint (nicht) abgeschlossen hat

HCL Connections: Prüfen wer Touchpoint (nicht) abgeschlossen hat

Mit HCL Connections 6.5 wird Touchpoint automatisch installiert. Hierbei handelt es sich um einen sogenannten Onboarding-Assistenten: Er soll auf der einen Seite neue Anwender an die Hand nehmen, ihnen beim ausfüllen des Profiles, finden von Communitys, anderen Personen etc. helfen. Darüber hinaus kann auch eine Datenschutzerklärung inklusive Version eingebunden werden. Der Nutzer muss diese akzeptieren, was wiederum systemseitig gespeichert wird. Touchpoint gab es zuvor schon. Allerdings musste die Anwendung händisch installiert werden.

Bisher geschah die Einbindung über ein JavaScript-Schnipsel in der header.jsp bzw. footer.jsp recht transparent. Mit 6.5 wanderte dies ins Backend und es gibt offiziell auch keine Einstellungsmöglichkeiten für z.B. den Intervall mehr. Erschwerend hinzu kommt, dass der Touchpoint nach Aktivierung aufgrund verschiedener Caches gar nicht oder erst später erscheint.

Wo speichert Touchpoint seine Daten?

Es ist daher nur sinnvoll nachzuschauen, ob und wer überhaupt den Touchpoint abgeschlossen hat. Leider gibt es hierzu keinerlei Oberfläche oder Dokumentation. Alles Folgende basiert daher auf eigener Arbeit, Recherche sowie Reverse Engineering.

Zunächst muss man wissen, dass Touchpoint zwei benutzerdefinierte Profilfelder anlegt. Alle Daten befinden sich somit in der Tabelle EMPINST.PROFILE_EXTENSIONS. Gefiltert werden muss nach den im folgenden erläuterten Schlüsseln.

Die Touchpoint Sitzung

touchpointSession wird beim ersten Aufruf des Touchpoints angelegt. Das System speichert darin ein riesiges JSON-Dokument von ca. 10KB größe. Darin sind zahlreiche Informationen über das Profil des Nutzers, seine Communitys in denen er Mitglied ist und vieles mehr enthalten. Darüber hinaus auch eigene Daten von Touchpoint, wie etwa den zuletzt geöffneten Schritt. Schließt ein Nutzer den Touchpoint in Schritt 2, wird er beim nächsten Aufrufen wieder dort landen – statt ihn erneut durchklicken zu müssen. Das gespeicherte JSON-Dokument lässt sich auch über die Profile-API aufrufen:

https://cnx.host/profiles/atom/profileExtension.do?key=51673ab8-4e38-46ca-83ca-795796074813&extensionId=touchpointSession

Direkt aus der Datenbank erhalten wir es mit folgender Abfrage (DB2):

SELECT PROF_KEY, CAST(PROF_VALUE_EXTENDED as VARCHAR(32672) CCSID UNICODE) as JSON_VALUE
FROM EMPINST.PROFILE_EXTENSIONS 
WHERE PROF_PROPERTY_ID = 'touchpointSession'

Wenn wir hier leere Felder erhalten wie in der ersten Zeile, ist vermutlich ein Fehler in der Standardkonfiguration schuld. Die Datei tdisol/conf/LotusConnections-config/profiles-types.xml enthält die beiden Touchpoint-Attribute:

<property>
        <ref>privacyAndGuidelines</ref>
        <updatability>readwrite</updatability>
        <hidden>true</hidden>
        <fullTextIndexed>false</fullTextIndexed>
</property>
<property>
        <ref>touchpointState</ref>
        <updatability>readwrite</updatability>
        <hidden>true</hidden>
        <fullTextIndexed>false</fullTextIndexed>
</property>
<property>
        <ref>touchpointSession</ref>
        <updatability>readwrite</updatability>
        <hidden>true</hidden>
        <fullTextIndexed>false</fullTextIndexed>
</property>

Sofern es diese Felder nicht im LDAP gibt und sie dort nicht primär gespeichert werden (worin ich wenig Sinn sehe), müssen sie auskommentiert werden. Ansonsten synchronisiert der TDI sie bei jedem Durchlauf. Gibt es die Felder nicht im LDAP, werden sie überschrieben, auch wenn sich bereits Daten in der Datenbank befanden.

Die akzeptierte Datenschutzerklärung und ggf. die Nutzungsbedingungen

Der Touchpoint kann auch genutzt werden, um die eigene Datenschutzerklärung sowie die Nutzungsbedingungen vom Benutzer bestätigen zu lassen. Hierzu muss man in der Konfiguration nur privacyAndGuidelines.enabled auf true setzen und in den Link-Attributen jeweils eine Link für externe und interne Nutzer hinterlegen. Auf der ersten Seite wird den Nutzern dann eine Checkbox mit den hinterlegten Links angezeigt, die er anhaken muss.

Sinnvolerweise lässt sich die Datenschutzerklärung versionieren und Touchpoint speichert, welcher Benutzer welche Version akzeptiert hat. Somit ist dies zum einen nachvollziehbar. Zum anderen lassen sich die Anwender bei geänderten Nutzungsbedingungen dazu auffordern, diese erneut zu akzeptieren. In diesem Falle erhöht man beispielsweise die Version von 1.0 (Standard) auf 1.1. Über den Schlüssel privacyAndGuidelines können wir aus der gleichen Tabelle auslesen, welche Version akzeptiert wurde:

SELECT PROF_KEY, PROF_VALUE 
FROM EMPINST.PROFILE_EXTENSIONS privacyExt
WHERE privacyExt.PROF_PROPERTY_ID = 'privacyAndGuidelines'

Welcher Benutzer hat den Touchpoint erhalten und abgeschlossen?

Mit dem obigen Wissen kann man händisch ermitteln, ob ein Benutzer den Touchpoint abgeschlossen hat und wenn ja mit welcher Version der Datenschutzerklärung. Für die anfangs angesprochene Übersicht ist dies allerdings wenig hilfreich: Schließlich müsste man manuell die User-Id heraussuchen und in die Abfrage einfügen – für jeden User. Eine Abfrage aller Daten ist ohne sprechende Benutzer wenig hilfreich. Daher habe ich eine Abfrage erstellt, mit der man alle in meinen Augen wichtigen Informationen erhält:

SELECT e.PROF_DISPLAY_NAME, JSON_VAL(SYSTOOLS.JSON2BSON(PROF_VALUE), 'timestamp' , 'l') AS timestampRaw,
DATE((((JSON_VAL(SYSTOOLS.JSON2BSON(PROF_VALUE), 'timestamp' , 'l') / 1000)-5*3600)/86400)+719163) AS calculatedDate,
(
	SELECT privacyExt.PROF_VALUE 
	FROM EMPINST.PROFILE_EXTENSIONS privacyExt
	WHERE ext.PROF_KEY = privacyExt.PROF_KEY 
	AND privacyExt.PROF_PROPERTY_ID = 'privacyAndGuidelines'
) AS privacyVersion
FROM EMPINST.PROFILE_EXTENSIONS ext
LEFT JOIN EMPINST.EMPLOYEE e ON (e.PROF_KEY = ext.PROF_KEY)
WHERE PROF_PROPERTY_ID = 'touchpointState'
ORDER BY JSON_VAL(SYSTOOLS.JSON2BSON(PROF_VALUE), 'timestamp' , 'l') DESC

Als Ergebnis erhalten wir eine Tabelle mit Anzeigename, Unix-Timestamp, lesbarem Datum und Version der akzeptierten Datenschutzerklärung – sortiert nach Abschlussdatum:

Alte Abfrage

Meine erste Abfrage war weniger elegant, da ich Probleme mit den JSON-Funktionen hatte. Mittlerweile funktioniert dies und ich habe die obige Anfrage angepasst. Zu Archivzwecken hier noch die alte Abfrage, die alles außer dem Zeitstempel mit der String-Funktion REPLACE entfernt:

SELECT e.PROF_DISPLAY_NAME, REPLACE(REPLACE(ext.PROF_VALUE, '}', ''), '{"state":"complete","timestamp":', '') AS timestampRaw,
DATE((((REPLACE(REPLACE(ext.PROF_VALUE, '}', ''), '{"state":"complete","timestamp":', '') / 1000)-5*3600)/86400)+719163) AS calculatedDate,
(
	SELECT privacyExt.PROF_VALUE 
	FROM EMPINST.PROFILE_EXTENSIONS privacyExt
	WHERE ext.PROF_KEY = privacyExt.PROF_KEY 
	AND privacyExt.PROF_PROPERTY_ID = 'privacyAndGuidelines'
) AS privacyVersion
FROM EMPINST.PROFILE_EXTENSIONS ext
LEFT JOIN EMPINST.EMPLOYEE e ON (e.PROF_KEY = ext.PROF_KEY)
WHERE PROF_PROPERTY_ID = 'touchpointState'
ORDER BY REPLACE(REPLACE(ext.PROF_VALUE, '}', ''), '{"state":"complete","timestamp":', '') DESC

Zugegeben, technisch ist die Abfrage nicht sauber und durch das ganze Gebastel auch nicht wirklich performant für große Datenmengen geeignet. Dies liegt primär daran, dass der Touchpoint die generische Attribute-Tabelle nutzt und hier ein JSON-Objekt serialisiert gespeichert wird. Ich hatte kurz mal mit SYSTOOLS.JSON_VAL experimentiert – DB2 scheint grundsätzlich tatsächlich in der Lage zu sein, mit JSON-Dokumenten in Tabellenfeldern zu arbeiten. Jedoch kam ich bisher damit zu keinem zufriedenstellenden Ergebnis.

Leave a Reply