Teams Presence und Office IM API

"Wie kann ich den Präsenzstatus in Teams abfragen". Diese Frage habe ich mir schon häufiger gestellt. In Skype for Business konnte ich eine COM-API nutzen aber in Teams gibt es das so erst mal nicht. Bis Presence über die Graph API nutzbar wird, können Sie alternative Wege suchen.

Teams does not use COM at all and never will. We plan to support presence APIs in Microsoft Graph bit do not have a date to share
Quelle: https://stackoverflow.com/questions/56865704/com-object-for-teams-client-microsoft-office-uc

Office API

Wer sich den Teams Client  for Windows anschaut, findet in den Einstellungen die folgende Option:

Damit schalten sie in Outlook aber auch Word, Excel und Co die Schnittstelle von Lync/Skype auf Teams um und in Outlook wird die Präsenzanzeige mit Teams verbunden. Ich sehen also die Präsenz des Teams-Teilnehmers im gleichen Tenant aber auch per Federation und kann über den Weg auch einen "Chat" oder einen VoIP-Anruf starten.

Was da im Hintergrund passiert, beschreibt Microsoft eigentlich ganz schön auf seiner Webseite

To enable this integration with Office, an IM client application must implement a set of interfaces that Office provides to connect to it. The APIs for this integration are included in the UCCollborationLib namespace that is contained in the Microsoft.Office.UC.dll file, which is installed with versions of Office 2013 that include Lync / Skype for Business. The UCCollaborationLib namespace includes the interfaces that you must implement to integrate with Office.
Quelle: Integrating IM applications with Office https://docs.microsoft.com/en-us/office/client-developer/shared/integrating-im-applications-with-office

Weiter im Dokument steht genau, wie sich Office dann an die Applikation anbindet.

  1. Lesen der Default IM App aus "HKEY_CURRENT_USER\Software\IM Providers\DefaultIMApp"
  2. Prüfen, ob die App läuft "HKEY_CURRENT_USER\Software\IM Providers\%AppName%\UpAndRunning=2"
  3. Ermittel des ProzessID aus "Computer\HKEY_CURRENT_USER\Software\IM Providers\Teams\ProcessId"
  4. Anbinden als "Out of Band COM-Process" über "CoCreateInstance"

So sieht ein Auszug aus meiner Registrierung aus:

Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\Software\IM Providers]
"DefaultIMApp"="Teams"

[HKEY_CURRENT_USER\Software\IM Providers\Communicator]
"UpAndRunning"=dword:00000002
"ProcessId"=dword:00002bd8

[HKEY_CURRENT_USER\Software\IM Providers\EasyLy]
@=""
"IsFirstRun"=dword:00000000

[HKEY_CURRENT_USER\Software\IM Providers\Lync]
"ProcessId"=dword:00002bd8
"UpAndRunning"=dword:00000002

[HKEY_CURRENT_USER\Software\IM Providers\Teams]
"PreviousDefaultIMApp"="Lync"
"ProcessId"=dword:0000384c
"UpAndRunning"=dword:00000002

An dem Zeitpunkt war "Teams" die "DefaultIMApp" und die Zeile ""UpAndRunning"=dword:00000002" zeigt an, dass Teams mit der ""ProcessId"=dword:0000384c" gelaufen ist. Die Information kann natürlich einfach auch per PowerShell abgefragt werden

Get-ChildItem "HKCU:Software\IM Providers\"
Get-Item "HKCU:Software\IM Providers\Teams\"

Per Powershell ist dann auch der Prozess dazu schnell gefunden:

get-process -Id 14412 | fl *

Name                       : Teams
Id                         : 14412
PriorityClass              : Normal
FileVersion                : 1.2.00.10954
HandleCount                : 1970
WorkingSet                 : 109744128
PagedMemorySize            : 116072448
PrivateMemorySize          : 116072448
VirtualMemorySize          : 1220177920
TotalProcessorTime         : 00:09:28.3281250
SI                         : 1
Handles                    : 1970
VM                         : 2204538400768
WS                         : 109744128
PM                         : 116072448
NPM                        : 86096
Path                       : C:\Users\fcarius\AppData\Local\Microsoft\Teams\current\Teams.exe
Company                    : Microsoft Corporation
CPU                        : 568,328125
ProductVersion             : 1.2.00.10954
Description                : Microsoft Teams
Product                    : Microsoft Teams
__NounName                 : Process
BasePriority               : 8
ExitCode                   :
HasExited                  : False
ExitTime                   :
Handle                     : 4280
SafeHandle                 : Microsoft.Win32.SafeHandles.SafeProcessHandle
MachineName                : .
MainWindowHandle           : 41029646
MainWindowTitle            : UCLabor | Microsoft Teams
MainModule                 : System.Diagnostics.ProcessModule (Teams.exe)
MaxWorkingSet              : 1413120
MinWorkingSet              : 204800
Modules                    : {System.Diagnostics.ProcessModule (Teams.exe), System.Diagnostics.ProcessModule
                             (ntdll.dll), System.Diagnostics.ProcessModule (KERNEL32.DLL),
                             System.Diagnostics.ProcessModule (KERNELBASE.dll)...}
NonpagedSystemMemorySize   : 86096
NonpagedSystemMemorySize64 : 86096
PagedMemorySize64          : 116072448
PagedSystemMemorySize      : 957848
PagedSystemMemorySize64    : 957848
PeakPagedMemorySize        : 132956160
PeakPagedMemorySize64      : 132956160
PeakWorkingSet             : 178851840
PeakWorkingSet64           : 178851840
PeakVirtualMemorySize      : 1279320064
PeakVirtualMemorySize64    : 2204597542912
PriorityBoostEnabled       : True
PrivateMemorySize64        : 116072448
PrivilegedProcessorTime    : 00:03:50.9531250
ProcessName                : Teams
ProcessorAffinity          : 255
Responding                 : True
SessionId                  : 1
StartInfo                  : System.Diagnostics.ProcessStartInfo
StartTime                  : 15.05.2019 23:17:00
SynchronizingObject        :
Threads                    : {3328, 16276, 29388, 22428...}
UserProcessorTime          : 00:05:37.3750000
VirtualMemorySize64        : 2204538400768
EnableRaisingEvents        : False
StandardInput              :
StandardOutput             :
StandardError              :
WorkingSet64               : 109744128
Site                       :
Container                  :

Damit bleibt aber immer noch die Frage, wie man an ein passenden COM-Objekt kommt

Aus dem PowerShell-Magazin habe ich dann einen Code-Schnipsel angepasst, um nach COM-Objekten zu suchen:

Get-ChildItem HKLM:\Software\Classes -ErrorAction SilentlyContinue `
| Where-Object { $_.PSChildName -like '*teams*' -and (Test-Path -Path "$($_.PSPath)\CLSID") } `
| Select-Object -ExpandProperty PSChildName
Get-ChildItem HKLM:\Software\Classes -ErrorAction SilentlyContinue `
| Where-Object { $_.PSChildName -like '*teams*' } `
| Select-Object -ExpandProperty PSChildName

Aber Treffer habe ich bei mir keine gehabt. Anscheinend ist das eine COM-Schnittstelle, die so nicht auffindbar ist. Nun will ich natürlich keine eigene API bereitstellen, um in Office eine Präsenz-Anzeige bereit zu stellen. Das wäre dann eher etwas für Unify, Avaya, Estos u.a. Aber wenn Office (Outlook, Word, Excel) diese API nutzen um in ihren Applikationen eine Präsenzanzeige und vielleicht mehr anzuzeigen, dann ist das auch für mich interessant. Es wäre ja eine Client-API, mit der ich per Skript z.B. den eigenen Präsenzstatus oder auch den Status anderer Teilnehmer abfragen könnte.

Microsoft.OfficeUC.dll

In dem Zuge ist auch die DLL "Microsoft.OfficeUC.dll" in meinen Fokus gerückt. Leider konnte ich mittels "Depends.exe" nicht ermitteln, welche Funktionen und Klassen Sie bereit stellt. Allerdings gibt es eine Dokumentation, die auf einige Bestandteile referenziert. Allein auf meinem PC gibt es auch jede Menge Versionen davon, da viele Programme diese DLL einfach mitbringen

Der Versuch diese DLL einfach mal in VBA als Verweis zu addieren, ist aber auch schief gelaufen

Auch hier haben aber meine stümperhaften Versuche noch nicht zum Erfolg geführt.

Nutzung mit PowerShell

ich hoffe ja immer noch, dass ich eine API für die Abfrage eines Teams Presence finde, mit der ich dann ein "Teams Statusbild" in welcher Form auch immer bauen kann. Sei es als einfache Statusanzeigen per WLAN-LED (Siehe dazu z.B. Shelly Bulb auf Shelly IoT) pro Anwender oder ein LED-Band im Eingangsbereich oder ein LED-Weihnachtsbaum für eine Firma oder wegen mir auch ein ein Satz von per DMX gesteuerten Leuchten im Fenster jedes Mitarbeiters.

Der Weg über die COM-API von Teams zu gehen, die auch Office Applikationen nutzen, ist mir bislang nicht gelungen. Zukünftig wird sicher eine Abfrage über die Graph API der bessere Weg sein. Aber noch gibt es hier keine Roadmap für Präsenz. Und andere Wege wie z.B. MQTT sind noch viel weiter entfernt.

Browser-API

Dann ist mir z.B. in LinkedIn und Yammer aufgefallen, dass bei den Fotos von Personen, die auch in Teams bekannt sind, mit einem Status versehen werden. Ich kann in LinkedIn auch nach mir suchen und finde so einen Hinweis

Bei anderen Menschen habe ich andere Statusmeldungen gefunden

Nun erwarte ich nicht, dass LinkedIn, obwohl es zu Microsoft gehört, serverseitig den Status ermittelt sondern das mein Browser machen muss.

Ich habe noch nicht ermittelt, wie der Browser oder vielleicht doch das LinkedIn Backend den Status ermittelt.

Weitere Links