如何遍历Microsoft Teams自动话务员的多层嵌套菜单选项?
遍历Microsoft Teams自动话务员嵌套菜单的解决方案
要遍历未知深度的Teams自动话务员(Auto Attendant)嵌套菜单,核心是用递归逻辑处理每个菜单选项指向的子Auto Attendant,同时规避循环引用(比如选项指向自身的情况)。以下是修改后的完整实现:
完整代码实现
function Add-MenuOption { param( [string]$Key, [string]$Action, [string[]]$VoiceResponses, [string]$CallTarget, [string]$ID, [string]$AutoAttendant, [int]$Level ) process { # 标准化转接操作员的选项格式 if ($Action -eq "TransferCallToOperator") { $Key = "0" $VoiceResponses = @("Operator") $CallTarget = "Operator" $ID = "Operator" } return [PSCustomObject]@{ Key = $Key Action = $Action VoiceResponses = $VoiceResponses -join "; " CallTarget = $CallTarget TargetID = $ID AutoAttendant = $AutoAttendant Level = $Level # 记录当前菜单层级,方便查看结构 } } } function Get-NestedAutoAttendantMenu { param( [Microsoft.Rtc.Management.Hosted.OAA.Models.AutoAttendant]$AutoAttendant, [System.Collections.Generic.List[string]]$VisitedIDs, [int]$CurrentLevel ) $results = @() # 避免循环遍历:如果当前Auto Attendant已访问过,直接返回 if ($VisitedIDs.Contains($AutoAttendant.Id)) { return $results } $VisitedIDs.Add($AutoAttendant.Id) # 获取当前Auto Attendant的默认呼叫流程菜单 if ($AutoAttendant.DefaultCallFlow -and $AutoAttendant.DefaultCallFlow.Menu) { foreach ($option in $AutoAttendant.DefaultCallFlow.Menu.MenuOptions) { # 解析DTMF按键(比如DtmfResponse为"Dtmf1",提取为"1") $key = $option.DtmfResponse.ToString().Replace("Dtmf", "") # 处理特殊按键*和# if ($key -eq "Star") { $key = "*" } if ($key -eq "Hash") { $key = "#" } # 匹配CallTarget对应的Auto Attendant名称 $targetID = $option.CallTarget.Id $callTargetName = if ($targetID) { ($allAttendants | Where-Object { $_.ApplicationInstances -contains $targetID }).Name } else { $option.Action.ToString().Split('.')[-1] } # 添加当前菜单选项到结果 $results += Add-MenuOption -Key $key ` -Action $option.Action.ToString() ` -VoiceResponses $option.VoiceResponses ` -CallTarget $callTargetName ` -ID $targetID ` -AutoAttendant $AutoAttendant.Name ` -Level $CurrentLevel # 如果CallTarget是另一个Auto Attendant,且不是当前自身,递归遍历 if ($option.Action -eq "TransferCallToAutoAttendant" -and $callTargetName -ne $AutoAttendant.Name) { $childAttendant = $allAttendants | Where-Object { $_.Name -eq $callTargetName } if ($childAttendant) { $results += Get-NestedAutoAttendantMenu -AutoAttendant $childAttendant ` -VisitedIDs $VisitedIDs ` -CurrentLevel ($CurrentLevel + 1) } } } } return $results } # 主执行逻辑 $allAttendants = Get-CsAutoAttendant $rootAttendant = $allAttendants | Where-Object { $_.Name -like "*AA Georgian Top*" } # 初始化已访问ID列表,避免循环 $visitedIDs = [System.Collections.Generic.List[string]]::new() $fullCallTree = Get-NestedAutoAttendantMenu -AutoAttendant $rootAttendant ` -VisitedIDs $visitedIDs ` -CurrentLevel 0 # 输出结果表格 $fullCallTree | Format-Table Key, Level, Action, VoiceResponses, CallTarget, AutoAttendant -AutoSize
关键逻辑说明
递归遍历核心:
Get-NestedAutoAttendantMenu函数负责递归处理每个Auto Attendant的菜单,每次处理前检查是否已访问过该ID,防止循环引用- 当菜单选项的Action为
TransferCallToAutoAttendant,且目标不是当前Auto Attendant时,触发递归调用,层级+1
标准化菜单选项:
Add-MenuOption函数统一处理菜单选项的格式,将转接操作员的选项标准化为固定格式- 提取DTMF按键时,自动转换
DtmfStar为*、DtmfHash为#,更直观
层级记录:
- 添加
Level字段记录当前菜单的嵌套层级,方便在输出中区分主菜单、子菜单、孙菜单等
- 添加
输出示例
执行后会输出包含所有层级菜单的表格,示例如下:
| Key | Level | Action | VoiceResponses | CallTarget | AutoAttendant |
|---|---|---|---|---|---|
| 0 | 0 | TransferCallToOperator | Operator | Operator | AA Georgian Top |
| 1 | 0 | TransferCallToAutoAttendant | Department A | Department A | AA Georgian Top |
| 0 | 1 | TransferCallToOperator | Operator | Operator | Department A |
| 1 | 1 | TransferCallToUser | Group A1 | Group A1 | Department A |
| 3 | 1 | TransferCallToAutoAttendant | Department B | Department B | Department A |
| ... | ... | ... | ... | ... | ... |
内容的提问来源于stack exchange,提问作者Shamus Berube
相关产品推荐
相关产品推荐

