Teams 中的工作流机器人

工作流机器人允许用户与自适应卡片交互。 自适应卡片操作处理程序使自适应卡片能够在 Teams 应用中进行对话。 可以在多种方案中为用户创建工作流机器人,以增强用户体验,例如事件管理、票证、审批工作流和项目管理卡。 可以使用工作流机器人创建和分配工作项,并将内容同步到 Azure DevOps 或 Jira 系统。

工作流机器人可以安装到团队、群组聊天或个人应用中,具体取决于不同的范围。 默认命令逻辑返回自适应卡片。 可以根据业务需求自定义此逻辑。 对于自定义,需要调用现有 API。

优点

  • 自动执行业务流程和重复工作流,而无需离开对话上下文。

  • 通过各种卡片逐步支持具有顺序工作流的用户,而无需发送其他卡片。

  • 提供特定于用户的最新视图。

  • 使用 TeamsFx SDK 简化编程模型。

    注意

    添加应用时,可以选择想要安装的功能。 有关详细信息,请参阅 配置默认安装选项

可以创建工作流机器人来响应用户触发的自适应卡片。 由 TeamsFx SDK 提供支持的自适应卡片操作处理程序可以执行用户触发的自适应卡片通用操作 Action.Execute 。 为了响应对话中的这一相应卡片操作,自适应卡片操作处理程序会发送另一个自适应卡片。

屏幕截图显示了 Teams 中工作流机器人的最终输出。

卡片操作处理程序

为了简化工作流机器人的创建,TeamsFx SDK 提供了自适应卡片操作处理程序 TeamsFxAdaptiveCardActionHandler。 你只能专注于开发工作流机器人以响应卡片操作,而无需学习 Bot Framework。

下图演示了如何使用 TeamsFx SDK 响应自适应卡片操作:

显示工作流机器人卡操作处理程序的关系图。

  1. 操作卡:定义用户可调用的操作的卡,例如 DoStuff
  2. 卡片操作处理程序:当用户调用相应的卡片操作时触发,其 triggerVerbverb 自适应卡片操作中的 属性相同。 它可以发送响应卡来响应操作。
  3. 响应卡:当用户从操作卡调用操作时响应操作的卡。

若要使用 TeamsFx SDK 处理卡片操作,每个卡片操作处理程序都必须实现 接口 TeamsFxAdaptiveCardActionHandler


TeamsFxAdaptiveCardActionHandler 
{
    /**
     * The verb defined in adaptive card action that can trigger this handler.
     */
    triggerVerb: string;

    /**
     * Specify the behavior for how the card response will be sent in Teams conversation.
     * The default value is `AdaptiveCardResponse.ReplaceForInteractor`, which means the card
     * response will replace the current one only for the interactor.
     */
    adaptiveCardResponse?: AdaptiveCardResponse;
    
    /**
     * The handler function that will be invoked when the action is fired.
     * @param context The turn context.
     * @param actionData The contextual data that associated with the action.
     */
    handleActionInvoked(context: TurnContext, actionData: any): Promise<InvokeResponse>;
}

自定义初始化

可以使用自己的适配器初始化工作流机器人,也可以在初始化后进行自定义。 默认初始化位于 中 bot/src/internal/initialize.js(ts)

可以将初始化逻辑更新为:

  1. 设置为 options.adapter 使用你自己的 BotFrameworkAdapter
  2. 设置为 options.command.commands 包含多个命令处理程序。
  3. 设置为 options.cardAction.actions 包含多个操作处理程序。
  4. 设置为 options.{feature}.enabled 启用多个 ConversationBot 功能。

有关初始化自定义的详细信息,请参阅 其他初始化自定义

添加卡片操作

若要使用 JavaScript 和 TypeScript 添加卡片操作,请执行以下步骤:


1. 向自适应卡片添加操作

可以通过在 JSON 文件中定义新操作 (按钮) 添加到自适应卡片,例如向文件添加新 DoSomething 操作 src/adaptiveCards/helloworldCommandResponse.json

以下代码是操作类型 Action.Execute的示例:

{ 
  "type": "AdaptiveCard", 
  "body": [
    ...
    {
      "type": "ActionSet",
      "actions": [
        {
          "type": "Action.Execute",
          "title": "DoSomething",
          "verb": "doSomething" 
        }
      ]
    },
    ...
  ]
}

在 Teams 中调用操作时,需要谓词属性,以便 TeamsFx 对话 SDK 可以调用相应的操作处理程序。

注意

使用可能导致与其他机器人冲突的常规字符串时,请确保为谓词属性提供全局唯一字符串。 这可以避免意外行为。


2. 使用新的自适应卡片进行响应

可以为调用的每个操作返回一个新的自适应卡片,以便向最终用户显示响应。 需要创建一个新文件, bot/src/adaptiveCards/doSomethingResponse.json 作为操作的响应 doSomething ,其中包含以下内容:

{
  "type": "AdaptiveCard",
  "body": [
    {
      "type": "TextBlock",
      "size": "Medium",
      "weight": "Bolder",
      "text": "A sample response to DoSomething."
    }
  ],
  "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
  "version": "1.4"
}

注意

可以根据业务需求设计卡片布局。 请参阅 自适应卡片设计器


3.添加操作处理程序

可以使用 TeamsFx SDK 的 类 TeamsFxAdaptiveCardActionHandler处理自适应卡片调用的新操作。 你需要在此步骤中自定义操作,例如调用 API、处理数据或根据业务需求执行任何其他操作。

可以创建新文件 bot/src/cardActions/doSomethingActionHandler.js

    const { AdaptiveCards } = require("@microsoft/adaptivecards-tools");
    const { AdaptiveCardResponse, InvokeResponseFactory } = require("@microsoft/teamsfx");
    const responseCard = require("../adaptiveCards/doSomethingResponse.json");

    class DoSomethingActionHandler { 
    triggerVerb = "doStuff";

        async handleActionInvoked(context, message) { 
            const responseCardJson = AdaptiveCards.declare(responseCard).render(actionData);
            return InvokeResponseFactory.adaptiveCard(responseCardJson);
        }
    }

     module.exports = {

       DoSomethingActionHandler,
    }

注意

  • triggerVerb 是操作的谓词属性。
  • actionData 是与操作关联的数据,其中可能包括动态用户输入或操作的数据属性中提供的一些上下文数据。
  • 如果返回自适应卡片,则默认将现有卡片替换为该卡。

4.注册操作处理程序

需要在 中 conversationBot 配置每个新卡片操作,以启用工作流机器人模板的对话流。 可以导航到 bot/src/internal/initialize.js(ts) 文件并更新 actions 属性的 cardAction 数组。

以下步骤可帮助你注册操作处理程序:

  1. 可以打开文件 bot/src/internal/initialize.js(ts)

  2. 需要更新 conversationBot 初始化,才能启用 cardAction 功能。 使用以下代码将处理程序添加到 actions 数组:

          const conversationBot = new ConversationBot({ 
         ... 
         cardAction: { 
           enabled: true, 
           actions: [ 
             new DoStuffActionHandler(),
             new DoSomethingActionHandler() 
           ], 
         } 
       });
    

    注意

    若要详细了解如何扩展工作流机器人模板,请参阅 响应 Teams 中的卡片操作


自定义操作响应

可以使用 adaptiveCardResponse 处理程序中的 属性来自定义机器人向用户发送自适应卡片的方式。 下面是用于自定义的三个选项:

  • 响应卡将替换为当前卡片,其中为触发操作的交互器定义了按钮。 默认情况下,对话中的用户仍可查看原始操作卡片 AdaptiveCardResponse.ReplaceForInteractor

    屏幕截图显示如何自定义机器人发送自适应卡片的方式。

  • 响应卡将替换为聊天中所有用户的操作卡,他们可以查看响应卡 AdaptiveCardResponse.ReplaceForAll

    屏幕截图显示了聊天中所有用户的操作卡已替换为“确认”按钮。

    屏幕截图显示聊天中所有用户的操作卡已替换,没有“确认”按钮。

  • 响应卡作为对话中的单独消息发送,无法替换操作卡。 聊天中的所有用户都可以查看响应卡 AdaptiveCardResponse.NewForAll

    屏幕截图显示作为聊天中的所有用户发送的响应卡作为单独的消息。

使用短信进行响应

还可以使用短信进行响应,而不是使用自适应卡片进行卡片操作响应,使用 InvokeResponseFactory.textMessage

async handleActionInvoked(context: TurnContext, actionData: any): Promise<InvokeResponse> {
    return InvokeResponseFactory.textMessage("This is a sample card action response!");
}

可以在 Teams 中看到以下响应消息:

屏幕截图显示了示例卡片响应。

使用错误消息进行响应

如果要将错误响应消息返回给客户端,可以应用 InvokeResponseFactory.errorResponse 以生成调用响应。 下图显示了自适应卡中的错误消息:

屏幕截图显示了错误响应消息。

注意

有关调用响应格式的详细信息,请参阅 响应格式

自定义自适应卡片内容

可以编辑文件 src/adaptiveCards/helloworldCommand.json 以根据自己的偏好自定义自适应卡片。 该文件 src/cardModels.ts 定义用于填充自适应卡片数据的数据结构。

模型与自适应卡片之间的绑定是通过匹配名称完成的,例如, CardData.title 在自适应卡片中映射到 ${title} 。 可以添加、编辑或删除属性及其绑定,以根据需要自定义自适应卡片。

如果应用程序需要,还可以添加新卡。 若要使用 ColumnSetFactSet生成不同类型的自适应卡片,其中包含列表或动态内容表,请参阅 TeamsFx-Samples

自动刷新到特定于用户的视图

在 Teams 频道或群组聊天中发送自适应卡片时,所有用户都可以看到相同的卡片内容。 使用自适应卡片通用操作的新刷新模型,用户可以拥有特定于用户的视图。 自动刷新还有助于实现审批、轮询创建者控制、票证、事件管理和项目管理卡等方案。 下图演示了如何通过 refresh 模型提供特定于用户的视图:

图中显示了特定于用户的自动刷新模型。

  1. 基本卡:机器人发送一条消息,其中包含卡的基本版本。 此基卡可以作为机器人通知、命令响应或任何其他卡片操作响应发送。 对话的所有成员都可以查看相同的响应。 基础卡会自动刷新到在基本卡的 属性中refresh定义的userId用户。

  2. 刷新行为:用户查看消息后,Teams 客户端会在上次刷新响应后一分钟自动触发刷新。 调用特定于用户的视图处理程序以返回特定用户的UserA卡片视图Response Card。 对话中的其他用户仍然可以查看基本卡。

下图演示了如何在 Teams 中显示特定于用户的视图:

屏幕截图显示了 Teams 中特定于用户的视图。

添加特定于用户的视图

以下步骤可帮助你使用 TeamsFx SDK 添加特定于用户的视图:


1. 在基本自适应卡片中启用刷新

从基卡刷新响应卡时,将从基础卡刷新特定于用户的视图,如 自动刷新用户特定的视图所示。 可以在基础卡上启用自动刷新,如下所示:

  • 第一个选项使用 SDK 启用特定于用户的视图刷新。 基本卡可以作为命令响应或卡操作响应发送。 可以在命令处理程序或 handleCommandReceived 返回基卡的卡片操作处理程序中 handleActionInvoked 启用用户特定的视图刷新。 可以使用 refresh(refreshVerb, userIds, data) 库中的方法 @microsoft/adaptivecards-tools 将刷新节注入到基本卡中。 若要定义刷新部分,请确保提供以下属性:

    1. userIds:一组用户 MRI,适用于可以触发自动刷新的用户。 有关如何在 userIds 自适应卡片的刷新部分中添加列表的详细信息,请参阅 提取名单或用户配置文件
    2. verb:用于标识刷新操作的字符串。
    3. data:与刷新操作关联的可选数据。

    在以下示例中,基卡作为命令响应返回,该响应可自动刷新给特定用户,例如命令发送者:

             import baseCard from "../adaptiveCards/baseCard.json";
             import { AdaptiveCards } from "@microsoft/adaptivecards-tools";
    
             export class MyCommandHandler1 implements TeamsFxBotCommandHandler {
             triggerPatterns: TriggerPatterns = "helloWorld";
    
             async handleCommandReceived(context: TurnContext, message: CommandMessage): 
             Promise<string | Partial<Activity> | void> {
             const refreshVerb = "userViewRefresh";        // verb to identify the refresh action
             const userIds = [ context.activity.from.id ]; // users who will be refreshed
             const data = { key: "value"};                 // optional data associated with the action
    
             const responseCard = AdaptiveCards
               .declare(baseCard)
               .refresh(refreshVerb, userIds, data)
               .render(cardData);
    
                 return MessageFactory.attachment(CardFactory.adaptiveCard(responseCard));
             }
           }
    
  • 第二个选项使特定于用户的视图能够刷新自适应卡片。 这是在 中 baseCard.json定义的刷新操作示例:

    {
      "type": "AdaptiveCard",
      "refresh": {
        "action": {
          "type": "Action.Execute",
          "title": "Refresh",
          "verb": "userViewRefresh" ,
          "data": {
            "key": "value"
          }
        },
        "userIds": [
          "${userID}"
        ]
      },
      "body": [
        ...
      ],
      ...
    }
    
    

    在呈现卡片内容时,需要将 替换为 ${userID} 代码中的用户 MRI。


2. 添加特定于用户的自适应卡片

你需要设计特定于用户的自适应卡片来刷新特定响应卡,例如 responseCard.jsonuserA刷新行为图中显示的。 若要开始,可以创建 responseCard.json 包含以下内容的 ,并将其保存在 bot/src/adaptiveCards 文件夹中:

-
{
  "type": "AdaptiveCard",
  "body": [
    {
      "type": "TextBlock",
      "size": "Medium",
      "weight": "Bolder",
      "text": "This is a user-specific view"
    }
  ],
  "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
  "version": "1.4"
}


3. 添加卡片操作处理程序以刷新视图

可以添加实现的 TeamsFxAdaptiveCardActionHandler 处理程序来处理在 Teams 中自动触发的刷新调用活动:

import responseCard from "../adaptiveCards/responseCard.json";

export class Handler1 implements TeamsFxBotCardActionHandler {
    triggerVerb: string = "userViewRefresh";

    async handleActionInvoked(context: TurnContext, actionData: any): Promise<InvokeResponse> {
      /**
       * If you have multiple userIds defined in your refresh action, for example: userIds: [ "<UserA>", "<userB>" ] ,
       * and you can return different card response for those users respectively with the following code sample.
        
        const currentUserId = context.activity.from.id;
        switch (currentUserId) {
          case "<userA's id>":
            const card1 = AdaptiveCards.declare(card1).render(actionData);
            return InvokeResponseFactory.adaptiveCard(card1);
          case "<userB's id>":
            const card1 = AdaptiveCards.declare(card2).render(actionData);
            return InvokeResponseFactory.adaptiveCard(card2);
        }
     */
      const responseCardJson = AdaptiveCards.declare(responseCard).render(actionData);
      return InvokeResponseFactory.adaptiveCard(responseCardJson);
    } 
}

4.注册操作处理程序

可以使用以下代码在 中 bot/src/internal/initialize.js(ts) 注册刷新操作处理程序:

export const commandBot = new ConversationBot({
  ...
  cardAction: {
    enabled: true,
    actions: [
      new Handler1()
    ],
  }
})


访问 Microsoft Graph

如果要响应需要访问已登录 Teams 用户的Microsoft Graph 数据的命令,则可以使用其 Teams 用户令牌通过单一登录 (SSO) 来执行此操作。 详细了解 Teams 工具包如何帮助你 向 Teams 应用添加单一登录

连接到现有 API

需要经常连接到现有 API,以便检索要发送到 Teams 的数据。 使用 Teams 工具包可以轻松配置和管理现有 API 的身份验证。 有关详细信息,请参阅如何 集成现有的第三方 API

常见问题


如何使用通知扩展工作流机器人?

通知增加了应用中发送自适应卡片以响应外部事件的功能。 例如,将消息发布到事件中心时,应用可以根据需要使用自适应卡片进行响应。 如何使用通知扩展工作流机器人,请参阅 自定义通知


如何使用命令和响应扩展工作流机器人?

默认工作流机器人附带命令和响应。 有关使用命令和响应扩展工作流机器人的详细信息,请参阅 添加命令和响应


分步指南

按照 分步 指南生成 Teams 工作流机器人。

另请参阅