使用自适应卡片格式设计 Outlook 可操作邮件卡片Designing Outlook Actionable Message cards with the Adaptive Card format

Outlook 可操作邮件卡片可以使用自适应卡片格式来设计。Outlook Actionable Messages cards are designed using the Adaptive Card format. 自适应卡片格式是一种灵活性强、设计简单且功能强大的声明性布局格式,可轻松创造出视觉效果丰富的卡片。The Adaptive Card format is a simple yet powerful declarative layout format that provides a lot of flexibility, allowing for visually rich cards. 在本主题中我们将介绍 Outlook 特定功能之一,自适应卡片格式。In this topic we'll cover the Outlook-specific features of the Adaptive Card format.

重要

自适应卡格式仅适用于通过电子邮件发送的可操作邮件,并且它是支持 iOS 版和 Android 版 Outlook 的 必要 条件。The Adaptive Card format is only available for Actionable Messages sent via email, and is required to support Outlook on iOS and Android. 仍支持 MessageCard 格式,但已不再着重强调。The MessageCard format is still supported but is now de-emphasized. Office 连接器和 Microsoft Teams 连接器目前不支持自适应卡片格式。Office connectors and Microsoft Teams connectors do not currently support the Adaptive Card format. 如果正在使用 Office 365 连接器或 Microsoft Teams 连接器,请参阅 MessageCard 格式参考If you are implementing an Office 365 or Microsoft Teams connector, please refer to the MessageCard format reference.

有关哪些 Outlook 版本支持自适应卡片格式的信息,请参阅 可操作邮件的 Outlook 版本要求For information on which Outlook versions support the Adaptive Card format, see Outlook version requirements for actionable messages.

卡片样本Card Playground

卡片操练场工具已更新,可支持自适应卡片格式。Our Card Playground tool has been updated to support the Adaptive Card format. 此处将显示自适应卡片示例(包括以下所示),可帮助您开始创建自己的卡片,同时允许您将这些卡片发送到自己的 Microsoft 365 电子邮件帐户,以查看它们在 Outlook 中的外观。There you will find Adaptive Card samples (including the one below) that can help you get started crafting your own cards and also allows you to send those cards to your own Microsoft 365 email account to see how they look in Outlook.

自适应卡片设计器(预览版)Adaptive Cards Designer (preview)

自适应卡片设计器提供拖放体验,可快速构建和调整自适应卡片。The Adaptive Cards Designer provides a drag-and-drop experience to quickly build and tweak adaptive cards.

简单的自适应卡片示例A simple Adaptive Card example

自适应卡片示例

上述卡片描述了自适应卡片的部分核心功能和最强大的功能:The above card illustrates some of the core and most powerful capabilities of the Adaptive Card format:

  • 以任意顺序堆叠各种类型元素的能力The ability to stack elements of various types in any order
  • 控制这些元素之间空间量的能力The ability to control the amount of space between those elements
  • 在多个列中布局元素的能力The ability to layout elements in multiple columns
  • 将元素在水平方向和垂直方向对齐的能力The ability to align elements horizontally and vertically

下面是此卡片的制作方式:Here is how this card is crafted:

{
  "$schema": "https://adaptivecards.io/schemas/adaptive-card.json",
  "version": "1.0",
  "type": "AdaptiveCard",
  "speak": "<s>Your flight is confirmed for you and 3 other passengers from San Francisco to Amsterdam on Friday, October 10 8:30 AM</s>",
  "body": [
    {
      "type": "ColumnSet",
      "columns": [
        {
          "width": "stretch",
          "verticalContentAlignment": "center",
          "items": [
            {
              "type": "TextBlock",
              "size": "medium",
              "text": "**FLIGHT ITINERARY - CONTOSO AIR**"
            },
            {
              "type": "TextBlock",
              "spacing": "none",
              "text": "Passenger: David Claux",
              "isSubtle": true
            }
          ]
        },
        {
          "width": "auto",
          "items": [
            {
              "type": "Image",
              "width": "48px",
              "url": "http://lh3.googleusercontent.com/ik5VKcUE5U7qGSpU3XWwAwe_zeOnHU5x_79o-VXf-C_EGrFPHp4-NcKRCtblrJM5iO61=w300"
            }
          ]
        }
      ]
    },
    {
      "type": "TextBlock",
      "text": "2 Stops",
      "weight": "bolder",
      "spacing": "medium"
    },
    {
      "type": "TextBlock",
      "text": "Fri, October 10 8:30 AM",
      "weight": "bolder",
      "spacing": "none"
    },
    {
      "type": "ColumnSet",
      "separator": true,
      "columns": [
        {
          "type": "Column",
          "width": 1,
          "items": [
            {
              "type": "TextBlock",
              "text": "San Francisco",
              "isSubtle": true
            },
            {
              "type": "TextBlock",
              "size": "extraLarge",
              "color": "accent",
              "text": "SFO",
              "spacing": "none"
            }
          ]
        },
        {
          "type": "Column",
          "width": "auto",
          "items": [
            {
              "type": "TextBlock",
              "text": "&nbsp;"
            },
            {
              "type": "Image",
              "url": "https://messagecardplayground.azurewebsites.net/assets/airplane.png",
              "size": "small",
              "spacing": "none"
            }
          ]
        },
        {
          "type": "Column",
          "width": 1,
          "items": [
            {
              "type": "TextBlock",
              "horizontalAlignment": "right",
              "text": "Amsterdam",
              "isSubtle": true
            },
            {
              "type": "TextBlock",
              "horizontalAlignment": "right",
              "size": "extraLarge",
              "color": "accent",
              "text": "AMS",
              "spacing": "none"
            }
          ]
        }
      ]
    },
    {
      "type": "TextBlock",
      "text": "Non-Stop",
      "weight": "bolder",
      "spacing": "medium"
    },
    {
      "type": "TextBlock",
      "text": "Fri, October 18 9:50 PM",
      "weight": "bolder",
      "spacing": "none"
    },
    {
      "type": "ColumnSet",
      "separator": true,
      "columns": [
        {
          "type": "Column",
          "width": 1,
          "items": [
            {
              "type": "TextBlock",
              "text": "Amsterdam",
              "isSubtle": true
            },
            {
              "type": "TextBlock",
              "size": "extraLarge",
              "color": "accent",
              "text": "AMS",
              "spacing": "none"
            }
          ]
        },
        {
          "type": "Column",
          "width": "auto",
          "items": [
            {
              "type": "TextBlock",
              "text": "&nbsp;"
            },
            {
              "type": "Image",
              "url": "https://messagecardplayground.azurewebsites.net/assets/airplane.png",
              "size": "small",
              "spacing": "none"
            }
          ]
        },
        {
          "type": "Column",
          "width": 1,
          "items": [
            {
              "type": "TextBlock",
              "horizontalAlignment": "right",
              "text": "San Francisco",
              "isSubtle": true
            },
            {
              "type": "TextBlock",
              "horizontalAlignment": "right",
              "size": "extraLarge",
              "color": "accent",
              "text": "SFO",
              "spacing": "none"
            }
          ]
        }
      ]
    }
  ]
}

自适应卡片设计提示Adaptive Card design tips

根据想要实现的布局,自适应卡片可以非常简单,也可以异常复杂。An Adaptive Card can be very simple or quite complex depending on the layout you wish to achieve. 在编写自适应卡片有效载荷之前,事先谋划好您的设计方案(例如使用绘图工具或者仅仅使用笔和纸),总归是一个不错的主意。这样一来,将更容易把视觉图形转换为合适的自适应卡片结构。It is always a good idea to plan your design ahead of writing the Adaptive Card payload, using a paint tool for instance or even just pen and paper; this will make it a lot easier to translate visuals into the appropriate Adaptive Card constructs. 下面是帮助您入门的一些设计提示。Below are a few design tips to help you get started.

文本格式Text formatting

卡片中所有 TextBlock 元素都可使用 Markdown 来格式化。All TextBlock elements in a card can be formatted using Markdown. Outlook 支持基本的 Markdown。Outlook supports basic Markdown.

重要

由于所有 TextBlock 元素均被处理为 Markdown,因此必要时请务必将 Markdown 特殊字符(例如 *#)转义。Since all TextBlock elements are processed as Markdown, be sure to escape Markdown special characters (such as * or #) if needed.

效果Effect Markdown 语法Markdown syntax
斜体Italics *This text is in italics*
粗体Bold **This text is bold**
粗斜体Bold + italics ***This text is bold and in italics***
删除线Strike-through ~~This text is struck through~~
链接Link [Microsoft](http://www.microsoft.com)
标题 (级别 1 到 6)Headings (level 1 through 6) # Heading###### Heading# Heading through ###### Heading
项目符号列表Bulleted list * List item- List item* List item or - List item

提示

  • 务必 使用 Markdown 设置文本格式。Do use Markdown to format text.
  • 请勿 在卡片中使用 HTML 标记。将忽略 HTML 并将其视为纯文本。Don't use HTML markup in your cards. HTML is ignored and treated as plain text.

窄屏幕设计Design for a narrow screen

就像设计一封电子邮件的 HTML 正文一样,必须假定您的自适应卡片可能会显示在宽屏幕和窄屏幕上(例如台式电脑和移动电话)。Just like when designing the HTML body of an email, you have to assume that your Adaptive Card might be displayed on both wide and narrow screens (e.g. a desktop and a mobile phone.)

提示

  • 设计自适应卡片时,务必 考虑在窄屏幕上显示的效果。Do design your Adaptive Card in such a way that it looks great on a narrow screen. 通常情况下,专为窄屏设计的卡片可以完美扩展到宽屏。Typically, a card designed for a narrow screen will scale well to a wide screen. 但是反过来却无法实现。The opposite is however not true.
  • 请勿 基于这样的假定来设计您的自适应卡片,即您的自适应卡片只有 Outlook 桌面用户才能看到。Don't design your Adaptive Card assuming that only users of Outlook on the desktop will see it.

精心制作高 DPI 屏幕图像Craft your images with high DPI screens in mind

从前,大多数屏幕都使用较低分辨率(例如 1024 x 768 像素)和 96 DPI(每英寸点数),这意味着在一英寸屏幕的实际显示范围中 96 像素即适用。Not so long ago, most screens had a somewhat low resolution (1024x768 pixels for instance) and were operating at 96 DPI (Dots Per Inch), meaning that 96 pixels would fit within an actual inch of the screen. 但在过去几年中,屏幕分辨率和 DPI 指标有了突飞猛进的发展,尤其是在移动设备上,现在在屏幕上运行 192 DPI 或更高 DPI 已经十分常见。But in the past few years, screens have grown considerably in terms of resolution and DPI, especially on mobile devices, and it is now very common for a screen to operate at 192 DPI or even more.

在设计自适应卡片时,需要确保图像效果在任何屏幕上都能良好显示(不考虑 DPI)。When designing your Adaptive Cards, you need to make sure your images will look good on any screen regardless of its DPI.

提示

  • 在设计图像时,务必 假设为图像在高 DPI 屏幕上显示。Do design your images assuming they will be displayed on a high DPI screen. 专为低 (96) DIP 屏幕设计的图像在高 DPI 屏幕上显示时会被放大显示,因此看起来像是被像素化。An image designed for a low (96) DPI screen will be blown up when displayed on a higher DPI screen and will therefore look pixelated. 专为高 DPI 屏幕设计的图像在较低 DPI 屏幕上显示时会收缩,通常会产生较好的效果。An image designed for a high DPI screen will be shrunk on a lower DPI screen which usually yields good results. 换言之,最好是设计为 100 x 100 像素图像但显示为 50 x 50 像素图像,而不是设计为 50 x 50 像素但显示为 100 x 100 像素。In other words, it is better to design a 100x100 pixels image and display it at 50x50 pixels than to design a 50x50 pixels image and display it at 100x100 pixels.
  • 如果需要精确控制卡片中图像的实际大小,请 务必 使用 widthheight 属性(图像 元素)。Do use the width and height properties of the Image element if you need to precisely control the actual size of the images in your card.
  • 设计图像时,请勿 使用固定背景颜色,如白色,除非用户能看到该背景颜色。Don't design your images with a fixed background color, like white, unless that background color is supposed to be visible to the user. 在 Outlook 中,自适应卡片不一定要在白色背景上显示,图像应能够叠加在任何背景色之上。In Outlook, your Adaptive Cards will not necessarily be displayed on top of a white background, and your images should be able to superimpose themselves on top of any background color. 因此,务必 使图像背景透明。For that reason, do make the background of your images transparent.
  • 请勿 使用内置填充材料来制作图像。Don't craft your images with built-in paddings. 此类填充材料通常会在图像侧面引入多余间距来干扰整体布局。Such paddings usually interfere with the overall layout by introducing undesirable spacing on the side of your image.

容器的使用Use of containers

仅在必要时使用 Container 元素。Use the Container element only when necessary. 可通过 Container 元素,将一些元素归为一组。The Container element makes it possible to group a set of elements together.

提示

  • 务必 使用 Container强调一组元素:通过将 Containerstyle属性设置 emphasis,可着重突出 Container 及其所包含的元素。Do use a Container to emphasize a group of elements: by setting the style property of the Container to emphasis you can make that Container, and the elements it contains, stand out.
  • 务必 使用 Container 将一个操作与元素组关联起来:通过设置 Container 的属性 selectActionContainer 及其内容成为可触发指定操作的可点击区域。Do use a Container to associate an action with group of elements: by setting the selectAction property of a Container, the Container and its content become a single clickable area that triggers the specified action.
  • 务必 使用 Container 让卡片的一部分能够折叠:通过使用 Action.ToggleVisibility(以 Container 为目标),可轻松使一组元素变为可折叠的状态。Do use a Container to make a portion of your card collapsible: by using an Action.ToggleVisibility targeted to a Container, you can easily make a group of elements collapsible.
  • 请勿Container 用于其他任何用途。Don't use Container for any other reason.

使用列Use of columns

仅当需要在单个横线上对齐多个元素时使用 ColumnSetUse ColumnSet only when you need to align several elements on a single horizontal line.

提示

  • 务必ColumnSet 用于类似于表格的布局(一般情况下)。Do use ColumnSet for table-like layouts in general.
  • 务必 在需要时才使用 ColumnSet,例如,在卡片的最左边显示一张图片,在卡片最右边的同一行中显示一些文本。Do use ColumnSet if you need to, for example, display an image of the far left of the card and some text on the same line at the far right of the card.
  • 务必 对列使用相应的大小调整方法:Do use the appropriate sizing approach for columns:
    • Column 使用 "width": "auto",以使用其内容所需的必要宽度。Use "width": "auto" for a Column to use as much width as is necessary to fit its content.
    • 使用 "width": "stretch"(对 Column),以便在 ColumnSet 中使用剩余宽度。Use "width": "stretch" for a Column to use the remaining width in the ColumnSet. 多个 Columns 具有 "width": "stretch" 时,它们将共享剩余宽度。When multiple Columns have "width": "stretch", they all equally share the remaining width.
    • 使用 "width": <number>(对 Column),以便在 ColumnSet 中按比例使用可用宽度。Use "width": <number> for a Column to use a proportion of the available width in the ColumnSet. 如果有三列的 width 属性分别设置为 145,则最终分别会使用 10%、40% 和 50% 的可用宽度。If you have three columns with their width property set to 1, 4 and 5 respectively, they will end up using 10%, 40% and 50% of the available width, respectively.
    • 使用 "width": "<number>px" 实现特定像素宽度。Use "width": "<number>px" to have a specific pixel width. 在创建表格布局时尤其有用(且有必要)。This is particularly useful (and necessary) when creating table layouts.
  • 如果只需要在垂直方向堆叠元素,请勿 使用 ColumnSetDon't use ColumnSet if all you need is stack elements vertically.

Outlook 特定自适应卡片属性和功能Outlook-specific Adaptive Card properties and features

Outlook 引入了一组额外自适应卡片属性和功能,可在可操作邮件上下文中使用。Outlook introduces a set of additional Adaptive Card properties and features for use in the context of Actionable Messages.

重要

Outlook 特定的自适应卡片属性和功能 仅适用于可操作邮件上下文Outlook-specific Adaptive Card properties and features only work in the context of Actionable Messages. 它们与其他启用了自适应卡片的应用程序不兼容,因此并未记录在官方自适应卡片网站上。They will NOT work in other Adaptive Card enabled applications and are therefore not documented on the official Adaptive Cards site.

不支持 Outlook 可操作邮件的自适应卡片功能Adaptive Card features not supported with Outlook Actionable Messages

Action.SubmitAction.Submit

Action.Submit 操作类型 支持 Outlook 可操作邮件。The Action.Submit action type is NOT supported with Outlook Actionable Messages. 如果在卡片中包含 Action.Submit,则此项不会显示出来。If you include an Action.Submit in your card, it will not be displayed.

Input.TimeInput.Time

Input.Time 元素类型 支持 Outlook 可操作邮件。The Input.Time element type is NOT supported with Outlook Actionable Messages. 如果在卡片中包含 Input.Time 元素,则不会显示该元素。If you include an Input.Time element in your card, it will not be displayed. 如果需要允许用户输入一个时间,请使用 Input.Text 而不是验证其值服务器端。If you need to allow users to input a time, use an Input.Text instead and validate its value server-side.

Action.HttpAction.Http

Outlook 可操作邮件通过 Action.Http 类型使用基于 HTTP 的操作模型。Outlook Actionable Messages use an HTTP-based action model via the Action.Http type. 通过使用 Action.Http,当用户在卡片中采取了操作时,可实现对特定目标 url 执行 GET 或 POST 请求。Action.Http makes it possible to make a GET or POST request to a specific target url as a result of a user taking an action in a card.

属性名称Property name 类型Type 必需Required 说明Description
type 字符串String Yes 必须设置为 Action.HttpMust be set to Action.Http.
title 字符串String No 例如,操作的标题,会显示在屏幕上的按钮控件上。The title of the action as it will appear on screen on a button control, for instance.
method 字符串String Yes 有效值为 GETPOSTValid values are GET and POST. method 设置为 POST 时,必须指定 body 属性。When method is set to POST the body property must be specified.
url 字符串String Yes 请求的目标端点的 url。The url of the request's target endpoint. url 属性支持输入值替换The url property supports input value substitution. 注释: 必须可通过 Internet 访问此 URL,无法使用 localhostNote: this URL must be accessible from the internet, you cannot use localhost.
headers HttpHeader 对象数组Array of HttpHeader objects No 应发送到目标端点的可选标头列表。An optional list of headers that should be sent to the target endpoint .
body 字符串String 仅当 method 设置为 POSTOnly if method is set to POST POST 请求的正文。The body of the POST request. body 属性支持输入值替换The body property supports input value substitution.

HttpHeaderHttpHeader

属性名称Property name 类型Type 必需Required 说明Description
name 字符串String Yes HTTP 标头名称。The name of the HTTP header. 例如,Content-TypeFor example, Content-Type.
value 字符串String Yes HTTP 标头值。The value of the HTTP header. 例如,application/jsonFor example, application/json. value 属性支持输入值替换The value property supports input value substitution.

Action.Http 示例Action.Http example

{
  "type": "AdaptiveCard",
  "version": "1.0",
  "body": [
    {
      "type": "TextBlock",
      "text": "Hello world!"
    }
  ],
  "actions": [
    {
      "type": "Action.Http",
      "title": "Click me!",
      "method": "POST",
      "url": "https://contoso.com/api/...",
      "body": "<body of the POST request>",
      "headers": [
        { "name": "Content-Type", "value": "application/json" }
      ]
    }
  ]
}

Action.Http 示例卡片

实现 Web APIImplementing the Web API

url 属性中指定的 URL 必须符合以下要求。The URL specified in the url property must conform to the following requirements.

  • 终结点必须接受 POST 请求。The endpoint must accept POST requests.
  • 终结点应接受 body 属性中的内容。The endpoint should accept the contents of the body property.
  • 终结点应使用 Authorization 标头中发送的 JWT 验证请求是否来自 MicrosoftThe endpoint should use the JWT sent in the Authorization header to verify that requests come from Microsoft.

输入值替换Input value substitution

自适应卡片可能包含输入,且可能需要通过 Action.Http 操作将这些输入值传递到目标端点。Adaptive Cards may contain inputs, and it may be necessary to pass the values of these inputs to the target endpoint via an Action.Http action. 可以使用输入值替换来完成。This is done using input value substitution. 请考虑下面的示例:Consider the following example:

{
  "type": "AdaptiveCard",
  "version": "1.0",
  "body": [
    {
      "type": "TextBlock",
      "text": "What's your name?"
    },
    {
      "type": "Input.Text",
      "id": "nameInput",
      "placeholder": "Type your name"
    }
  ],
  "actions": [
    {
      "type": "Action.Http",
      "title": "Say hello",
      "method": "GET",
      "url": "https://contoso.com/sayhello?name={{nameInput.value}}"
    }
  ]
}

输入值替换示例卡片

上述卡片定义了文本输入并将其 id 属性设置为 nameInputThe above card defines a text input and sets it id property to nameInput. 它还定义了一个 Action.Http 操作,用于对域 contoso.com 上的一个终结点执行 GET 调用。It also defines an Action.Http action that makes a GET call to an endpoint on domain contoso.com. 在目标 URL 上包含 ?name={{nameInput.value}} 后,会在用户执行该操作时动态替换 ID 为 nameInput 的输入的值。With the inclusion of ?name={{nameInput.value}} on the target URL, the value of the input with id nameInput will be dynamically substituted at the time the action is taken by the user. 所以如果用户在文本输入中输入姓名 David 后,替换后的目标 URL 为 https://contoso.com/sayhello?name=DavidSo if the user had entered the name David in the text input, the target URL after substitution would be https://contoso.com/sayhello?name=David

输入值替换在 Action.Http 操作的正文属性中也适用。Input value substitution also works in the body property of an Action.Http action. 例如:For example:

{
  "type": "AdaptiveCard",
  "version": "1.0",
  "body": [
    {
      "type": "TextBlock",
      "text": "What's your name?"
    },
    {
      "type": "Input.Text",
      "id": "nameInput",
      "placeholder": "Type your name"
    }
  ],
  "actions": [
    {
      "type": "Action.Http",
      "title": "Say hello",
      "method": "POST",
      "url": "https://contoso.com/sayhello",
      "body": "{{nameInput.value}}"
    }
  ]
}

报告 Action.Http 操作执行成功与否Reporting Action.Http execution success or failure

如果成功执行 Action.Http 操作,服务应返回 HTTP 200 状态代码。Your service should return an HTTP 200 status code when it successfully executes an Action.Http action. 如果操作执行失败,服务应返回 HTTP 4xx 状态代码,并在其响应中包含 CARD-ACTION-STATUS HTTP 标头,以指定自定义错误消息。If the action execution fails, your service should return an HTTP 4xx status code, and it should also include the CARD-ACTION-STATUS HTTP header in its response to specify a custom error message. Action.Http 无法执行的情况下,会向最终用户显示标头值。The value of that header will be displayed to the end-user in case the Action.Http fails to execute.

提示

返回 Action.Http 操作的响应时,请遵循下面这些准则。Follow these guidelines when returning a response to Action.Http actions.

  • 务必 在错误响应中返回 CARD-ACTION-STATUS 标头。Do return the CARD-ACTION-STATUS header in your error responses.
  • 务必 尽可能地使标头中的消息提供丰富且有意义的内容。Do make the message in that header as informative and meaningful as possible.
  • 请勿CARD-ACTION-STATUS 标头中提及执行操作的人员名称及执行操作的时间。Don't mention either the name of the person taking the action nor the time the action is being taken in your CARD-ACTION-STATUS header.

刷新卡片Refresh cards

刷新卡片是非常强大的机制,通过它,Action.Http 操作可以在其成功完成后以动态形式对卡片进行完全更新。许多场景可从刷新卡片机制受益:Refresh cards are a very powerful mechanism that allow Action.Http actions to fully update the card on the fly as the action successfully completes. There are many scenarios that benefit from refresh cards:

  • 审批场景(例如零用金报销单)Approval scenario (e.g. expense report)
    • 批准或拒绝请求后,将刷新卡片以删除批准/拒绝操作并更新其内容,以便其反映请求已被批准或拒绝的事实。Once the request is approved or rejected, the card is refreshed to remove the approve/decline actions and update its content so it reflects the fact that it's been approved or declined.
  • 任务状态Task status
    • 对任务执行操作后,例如设置其截止日期,卡片将进行刷新以便在事件中包含更新的截止日期。When an action is taken on a task, such as setting its due date, the card refreshes to include the updated due date in its facts.
  • 调查Survey
    • 问题得到答复后,卡片将进行刷新,以便:Once the question has been answered, the card is refreshed so:
      • 不再允许用户回答。It no longer allows the user to respond.
      • 显示更新状态,例如在用户实际回答旁显示“感谢答复此调查”。It shows updated status, like "Thanks for responding to this survey" alongside the user's actual response.
      • 可能包含新的 Action.OpenUrl 操作,以供用户在线咨询此调查。Potentially include a new Action.OpenUrl action that allows the user to consult the survey online.

若要刷新 Action.Http 操作后生成的卡片,服务需要执行以下操作:To refresh a card as a result of an Action.Http action, a service needs to do the following:

  • 在其收到的 HTTP POST 请求响应的正文中加入新卡片的 JSON 负载。Include the JSON payload of the new card in the body of the response to the HTTP POST request it received.
  • CARD-UPDATE-IN-BODY: true HTTP 标头添加到响应中,以使接收客户端知道其应分析响应正文并提取新卡片(如果未包含刷新卡片机制,则此操作可避免不必要的处理过程)。Add the CARD-UPDATE-IN-BODY: true HTTP header to the response, in order to let the receiving client know that it should parse the response body and extract a new card (this is to avoid unnecessary processing when no refresh card is included.)

提示

返回刷新卡片时,请遵循下面这些准则。Follow these guidelines when returning refresh cards.

  • 务必 对只能执行一次的操作使用刷新卡片机制。在这些情况下,刷新卡片不会包含无法再次执行的操作。Do use refresh cards with actions that can only be taken a single time. In those cases, the refresh card would not include any action that cannot be taken anymore.
  • 务必 对将更改执行操作的实体状态的操作使用刷新卡片机制。在这些情况下,刷新卡片应包含实体的更新信息,并且可以更改可供执行的操作集。Do use refresh cards with actions that change the state of the entity they are performed on. In those cases, the refresh card should include updated information about the entity, and MAY change the set of actions that can be performed.
  • 请勿 使用刷新卡片与用户进行对话。例如,请勿将刷新卡片用于多步骤“向导”。Don't use refresh cards to lead a conversation with the user. For instance, don't use refresh cards for a multi-step "wizard".
  • 至少包含一个 Action.OpenUrl 操作,以便在生成实体的外部应用程序中查看实体。Do include at least an Action.OpenUrl action to view the entity in the external app it comes from.

Action.InvokeAddInCommandAction.InvokeAddInCommand

Action.InvokeAddInCommand 操作会打开一个 Outlook 加载项任务窗格。The Action.InvokeAddInCommand action opens an Outlook add-in task pane. 如果未安装加载项,用户会看到提示,只需单击一下,即可安装加载项。If the add-in is not installed, the user is prompted to install the add-in with a single click.

执行 Action.InvokeAddInCommand 操作时,Outlook 会先检查是否已为用户安装并启用请求的加载项。When an Action.InvokeAddInCommand action is executed, Outlook first checks if the requested add-in is installed and turned on for the user. 如果没有,将通知用户此操作需要使用加载项,只需单击一下,即可安装并启用加载项。If it is not, the user is notified that the action requires the add-in, and is able to install and enable the add-in with a single click. Outlook 打开请求的任务窗格,为加载项提供此操作指定的任何初始化上下文。Outlook opens the requested task pane, making any initialization context specified by the action available to the add-in.

有关详细信息,请参阅通过可操作邮件调用 Outlook 加载项For more information, see Invoke an Outlook add-in from an actionable message.

属性名称Property name 类型Type 必需Required 说明Description
type 字符串String Yes 必须设置为 Action.InvokeAddInCommandMust be set to Action.InvokeAddInCommand.
title 字符串String No 例如,操作的标题,会显示在屏幕上的按钮控件上。The title of the action as it will appear on screen on a button control, for instance.
addInId 字符串String Yes 指定相应加载项的加载项 ID。Specifies the add-in ID of the required add-in. 加载项清单的 Id 元素中包含加载项 ID。The add-in ID is found in the Id element in the add-in's manifest.
desktopCommandId 字符串String Yes 指定打开所需任务窗格的加载项命令按钮的 ID。Specifies the ID of the add-in command button that opens the required task pane. 加载项清单中定义此按钮的 Control 元素id 属性中包含此命令按钮 ID。The command button ID is found in the id attribute of the Control element that defines the button in the add-in's manifest. 必须在 MessageReadCommandSurface 扩展点中定义指定的 Control 元素,并且必须为 Button 类型。此外,控件的 Action 还必须为 ShowTaskPane 类型。The specified Control element MUST be defined inside a MessageReadCommandSurface extension point, be of type Button, and the control's Action must be of type ShowTaskPane.
initializationContext 对象Object Yes 开发者可以在此字段中指定任意有效的 JSON 对象。Developers may specify any valid JSON object in this field. 此值会序列化为字符串,并在操作执行时提供给加载项。The value is serialized into a string and made available to the add-in when the action is executed. 这样一来,操作就可以将初始化数据传递给加载项。This allows the action to pass initialization data to the add-in.

Action.DisplayMessageFormAction.DisplayMessageForm

Action.DisplayMessageForm 操作会打开给定邮件 ID 的邮件的读取表单。The Action.DisplayMessageForm action opens the read form of a message given that message's ID. 可以通过 Outlook REST API 检索邮件 ID。Message IDs can be retrieved via the Outlook REST APIs.

属性名称Property name 类型Type 必需Required 说明Description
type 字符串String Yes 必须设置为 Action.DisplayMessageFormMust be set to Action.DisplayMessageForm.
title 字符串String No 例如,操作的标题,会显示在屏幕上的按钮控件上。The title of the action as it will appear on screen on a button control, for instance.
itemId 字符串String Yes 指定要打开邮件的 ID。Specifies the ID of the message to open.

Action.DisplayAppointmentFormAction.DisplayAppointmentForm

Action.DisplayAppointmentForm 操作打开给定日历项目 ID 的日历项目的读取表单。The Action.DisplayAppointmentForm action opens the read form of a calendar item given that calendar item's ID. 可以通过 Outlook REST API 检索日历项目 ID。Calendar item IDs can be retrieved via the Outlook REST APIs.

属性名称Property name 类型Type 必需Required 说明Description
type 字符串String Yes 必须设置为 Action.DisplayAppointmentFormMust be set to Action.DisplayAppointmentForm.
title 字符串String No 例如,操作的标题,会显示在屏幕上的按钮控件上。The title of the action as it will appear on screen on a button control, for instance.
itemId 字符串String Yes 指定要打开的日历项目的 ID。Specifies the ID of the calendar item to open.

Action.ToggleVisibilityAction.ToggleVisibility

使用 Action.ToggleVisibility 操作,用户在点击按钮或其他可操作元素时,可显示和/或隐藏卡片特定元素。The Action.ToggleVisibility action makes it possible to show and/or hide specific elements of a card as a result of a user clicking on a button or other actionable element. isVisible 属性配合使用时,Action.ToggleVisibility 可实现单个卡片的额外交互度。Coupled with the isVisible property, Action.ToggleVisibility allows for an extra degree of interactivity within a single card.

属性名称Property name 类型Type 必需Required 说明Description
type 字符串String Yes 必须设置为 Action.ToggleVisibilityMust be set to Action.ToggleVisibility.
title 字符串String No 例如,操作的标题,会显示在屏幕上的按钮控件上。The title of the action as it will appear on screen on a button control, for instance.
targetElements 字符串或 TargetElement 数组Array of String or TargetElement Yes 应切换可见性的元素的列表。The list of elements that should have their visibility toggled. targetElements 数组元素指定为字符串时,它们必须代表卡片中的一个元素的 Id;执行操作时,如果这些元素本身不可见,也会变得可见,否则不可见。When elements of the targetElements array are specified as strings, they must represent the Id of an element in the card; when the action is executed, these elements become visible if they were not, and invisible otherwise. 数组元素被指定为 TargetElement 对象时,每个目标元素的可见性由 TargetElement 对象的 isVisible 属性定义。When elements of the array are specified as TargetElement objects, the visibility of each targeted element is defined by the isVisible property of the TargetElement object.

TargetElementTargetElement

属性名称Property name 类型Type 必需Required 说明Description
elementId 字符串String Yes 目标元素的 ID。The Id of the target element.
isVisible BooleanBoolean Yes 指定完成该操作后目标元素是否可见。Specifies whether the target element should be visible once the action has completed.

Action.ToggleVisibility 示例Action.ToggleVisibility example

{
  "type": "AdaptiveCard",
  "version": "1.0",
  "body": [
    {
      "type": "TextBlock",
      "text": "**Action.ToggleVisibility example**: click the button to show or hide a welcome message"
    },
    {
      "type": "TextBlock",
      "id": "helloWorld",
      "isVisible": false,
      "text": "**Hello World!**",
      "size": "extraLarge"
    }
  ],
  "actions": [
    {
      "type": "Action.ToggleVisibility",
      "title": "Click me!",
      "targetElements": [ "helloWorld" ]
    }
  ]
}

单击按钮之前会呈现类似如下示例卡片:The example card renders similar to the following before the button is clicked:

折叠状态的 Action.ToggleVisibility 示例卡片屏幕截图

单击按钮之后会呈现类似如下示例卡片:The example card renders similar to the following after the button is clicked:

展开状态的 Action.ToggleVisibility 示例卡片屏幕截图

ActionSet 元素ActionSet element

Outlook 可操作邮件增加了对 ActionSet 元素的支持,可实现在卡片的任意位置添加操作按钮。Outlook Actionable Messages add support for the ActionSet element that makes it possible to add action buttons anywhere in a card.

属性名称Property name 类型Type 必需Required 说明Description
type 字符串String Yes 必须设置为 ActionSetMust be set to ActionSet.
id 字符串String No 元素的唯一 ID。The unique ID of the element.
spacing 字符串String No 控制此元素与上一元素之间的间距。Controls the amount of spacing between this element and the previous element.
separator BooleanBoolean No 控制此元素和上一元素之间是否应显示分隔线。Controls whether or not a separator line should be displayed between this element and the previous element. 分隔线显示在 spacing 属性定义的空白区域中间。The separator line is displayed in the middle of the space defined by the spacing property.
horizontalAlignment 字符串String No 控制此元素在其容器内的水平对齐方式。Controls the horizontal alignment of this element within its container.
actions Action 对象数组Array of Action objects No 要在集中显示的操作。The actions to be displayed in the set.

ActionSet 可放置在卡片中任意位置这一点外,它与 AdaptiveCard 的操作属性完全相同。Aside from the fact that ActionSet can be placed anywhere in the card, it behaves exactly like the actions property of an AdaptiveCard.

ActionSet 示例ActionSet example

{
  "type": "AdaptiveCard",
  "version": "1.0",
  "body": [
      {
        "type": "ActionSet",
        "actions": [
          {
            "type": "Action.ToggleVisibility",
            "title": "Click me!",
            "targetElements": [ "helloWorld" ]
          }
        ]
      },
      {
        "type": "TextBlock",
        "text": "**Action.ToggleVisibility example**: click the button above to show or hide a welcome message"
      },
      {
        "type": "TextBlock",
        "id": "helloWorld",
        "isVisible": false,
        "text": "**Hello World!**",
        "size": "extraLarge"
      }
  ]
}

ActionSet 示例卡片的屏幕截图

所有自适应卡片元素类型的其他属性Additional properties on all Adaptive Card element types

属性名称Property name 类型Type 必需Required 说明Description
isVisible BooleanBoolean 否。No. 默认值为 trueDefaults to true. 元素的初始可见性状态。The initial visibility state of the element. isVisible 设置为 false 时,元素最初在卡片中是不可见的。When isVisible is set to false, the element is initially not visible in the card. 使用 Action.ToggleVisibility 操作可使其变为可见状态,如上文所述。It can be made visible using an Action.ToggleVisibility action, as documented above.

请参阅前述示例,了解如何使用 isVisiblePlease refer to the previous example for an illustration of how to use isVisible.

自适应卡片类型的其他属性Additional properties on the AdaptiveCard type

可以在 Outlook 可操作邮件上下文中的自适应卡片对象上指定以下附加属性:The following additional properties can be specified on an AdaptiveCard object in the context of Outlook Actionable Messages:

属性名称Property name 类型Type 必需Required DescriptionDescription
autoInvokeAction Action.HttpAction.Http No autoInvokeAction 属性指定一个 URL,该 URL 提供更新后的自适应卡负载以替换邮件中的现有负载。The autoInvokeAction property specifies a URL that supplies an updated Adaptive Card payload to replace the existing payload in the message. Action.Http 操作的 method 必须是 POSTThe method of the Action.Http action MUST be POST. 这将允许服务在可操作的消息中提供最新信息。This allows your service to supply up-to-date information in the actionable message. 有关详细信息,请参阅用户打开时刷新可操作的消息For more information, see Refresh an actionable message when the user opens it.
correlationId 字符串String No correlationId 属性简化了出于问题排查目的而查找日志的过程。The correlationId property simplifies the process of locating logs for troubleshooting issues. 建议在发送可操作卡片时,服务应设置并记录此属性中的唯一 UUID。We recommend that when sending an actionable card, your service should set and log a unique UUID in this property. 当用户在卡片上调用 Action.Http 操作时,Office 365 会将 POST 请求中的 Card-Correlation-IdAction-Request-Id 标头发送给你的服务。When the user invokes an Action.Http action on the card, Office 365 sends the Card-Correlation-Id and Action-Request-Id headers in the POST request to your service. Card-Correlation-Id 的值与卡片中的 correlationId 属性值相同。Card-Correlation-Id contains the same value as the correlationId property in the card. Action-Request-Id 是 Office 365 生成的唯一 UUID,有助于查找用户执行的特定操作。Action-Request-Id is a unique UUID generated by Office 365 to help locate specific action performed by a user. 收到操作 POST 请求时,服务应同时记录这两个值。Your service should log both of these values when receiving action POST requests.
expectedActors 字符串数组Array of String No expectedActors 包含可能对卡片采取 Action.Http 操作的预期用户电子邮件地址的列表。expectedActors contains a list of expected email addresses of the users that may take Action.Http actions on the card. 用户可以拥有多个电子邮件地址且 Action.Http 目标端点可能不想要 sub 持有者令牌声明中显示的特定电子邮件地址。A user can have multiple email addresses and the Action.Http target endpoint might not be expecting the particular email address presented in the sub claim of the bearer token. 例如,某个用户可能同时有 john.doe@contoso.comjohn@contoso.com 电子邮件地址,但目标端点希望接收次级持有者令牌的 john@contoso.com 声明中的 Action.HttpFor example, a user could have both the john.doe@contoso.com or john@contoso.com email address, but the Action.Http target endpoint expects to receive john@contoso.com in the sub claim of the bearer token. 通过将 expectedActors 属性设置为 ["john@contoso.com"]sub 声明将拥有预期的电子邮件地址。By setting the expectedActors property to ["john@contoso.com"], the sub claim will have the expected email address.
hideOriginalBody BooleanBoolean 否。No. 默认值为 falseDefaults to false. 设置为 true 时,将隐藏邮件的 HTML 正文。When set to true, causes the HTML body of the message to be hidden. 当卡片是比 HTML 正文本身更好或更有用的内容表示形式,尤其是在卡片包含操作时,上述设置会非常有用。This is very useful in scenarios where the card is a better or more useful representation of the content than the HTML body itself, which is especially true when the card contains actions. 如果卡片本身包含用户需要读取的所有信息或者卡片内容含有包含了正文内容的冗余内容,请考虑 隐藏原始 HTML 正文。Consider hiding the original HTML body if the card itself contains all the information a user would need, or if the content of the card is redundant with the content of the body. 务必始终要包含一个良好的有实质内容的 HTML 正文,即使会将其隐藏。Do always include a nice, meaningful HTML body, even if it is going to be hidden. HTML 正文是不支持卡片的电子邮件客户端可以显示的唯一内容。The HTML body is the only thing an email client that doesn't support cards will be able to display. 此外,回复或转发电子邮件时不包含卡片,仅包含 HTML 正文。Furthermore, cards are not included when replying to or forwarding emails, only the HTML body. 当正文与卡片显示的信息相互补充时,请勿 隐藏正文。Don't hide the body when it is complementary to the information presented in the card. 例如,零用金报销单审批正文可能会详细说明报销单,而卡片仅显示简短摘要和批准/拒绝操作。For example, the body of an expense report approval might describe the report in great details while the card just presents a quick summary along with approve/decline actions.
originator 字符串String Yes 对于可操作电子邮件,必须设置为可操作电子邮件开发者仪表板生成的提供程序 ID。For actionable email, MUST be set to the provider ID generated by the Actionable Email Developer Dashboard.

列类型的其他属性Additional properties on the Column type

可以在 Outlook 可操作邮件上下文中列对象 中指定以下附加属性:The following additional properties can be specified on a Column object in the context of Outlook Actionable Messages:

属性名称Property name 类型Type 必需Required 说明Description
width 数字或字符串Number or String 否(默认为 autoNo (defaults to auto) 此属性可将 Column 宽度精准控制在 ColumnSet 内。This property allows for precise control of the width of a Column within its ColumnSet. 请参阅列宽值,了解详细信息。See Column width values for details.
verticalContentAlignment 字符串。String. 有效值为 topcenterbottomValid values are top, center and bottom. 否(默认为 top)。No. Defaults to top. 使用 verticalContentAlignment 属性,可垂直排列列中的内容(例如其中所有元素)。这对于类似表格的布局十分有用。The verticalContentAlignment property makes it possible to vertically position the content of the column (e.g. all its elements.) This is particularly useful for table-like layouts.
backgroundImage 字符串String No backgroundImage 属性表示将用作 Column 的背景的图像的 URL。The backgroundImage property represents the URL to an image that is to be used as the background of the Column. 背景图像覆盖全部 Column 表面,并按比例缩放以保留其原始纵横比。The background image covers the entirety of the Column's surface and is scaled so as to preserve its original aspect ratio.

列宽值Column width values

如果 width 为数字,则代表 Column 的相对宽度(ColumnSet 内)。If width is expressed as a number, it represents the relative weight of the Column within its ColumnSet. 为了让加权 Column 实际发挥作用,集中应至少再具有一个加权 ColumnFor a weighted Column to really be useful, there should be at least one more weighted Column in the set. 例如,如果列 A 将 width 设置为 1,列 B 将 width 设置为 2,则列 A 将使用集中三分之一可用空间,而列 B 将使用其余的三分之二空间。For example, if column A has its width set to 1 and column B has its width set to 2, then column A will use a third of the available space in the set, while column B will use the remaining two-thirds.

如果 width 为字符串,可具有以下值:If width is expressed as a string, it can have the following values:

  • autoColumn 将尽可能使用其内容所需的空间量。auto: The Column will use as much of the available space as is required to fit its content.
  • stretchColumn 将使用集中剩余的全部空间。stretch: The Column will use whatever space remains in the set. 如果多个列将 width 属性设置为 stretch,则它们会平均分享剩余空间。If multiple columns have their width property set to stretch, they all share the remaining space equally.
  • <number>px(例如<number>px (ex. 50px):列将分布于指定数目的像素。50px): The column will spread across the specified number of pixels.
  • <number>*,(例如<number>*, (ex. 1*):这相当于将 width 指定为数字。1*): This is equivalent to specifying width as a number.

列示例Column example

{
  "$schema": "https://adaptivecards.io/schemas/adaptive-card.json",
  "type": "AdaptiveCard",
  "version": "1.0",
  "body": [
    {
      "type": "ColumnSet",
      "columns": [
        {
          "width": "50px",
          "items": [
            {
              "type": "Image",
              "url": "https://adaptivecards.io/content/cats/1.png",
              "size": "stretch"
            }
          ]
        },
        {
          "width": "stretch",
          "verticalContentAlignment": "center",
          "items": [
            {
              "type": "TextBlock",
              "text": "This card has two ColumnSets on top of each other. In each, the left column is explicitly sized to be 50 pixels wide.",
              "wrap": true
            }
          ]
        }
      ]
    },
    {
      "type": "ColumnSet",
      "columns": [
        {
          "width": "50px"
        },
        {
          "width": "stretch",
          "verticalContentAlignment": "center",
          "items": [
            {
              "type": "TextBlock",
              "text": "In this second ColumnSet, columns align perfectly even though there is nothing in the left column.",
              "wrap": true
            }
          ]
        }
      ]
    }
  ]
}

宽度示例卡片的屏幕截图

容器类型的其他属性Additional properties on the Container type

可以在 Outlook 可操作邮件上下文中容器对象中指定以下附加属性:The following additional properties can be specified on a Container object in the context of Outlook Actionable Messages:

属性名称Property name 类型Type 必需Required 说明Description
verticalContentAlignment 字符串。String. 有效值为 topcenterbottomValid values are top, center and bottom. 否(默认为 top)。No. Defaults to top. 使用 verticalContentAlignment 属性,可垂直排列列中的内容(例如其中所有元素)。这对于类似表格的布局十分有用。The verticalContentAlignment property makes it possible to vertically position the content of the column (e.g. all its elements.) This is particularly useful for table-like layouts.
backgroundImage 字符串String No backgroundImage 属性表示将用作 Container 的背景的图像的 URL。The backgroundImage property represents the URL to an image that is to be used as the background of the Container. 背景图像覆盖全部 Container 表面,并按比例缩放以保留其原始纵横比。The background image covers the entirety of the Container's surface and is scaled so as to preserve its original aspect ratio.

这些属性的行为与其在 Column 类型上的对应项完全一致。These properties behave exactly like their counterpart on the Column type. 请参阅上面的示例。Please refer to the above example.

图像类型的其他属性Additional properties on the Image type

可以在 Outlook 可操作邮件上下文中图像对象中指定以下附加属性:The following additional properties can be specified on an Image object in the context of Outlook Actionable Messages:

属性名称Property name 类型Type 必需Required 说明Description
width 字符串String No 此属性允许对图像宽度进行精度控制(以像素为单位)。This property allows for precise control over the width of an image, in pixels. 允许的格式为 <number>px,其中 <number> 是整数。The allowed format is <number>px where <number> is an integer. 指定了 width 时,size 属性将被忽略。When width is specified, the size property is ignored. 如果指定了 width 但未指定 height,则图像的高度按照其纵横比自动计算。If width is specified but height isn't, the height of the image is automatically computed so as to respect its aspect ratio.
height 字符串String No 此属性允许对图像高度进行精度控制(以像素为单位)。This property allows for precise control over the height of an image, in pixels. 允许的格式为 <number>px,其中 <number> 是整数。The allowed format is <number>px where <number> is an integer. 指定了 height 时,size 属性将被忽略。When height is specified, the size property is ignored. 如果指定了 height 但未指定 width,则图像的宽度按照其纵横比自动计算。If height is specified but width isn't, the width of the image is automatically computed so as to respect its aspect ratio.
backgroundColor 字符串String No backgroundColor 属性指定顶部呈现的图像的颜色。The backgroundColor property specifies the color the image should be rendered on top of. 当需要在各种不同背景颜色中使用单个图像时,backgroundColor 尤其有用,因为不需要再精心制作单个图像的多个版本。backgroundColor is particularly useful in cases where a single image should be used on top of a variety of background colors, as it removes the need to craft multiple versions of a single image. backgroundColor 属性的格式为 #RRGGBB,其中 RRGGBB 分别是该颜色的红、绿和蓝成分的十六进制值。The format of the backgroundColor property is #RRGGBB where RR, GG and BB are the hexadecimal values of the red, green and blue components of the color, respectively.

图像属性示例Image properties example

{
  "$schema": "https://adaptivecards.io/schemas/adaptive-card.json",
  "type": "AdaptiveCard",
  "version": "1.0",
  "body": [
    {
      "type": "TextBlock",
      "text": "Below, the same image is presented on top of two different background colors."
    },
    {
      "type": "Image",
      "width": "64px",
      "url": "https://messagecardplayground.azurewebsites.net/assets/circleontransparentbackground.png",
      "backgroundColor": "#FF0000"
    },
    {
      "type": "Image",
      "style": "person",
      "width": "64px",
      "url": "https://messagecardplayground.azurewebsites.net/assets/circleontransparentbackground.png",
      "backgroundColor": "#0000FF"
    }
  ]
}

图像属性示例卡片的屏幕截图

另请参阅See also