向客户端应用程序发送自定义命令活动

重要

自定义命令将于 2026 年 4 月 30 日停用。 自 2023 年 10 月 30 日起,无法在 Speech Studio 中创建新的自定义命令应用程序。 与此更改相关的是,LUIS 将于 2025 年 10 月 1 日停用。 自 2023 年 4 月 1 日起,无法创建新的 LUIS 资源。

本文介绍如何将活动从自定义命令应用程序发送到运行语音 SDK 的客户端应用程序。

你将完成以下任务:

  • 从自定义命令应用程序定义并发送自定义 JSON 有效负载
  • 从 C# UWP 语音 SDK 客户端应用程序接收并可视化自定义 JSON 有效负载内容

先决条件

设置“向客户端发送活动”

  1. 打开此前创建的自定义命令应用程序

  2. 依次选择“TurnOnOff”命令、完成规则下的“ConfirmationResponse”、“添加操作”

  3. 在“新建操作类型”下,选择“向客户端发送活动”

  4. 将下面的 JSON 复制到“活动内容”

    {
       "type": "event",
       "name": "UpdateDeviceState",
       "value": {
         "state": "{OnOff}",
         "device": "{SubjectDevice}"
       }
     }
    
  5. 选择“保存”以创建包含“发送活动”操作的新规则,然后训练发布更改

    Send Activity completion rule

与客户端应用程序集成

如何:设置使用语音 SDK 的客户端应用程序(预览版)中,你创建了一个使用语音 SDK 的 UWP 客户端应用程序,该应用程序处理了 turn on the tvturn off the fan 等命令。 在添加了一些视觉对象后,可以看到这些命令的结果。

若要添加带有指示“on”或“off”的标签的框,请将 StackPanel 的以下 XML 块添加到 MainPage.xaml

<StackPanel Orientation="Vertical" H......>
......
</StackPanel>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Margin="20">
    <Grid x:Name="Grid_TV" Margin="50, 0" Width="100" Height="100" Background="LightBlue">
        <StackPanel>
            <TextBlock Text="TV" Margin="0, 10" TextAlignment="Center"/>
            <TextBlock x:Name="State_TV" Text="off" TextAlignment="Center"/>
        </StackPanel>
    </Grid>
    <Grid x:Name="Grid_Fan" Margin="50, 0" Width="100" Height="100" Background="LightBlue">
        <StackPanel>
            <TextBlock Text="Fan" Margin="0, 10" TextAlignment="Center"/>
            <TextBlock x:Name="State_Fan" Text="off" TextAlignment="Center"/>
        </StackPanel>
    </Grid>
</StackPanel>
<MediaElement ....../>

添加引用库

由于已经创建了 JSON 有效负载,因此需要添加对 JSON.NET 库的引用来处理反序列化。

  1. 右键单击解决方案。

  2. 选择“管理解决方案的 NuGet 包”,然后选择“浏览”

  3. 如果已安装 Newtonsoft.json,请确保其版本最低为 12.0.3。 如果不是,请转到“管理解决方案的 NuGet 包 - 更新”,搜索“Newtonsoft.json”并对它进行更新 。 本指南使用版本 12.0.3。

    Send Activity payload

  4. 此外,请确保 NuGet 包 Microsoft.NETCore.UniversalWindowsPlatform 最低为 6.2.10。 本指南使用版本 6.2.10。

在“MainPage.xaml.cs”中,添加

using Newtonsoft.Json; 
using Windows.ApplicationModel.Core;
using Windows.UI.Core;

处理收到的有效负载

InitializeDialogServiceConnector 中,将 ActivityReceived 事件处理程序替换为以下代码。 修改后的 ActivityReceived 事件处理程序会从活动中提取有效负载,并分别更改 tv 或 fan 的视觉状态。

connector.ActivityReceived += async (sender, activityReceivedEventArgs) =>
{
    NotifyUser($"Activity received, hasAudio={activityReceivedEventArgs.HasAudio} activity={activityReceivedEventArgs.Activity}");

    dynamic activity = JsonConvert.DeserializeObject(activityReceivedEventArgs.Activity);
    var name = activity?.name != null ? activity.name.ToString() : string.Empty;

    if (name.Equals("UpdateDeviceState"))
    {
        Debug.WriteLine("Here");
        var state = activity?.value?.state != null ? activity.value.state.ToString() : string.Empty;
        var device = activity?.value?.device != null ? activity.value.device.ToString() : string.Empty;

        if (state.Equals("on") || state.Equals("off"))
        {
            switch (device)
            {
                case "tv":
                    await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(
                        CoreDispatcherPriority.Normal, () => { State_TV.Text = state; });
                    break;
                case "fan":
                    await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(
                        CoreDispatcherPriority.Normal, () => { State_Fan.Text = state; });
                    break;
                default:
                    NotifyUser($"Received request to set unsupported device {device} to {state}");
                    break;
            }
        }
        else { 
            NotifyUser($"Received request to set unsupported state {state}");
        }
    }

    if (activityReceivedEventArgs.HasAudio)
    {
        SynchronouslyPlayActivityAudio(activityReceivedEventArgs.Audio);
    }
};

试试看

  1. 启动应用程序
  2. 选择“启用麦克风”
  3. 选择“对话”按钮
  4. 说出 turn on the tv
  5. 电视的可视状态应更改为“打开”

    Screenshot that shows that the visual state of the T V is now on.

后续步骤