Call Park mit Teams
Microsoft erweiterte die Teams Telefonie-Funktionen nach und nach um weitere Funktionen Bis Anfang 2019 sollten dann auch alle Tenants die Funktion Call Park erhalten haben, die ich hier näher beschreibe.
Warum Parken?
Das Parken von Anrufen ist eine Abwandlung einer Weiterleitung oder Rückfrage. Bei einer klassischen Vermittlung kennt der angerufene Teilnehmer das nächste Ziel und kann den Anrufer schnell vermitteln. Manchmal muss der Anrufer auch etwas warten, weil der angerufene Teilnehmer erst eine Rückfrage durchführt, d.h. das Ziel des zweiten Anrufs erst kurz die Vorgeschichte des Anrufer übermittellt oder gleich die Antwort erhält, die Rückfrage selbst beendet und weiter mit dem Anrufer spricht.
Beim Parken hingegen geht es darum, den Anrufer erst mal auf die "Seite" zu legen und den Zielteilnehmer ausfindig zu machen. Der Anrufer landet also auf einem "Part-Orbit" und der Parkende bekommt passend dazu eine Platznummer. Mit der Nummer kann nun jeder auf seinem Teams Client wieder die Verbindung heranholen.
Es in etwa wie die Abgabe ihres Mantels an der Garderobe, von der Sie dann einen Nummer bekommen. Diese Nummer ist zugleich die Berechtigung den Mantel wieder abzuholen.
Das klassische Beispiel dabei sind Orte mit einer Sprechanlage und Anwendern, die gar kein persönliches Telefon haben, z.B. ein Supermarkt oder Lagerhalle. Die Telefonzentrale kann Anrufe annehmen, den Anrufer nach dem gewünschten Anliegen oder Partner fragen und dann Parken. Der ausgerufene Teilnehmer kann dann an jedes Endgerät gehen und durch Eingabe der Nummer den Anruf heranziehen und fortsetzen.
Der Orbit - und Call Park Policies
Wenn Sie an einer Garderobe ihren Mantel abgeben, wissen sie natürlich, für welche Garderobe der Zettel gilt. Wenn eine Firma sehr groß ist und viele Anrufe zu bedienen sind, kann dürfen aber die Nummern nicht ausgehen. Auch muss sichergestellt sein, dass die Garderobenummern natürlich nur für ihren Tenant gelten. Selbst innerhalb eines Tenant wäre es unschön, wenn z.B. jemand die Nummer erfährt, der gar nicht die Anrufen annehmen darf.
Daher hat Microsoft das Problem so gelöst, dass über die "Call Park Policy" bestimmt wird, welche Benutzer einen Anruf annehmen können. Für jede Call Park Policy gibt es einen eigenen Orbit. Eine Nummer kann pro Orbit nur einmal vergeben werden aber jeder Orbit ist eigenständig. Insofern können mehrere Anrufe mit der gleichen Nummer geparkt sein.
Da jeder Anwender immer nur genau eine Call Park Policy haben kann, können sie diese Kreise auch nicht überlappend einrichten. Es gibt eine 1:! Zuordnung der Benutzer zu einer Call Park Policy und damit auch zu ihrem Orbit und von wem sie geparkte Anrufe übernehmen können. Sie müssen also schon genau schaue, wann und für wen ein Parken sinnvoll ist und wann vielleicht besser eine Call Queue solche Anrufe annehmen sollte.
Zusammenhänge
Allerdings gibt es dabei einige Dinge zu beachten. Die wesentlichen Aspekte dabei sind:
- Nur Teams Clients mit Teams Online
Die Funktion "Parken" steht nur für Teams Clients und Teams-Telefonen zur Verfügung. Eine Nutzung für Skype for Business Online Benutzer ist nicht möglich. Damit die Anwender mit Teams "telefonieren" können, müssen Sie auch in der Betriebsart "TeamsOnly" sein, denn nur dann werden PSTN-Anrufe auch an Teams signalisiert. Die Nutzung des Island-Mode ist nicht möglich. - Direct Routung erfordert REFER
Das ist erst mal nichts neues, da Microsoft sowieso nur entsprechende Gateways und SBCs zertifiziert, die mit REFER umgehen können. Allerdings müssen Sie es nun auch korrekt konfigurieren. Es reicht nicht einfach das REFER-Verb einzuschalten sondern Sie müssen natürlich auch die Daten im "Contact"-Feld korrekt setzen und verarbeiten. REFER ist aber auch für viele andere Funktionen wie z.B. MoH erforderlich - Timeout für Parken: 300 Sek (nicht
änderbar, Stand Okt 2019)
Wenn ein Anwender einen Anrufer parkt und dieser nicht innerhalb von 5 Minuten wieder abgerufen wird, dann stellt Teams den Anruf wieder zum Teilnehmer durch, der das Parken veranlasst hat. Sollte der Teilnehmer nicht mehr erreichbar sein (Offline/Busy), dann verhält sich Teams wie bei einem Erstanruf und leitet den Anruf auf die Voicemail, Stellvertreter o.ä. weiter. Wenn nichts davon funktioniert, wird der Anruf beendet. - Nummern 10-99 (nicht änderbar, Stand Okt
2019)
Die standardmäßig vorhandene globale Richtline reserviert die Rufnummern 10-99 für den CallPark Orbit aber ist nicht aktiv. Anders als bei Skype for Business gibt es hier allerdings keinen Konflikt. Bei SfB mussten Sie sicherstelle, dass sich Nummern nicht mit echten Rufnummern und Normalisierungsregeln in Dialplänen überlappt haben. Bei Teams werden die geparkten Anrufe über ein anderes Menü quasi "angerufen". - maximale geparkte Anrufe
Über die für CallPark konfigurierten Rufnummern steuern sie auch, wie viele gleichzeitige Anrufe geparkt werden können, denn jeder Anruf beansprucht eine Rufnummer - Wartemusik
In der ersten Version wird die Wartemusik von Microsoft vorgegeben. Eigene Sound-Dateien dürften irgendwann auch kommen
Für eine Aktivierung von CallPark benötigen Sie eigentlich nur noch ein Konzept welche Benutzer Sie mit welcher Richtlinie zusammenfassen. Vergessen Sie dabei aber nicht die Mitarbeiter auch entsprechend zu informieren.
Gerade das Thema "User Adoption" und "Change Management" wird bei vielen Firmen leider zu nachlässig behandelt und darf gerade bei einer Einführung von Teams nicht vergessen werden.
Konfiguration per PowerShell
Ich gehe hier davon aus, dass insbesondere mit Direct Routing die Einrichtung ihres Session Border Controllers samt REFER schon korrekt umgesetzt worden ist. Die eigentliche Konfiguration kennen Sie von vielen anderen Teams Policies vermutlich auch schon. Es gibt kein Property "CallPark" beim Benutzer sondern die CallPark-Einstellungen werden in Richtlinien zusammengefasst und dann eine davon dem Benutzer zugewiesen. So können Sie durch Änderungen an der Richtlinie das verhalten alle Benutzer anpassen, denen diese Richtlinie zugewiesen wird.
Sie müssen Sie also erst einmal mit der Skype for Business Online PowerShell verbinden um die standardmäßig vorhandene globale "Default Policy" zu sehen
PS C:\>$sfboSession = New-CsOnlineSession PS C:\>Import-PSSession $sfboSession -allowclobber PS C:\>Get-CsTeamsCallParkPolicy Identity : Global Description : AllowCallPark : False # Anfordern aller Werte Get-CsTeamsCallParkPolicy | select * XsAnyElements : XsAnyAttributes : Description : AllowCallPark : False PickupRangeStart : 10 PickupRangeEnd : 99 ParkTimeoutSeconds : 300 DataSource : CMS Key : [{urn:schema:Microsoft.Rtc.Management.Policy.Teams.2017}TeamsCallParkPolicy,Tenant{xxxx},Global] ScopeClass : Global Anchor : Microsoft.Rtc.Management.ScopeFramework.GlobalScopeAnchor Identity : Global TypedIdentity : Global Element : <TeamsCallParkPolicy xmlns="urn:schema:Microsoft.Rtc.Management.Policy.Teams.2017" AllowCallPark="false" PickupRangeStart="10" PickupRangeEnd="99" ParkTimeoutSeconds="300" />
Diese Richtlinie wirkt auf alle Personen, die keine individuelle abweichende Richtlinie habe. Microsoft beschreibt in ihrer Dokumentation, wie diese diese globale Richtlinie ändern.
Set-CsTeamsCallParkPolicy `
-Identity Global `
-AllowCallPark $true
#Qelle https://docs.microsoft.com/powershell/module/skype/set-csteamscallparkpolicy?view=skype-ps
Damit aktivieren sie aber CallPark für alle Benutzer mit einem gemeinsamen Orbit. Das wäre eher für kleine Firmen passend. Für einen Pilot und vermutlich auch Produktion wird man eher eine eigene Richtlinie anlege, die entweder für CallPark für die Personen erlaubt, denen im zweiten Schritt die Richtlinie zugewiesen wird. Eventuell sollten Sie aber auch mehrere Policies mit unterschiedlichen Namen aber gleichen Einstellungen Orbits anlegen, um das Heranholen von geparkten Anrufen einzuschränken. Bei der Anlage können Sie aber erst einmal nur den Namen und eine Beschreibung angeben und CallPark vorgeben.
New-CsTeamsCallParkPolicy ` -Identity CallParkPB ` -Description "CallPark Paderborn" ` -AllowCallPark $true Identity : Tag:CallParkPB Description : CallPark Paderborn AllowCallPark : True
Weitergehende Einstellungen müssen Sie dann mittels "Set-CSTeamsCallParkPolicy anpassen. Allerdings gibt es aktuell auch nur die Parameter "Description" und "AllowCallPark".
Eine so angelegte Richtlinie muss dann den Benutzer zugewiesen werden, das geht per "Grant-CSTeamsCallParkPolicy".
Grant-CsTeamsCallParkPolicy ` -PolicyName callparkpb ` -Identity callparktestuser@uclabor.de
Mit wenig Aufwand können Sie so auch Gruppen von Benutzern konfigurieren.
- New-CsTeamsCallParkPolicy
https://docs.microsoft.com/powershell/module/skype/new-csteamscallparkpolicy?view=skype-ps - Set-CsTeamsCallParkPolicy
https://docs.microsoft.com/powershell/module/skype/set-csteamscallparkpolicy?view=skype-ps - Grant-CsTeamsCallParkPolicy
https://docs.microsoft.com/powershell/module/skype/grant-csteamscallparkpolicy?view=skype-ps
Konfiguration per Portal
Die Einstellungen lassen sich mittlerweile auch über die Webseite admin.teams.microsoft.com durchführen. Unter der URL https://admin.teams.microsoft.com/policies/callpark sehen Sie die Default Policy und deren Einstellungen:
Die Richtlinie selbst enthält folgende Einstellungen:
Sie sehen hier aber auch, dass die Werte für die Nummern und der Timeout "readonly" sind. Sie können (noch) nicht geändert werden.
Ich habe mir angewöhnt, die Default Policy nicht zu ändern und besser für die Personen, die wirklich auch CallPark nutzen, eine passende Richtlinien anzulegen.
Welche Richtlinie für einen Anwender zutrifft, können Sie im Teams Admin Portal einsehen und ändern:
In dem Beispiel wurde dem Benutzer keine Call Park-Richtlinie zugewiesen und die Einstellungen der globalen Richtlinie werden angewendet.
Sicht des Anwender
Damit fehlt nur noch die Information, was der Anwender davon letztlich mitbekommt. Zuerst heißt es auch hier einmal Geduld habe, denn die Einstellungen per PowerShell oder Teams Admin Center werden natürlich in das Teams Directory geschrieben und auch hier gibt es die ein oder andere Replikationszeit. Selbst wenn dann alle Server die Information kennen, haben auch die Teams Services einen Cache, der die Einstellungen vorhält und es hängt z.B.: davon ab, ob der Benutzer sich vor kurzem erst angemeldet oder seine Konfiguration aktualisiert hat. Rechnen Sie mal mit 1-2 Stunden.
Aber selbst dann merkt der Anwender nicht sofort etwas, denn auch der Client muss die neue Konfiguration laden. Das macht er bei der Anmeldung und natürlich auch ab und an zwischendurch. Das Thema kennen Sie aber auch schon aus der Skype for Business-Zeit.
Sobald die Einstellungen beim Client angekommen sind und ein Anruf aktiv sind, kann der Anwender den Anruf auch parken.
Teams teilt dem Anwender die Parknummer mit, die der Anwender dann über einen beliebigen Weg an den gewünschten Empfänger übermittelt.
Achtung: Wenn der Anwender hier das "X" drückt, wird der Anruf nicht beendet sondern bleibt geparkt aber der Park-Code ist nicht mehr in Erfahrung zu bringen!
Einen Anruf kann ein Anwender am einfachsten dadurch abholen, dass er sich unter den Kurzwahlen auf "geparkte Anrufe" geht und dort die Nummer eingibt.
Selbst hier zeigt der Teams-Client keine Liste der aktuell geparkten Anrufe an, sondern sie müssen die Nummer schon wissen.
Das funktioniert natürlich auch auf einem Teams-Telefon. Allerdings konnte ich bislang keine Aussagen zum Support für 3PIP-Telefone finden. Diese basieren weiterhin auf Skype for Business und nutzen in der Cloud ein besonderes Gateway, damit ein "Teams Only" Benutzer mit Telefonie diese Geräte noch voraussichtlich bis Juni 2021 nutzen kann. Es gibt hier aber keinen Hotkey für "Call Unpark".
Auf einem 3PIP-Phone konnte ich einen geparkten Anruf nicht heranziehen. Ein einfaches Telefon in einer Werkhalle ist aktuell keine Lösung.
Fehlersuche Client
Natürlich protokolliert sowohl der Server als auch der Client die verschiedenen Aktionen. Über die Teams Logs auf dem Client (CTRL-AALT-SHIFT-1 drücken" ist eine schnelle Suche per Text-Editor möglich. Hier ein Auszug eines erfolgreichen Park-Vorgangs mit der Nummer 10:
2019-10-10T21:37:48.031Z Inf calling-screen: isCallwithParkservice = undefined 2019-10-10T21:37:47.966Z Inf callingService: startUnparkCall: Type_CallParticipantRemoved: call with id: <guid>, participant: 4:*11. Setting conversation id. thread id null, call type 1 2019-10-10T21:37:47.965Z Inf callingParticipantService: participant removed: PSTN-xxxxxxxxxx, teamsCallId: 4 2019-10-10T21:37:47.716Z Inf CallParkService: [unparkCall] Call unparked successfully. [call][callId=<guid>] [unparkContext=0]. unpark Code: 10 2019-10-10T21:37:47.716Z Inf [Scenario]unpark_call [step](1)stop (4778ms/4779ms) 2019-10-10T21:37:47.657Z Inf callingService: startUnparkCall: succeeded, parkContext 0, parkCode 10 2019-10-10T21:37:43.509Z Inf callingAgents: calling-stack [JS.TsCalling.SignalingAgent] ffffffff: CSA[<guid>][Idle] [ksy09sa3][startOutgoingCall]options={ "causeId": "ksy09sa3", "unpark": true, "context": "*11" } 2019-10-10T21:37:43.058Z Inf CallingUserActionService: placeCallInternal: [withVideo:undefined][conversationId:8:orgid:<guid>][isChannelMeeting:false][isVoicemail:undefined][isUnpark:true][isEchoBotCall:false] 2019-10-10T21:37:42.940Z Inf CallingUserActionService: getEventData: [call][context={"context":"unpark_call"}] 2019-10-10T21:37:42.938Z Inf CallingUserActionService: call enableEndpointHint=true, checkUserMode=undefined, isvoicemail=undefined, isUnpark=true 2019-10-10T21:37:42.938Z Inf [Scenario]unpark_call start 2019-10-10T21:37:42.937Z Inf CallParkService: [unparkCall] Unpark code 10. [unparkContext=0] 2019-10-10T21:37:42.927Z Inf UnparkCallController: Unparking call 2019-10-10T21:37:36.355Z Inf dialogService: Opened the dialog: CallingUnparkCall 2019-10-10T21:37:36.354Z Inf dialogService: Start opening the dialog: CallingUnparkCall 2019-10-10T21:36:03.537Z Inf calling-screen: isCallwithParkservice = undefined 2019-10-10T21:36:03.448Z Inf [Scenario]calling_emergency_service_start_call start 2019-10-10T21:36:03.336Z Inf CallingUserActionService: call enableEndpointHint=true, checkUserMode=undefined, isvoicemail=undefined, isUnpark=undefined 2019-10-10T21:36:01.094Z Inf CallParkService: [deleteParkedCall][call] disposing timer subscriptions 2019-10-10T21:36:01.094Z Inf CallParkService: [deleteParkedCall][call] deleting call from parked call from parkedCalls 2019-10-10T21:35:07.726Z Inf AggregatedSettingsStore: initFromSettings: Fetched settings from local store for schema substratesearch_people: userPropertiesSettings,userResourcesSettings,tenantSettingsV2,callingPolicy,messagingPolicy,clientSettings,meetingPolicy,educationAssignmentsAppPolicy,feedbackPolicy,adminSettings,teamsAndChannelsPolicy,tenantVoiceSettings,policySettings,voiceAdminSettings,callParkPolicy,onlineDialinConferencingPolicy,broadcastMeetingPolicy 2019-10-10T21:35:01.964Z Inf calling-screen: isCallwithParkservice = undefined 2019-10-10T21:34:50.565Z Inf CallParkService: [parkCall] finally is being executed. Deleted [call][callId=<guid>]. [parkContext=0] 2019-10-10T21:34:50.550Z Inf callingService: leaving call: [callId=<guid>][leaveCallContext=call_park_service][leaveCallState:4] 2019-10-10T21:34:50.549Z Inf [Scenario]park_call [step](3)stop (17ms/3462ms) 2019-10-10T21:34:50.532Z Inf [Scenario]park_call [step](2)call_parked (1999ms) 2019-10-10T21:34:50.532Z Inf CallParkService: [parkCall] successfully parked with pickUp Code 10. [call][callId=<guid>][parkContext=0] 2019-10-10T21:34:48.534Z Inf CallParkService: [parkCall] callbeing parked. [call][callId=<guid>] [parkContext=0] 2019-10-10T21:34:48.533Z Inf [Scenario]park_call [step](1)call_held (1446ms) 2019-10-10T21:34:48.533Z Inf CallParkService: [parkCall] Call put on hold using toggleHold. [call][callId=<guid>][parkContext=0] 2019-10-10T21:34:48.533Z Inf [Scenario]hold_call [step](1)stop (1446ms/1446ms) 2019-10-10T21:34:48.531Z Inf callingAgents: calling-stack [JS.TsCalling.SignalingAgent] ffffffff: CSA[<guid>][Connected]/[HTTP]/[588100af][Dispatcher] attempt to send request 2019-10-10T21:34:48.530Z Inf CallTogglingService: [holdCall] Successfully held call (callId = <guid>) 2019-10-10T21:34:48.530Z Inf CallBackgroundBlurMixinImplementation: Called resetBackgroundBlurringOnCallLeave from hold_call
Auf dem Server können Sie über das Call Quality Dashboard den Anruf verfolgen und wer die Rufnummern per Direct Routing angebunden hat, sieht ggfls. auch im Syslog des SBCs/Gateway die "REFER"-Pakete.
Trace auf dem SBC
Wenn Sie ihre Rufnummern selbst mitbringen und keinen Microsoft Dialplan haben, dann können Sie natürlich auch auf dem SBC die Funktion mit tracen. Hier ein Beispiel eines Anrufs von meinem Mobiltelefon auf die Teams-Rufnummer. Der Anruf wird dann gehalten und wieder vom gleichen Telefon aus der Parkschleife abgerufen. Sie gehen im wesentlichen drei Abschnitte:
Abschnitt | Beschreibung |
---|---|
Verbindungsaufbau |
Das ist noch der normale Verbindungsaufbau vom Amt zu Office 365, der mit einem finalen 200OK und ACK abgeschlossen wird. Die Verbindung steht. |
Parken |
Beim Parten sendet Teams nun einen INVITE mit der gleichen Call-ID zurück zum SBC. Der hier wichtige Ausschnitt im SDP ist der "Inactive"-Wert. |
Unpark
|
Wird der geparkte Anruf nun von einem Teilnehmer wieder abgerufen, dann sendet Office 365 einen REFER zum SBC. Der REFER enthält einen "Contact"-Header, mit dem der SBC dann die Verbindung zum neuen Ziel aufbaut. Als neue Verbindung erscheint nun hier auch der neue Ziel-SBC. Das könnte auch ein anderer SBC sein. |
Hier möchte ich es mit der Beschreibung zu Call Park nicht zu weit treiben. Als Reaktion auf den REFER sendet der SBC einen INVITE zu Teams, der aber keine SDP-Kandidaten enthält.
Daher sendet TEAMS seinerseits nun einen INVITE mit Kandidaten zum SDP zurück.
Am Ende wird der Call dann durch BYE von Teams beendet.
Weitere Links
- Direct Routing Konfiguration
- Call Park mit Skype for Business On-Premises
- Park a call in Teams
https://support.office.com/article/park-a-call-in-teams-8538c063-d676-4e9a-8045-fc3b7299bb2f - Call park and retrieve in Microsoft
Teams
https://docs.microsoft.com/de-de/microsoftteams/call-park-and-retrieve - Call Park in Microsoft Teams
https://erwinbierens.com/call-park-in-microsoft-teams/ - Call Park comes to Microsoft Teams –
here’s how it works
https://blog.thoughtstuff.co.uk/2019/01/call-park-comes-to-microsoft-teams-heres-how-it-works/ - Call Park in Microsoft Teams is Launched:
here's how it works
https://techcommunity.microsoft.com/t5/Microsoft-Teams/Call-Park-in-Microsoft-Teams-is-Launched-here-s-how-it-works/m-p/309474 - Parken eines Anrufs in Teams
https://support.office.com/de-de/article/parken-eines-anrufs-in-teams-8538c063-d676-4e9a-8045-fc3b7299bb2f - SIP REFER for Call Transfer
http://www.dialogic.com/webhelp/IMG1010/10.5.2/WebHelp/sip_rfr_calltrans.htm