34 Microsoft Teams

When you set up a Microsoft Teams channel, users can chat with your digital assistant (or a standalone skill) through the Microsoft Teams user interface.

Here's the process for setting up a channel:

  1. In Microsoft Teams, use App Studio to create an app and add a bot to that app. (Alternatively, you can use the Microsoft Bot Framework or the Microsoft Azure Bot Service to create a bot registration.)
  2. Using the app ID and password from the bot, create a channel in Digital Assistant .
  3. Copy the webhook URL that is generated when you create the channel and add it to the bot.
  4. Test your digital assistant in Microsoft Teams.

Step 1: Create a Bot

To make your digital assistant (or standalone skill) available in Microsoft Teams, you need to create a Microsoft bot in one of the following three ways:

  • Directly in Microsoft Teams, using App Studio.
  • Through Azure Bot Service, which requires having a Microsoft Azure account. See Azure Bot Channels Registration for the setup details.
  • Through Microsoft Bot Framework, which requires having an Office 365 account at a level of E1 or higher. See Bot Framework Channels Registration for the setup details.

The first of these options (using App Studio in Microsoft Teams) is the most straightforward.

App Studio Channels Registration

To set up a bot channel registration through App Studio, you create the following:

  • A Microsoft Teams app. This app is the container for the bot that you create and is how you access the bot in Teams.
  • A bot. This is the artifact within the app that communicates with Oracle Digital Assistant

Here are the steps:

  1. Go to https://teams.microsoft.com and log in with your Microsoft account.

  2. In the left navigation, click the App Studio icon.

    If the App Studio icon isn't shown, do the following to add it:

    1. In the left navigation of the service, click the Search field and then search for and select App Studio.

    2. Click the Add button.

      The icon for App Studio should appear in the left navigation.

  3. In App Studio, select the Manifest Editor tab.

  4. Click the Create a new app button.

  5. On the App details page, fill in the Short Name field with the name you want to use for the app as it will appear in Microsoft Teams. (This app will encapsulate the bot, which you will create later.)

  6. Under Identification, click Generate to create an app ID.

  7. Fill in the Package Name and Version fields.

  8. Fill in the remaining required fields.

  9. In the left navigation of the page, under the Capabilities section, select Bots.

  10. Click Set up.

  11. On the Set up a bot page, with the New bot tab selected, do the following:

    1. Enter a name for the bot.
    2. Optionally, select My bot supports uploading and downloading of files.
    3. Select the Personal scope.
    4. Click Create bot.

    Once the bot is created, a tile will appear at the top of the page with the bot name and a generated ID below it.

  12. Copy the ID and save it in a text file.

    You'll need this ID when you create the channel in Digital Assistant.

  13. Click Generate new password.

  14. Copy the password and save it in the text file where you saved the ID.

  15. In the left navigation of the page, under the Finish section, select Domains and permissions.

  16. Under Valid domains add any domains that the bot's users may be coming from.

  17. Leave App Studio open in your browser.

    You'll later complete the registration with a webhook URL that you get when you create the channel in Digital Assistant.

Now skip ahead to Step 2: Create a Channel in Digital Assistant.

Azure Bot Channels Registration

To create a bot channel registration through Azure:

  1. Go to https://portal.azure.com/ and log in with your Microsoft account.

  2. In the Search field, search for and select Bot Channels Registration.



  3. On the Bot Channels Registration page, fill in the Bot handle field with the name you want to use when accessing your digital assistant through Microsoft Teams.

  4. Fill in the rest of the required fields.

  5. Scroll down to the Microsoft App ID and password section, expand it, and click Create New.

    A new browser tab will open, and you will be redirected to the Azure portal's App registrations blade.

  6. Click New Registration.

  7. In the Supported account types section, select the Accounts in any organizational directory (Any Azure AD directory - Multitenant) and personal Microsoft accounts (e.g. Skype, Xbox) radio button.

  8. Fill in the rest of the required fields and click Register.

    In a few moments, the app registration should be completed.

  9. In the Overview blade, copy the value of the Application (client) ID and save it to a safe place on your system.

  10. Select the Certificates and Secrets blade.

  11. Click + New Client Secret, fill in a description, select when it should expire, and click Add.

  12. Copy the client secret and save it in a safe place on your system.

  13. Leave the Azure Portal open in your browser.

    You'll later complete the registration with a webhook URL that you get when you create the channel in Digital Assistant.

Now skip ahead to Step 2: Create a Channel in Digital Assistant.

Bot Framework Channels Registration

To create the registration through the Microsoft Bot Framework:

  1. Go to https://dev.botframework.com/bots/new and log in with an Office 365 user account. The account must be part of an E1 plan or higher.

  2. Upload an icon to represent your digital assistant in Microsoft Teams.

  3. Fill in the Display name, Bot handle, and Long description fields.

    Note:

    The bot handle is unique across all global metadata, so you'll probably want incorporate both the digital assistant name and the Microsoft Teams tenant in the value.
  4. Don’t enable the Streaming Endpoint checkbox.

  5. Click Create Microsoft App ID and password.

    A new browser tab will open, and you will be redirected to the Azure portal's App registrations blade.

    Note:

    Though you generate the app ID through Azure, the bot registration itself is still managed through the Microsoft Bot Framework.
  6. Click New Registration.

  7. In the Supported account types section, select the Accounts in any organizational directory (Any Azure AD directory - Multitenant) and personal Microsoft accounts (e.g. Skype, Xbox) radio button.

  8. Fill in the rest of the required fields and click Register.

    In a few moments, the app registration should be completed.

  9. In the Overview blade, copy the value of the Application (client) ID and save it to a safe place on your system.

  10. Select the Certificates and Secrets blade.

  11. Click + New Client Secret, fill in a description, select when it should expire, and click Add.

  12. Copy the client secret and save it in a safe place on your system.

  13. Return to the previous browser tab.
  14. In the Microsoft App ID from the Microsoft App registration portal field, paste the application ID that you copied from the app registration.
  15. Leave the Bot Framework page open in your browser.

    You'll later complete the registration with a webhook URL that you get when you create the channel in Digital Assistant.

Step 2: Create a Channel in Digital Assistant

  1. In a separate browser window or tab, open Digital Assistant, click Channels in the left menu, and choose Users.

  2. Click + Channel to open the Create Channel dialog.

  3. Give your channel a name.

  4. Choose Microsoft Teams as the channel type.

  5. Fill in Microsoft Application Id with the ID of the bot that you created in App Studio.

    Note:

    If you created your bot through Azure or the Microsoft Bot Framework portal, use the Microsoft App ID that you obtained through your bot registration.
  6. Fill in Microsoft Application Password with the password or client secret that was generated for the bot.

  7. Click Create.

  8. In the Channels page, copy the WebHook URL and paste it somewhere convenient on your system.

  9. Click icon for the Route To ... dropdown and select the digital assistant or skill that you want to associate with the channel.

  10. Switch on the Channel Enabled control.

Step 3: Configure the Webhook URL for Microsoft Teams

Now you need to circle back and complete the configuration in Microsoft Teams.

  • If you set up the bot with App Studio:

    1. In the browser tab where you have set up your bot registration, scroll to the Messaging endpoint section of the page and paste the webhook URL that you obtained when creating the channel in Digital Assistant into the Bot endpoint address field.

    2. In the left navigation, select Test and distribute.

    3. Click the Install button.

      Note:

      Later on, once your app is tested and ready for distribution, you'll go back to this page and click Download.
    4. Click Add.

  • If you registered the bot with Azure:

    1. In the browser tab where you have set up your bot registration, use the Search field to navigate back your bot registration.

    2. In the left navigation bar, select Settings.

    3. In the Messaging endpoint field, paste the webhook URL that you obtained when creating the channel in Digital Assistant.

    4. Within Bot Service in the left navigation bar, scroll down to the Bot Management section and click Channels.

    5. Click the icon for Microsoft Teams and then click Save.

  • If you have registered the bot with the Microsoft Bot Framework:

    1. In the Messaging endpoint field, paste the webhook URL that you obtained when creating the channel in Digital Assistant.

    2. Don’t enable analytics.

    3. Check the Agree box, and click Register.

    4. Select the bot you just registered.

    5. Within the Channels tab, click the icon for Microsoft Teams to add Microsoft Teams as a channel.

    6. Click Save to exit the Configure Microsoft Teams dialog.

Step 4: Enable Apps in Your Office 365 Tenant

You next need to have your Office 365 administrator configure your tenant to:

  • Allow external apps in Microsoft Teams.
  • Allow sideloading of external apps.
  • Enable new external apps by default.

For the concrete steps, see https://docs.microsoft.com/en-us/microsoftteams/platform/concepts/build-and-test/prepare-your-o365-tenant.

Step 5: Test in Microsoft Teams

With the Microsoft Teams channel and messaging configuration complete, you can test your digital assistant (or skill) in Microsoft Teams.

  • If you created the app with App Studio, an icon for the app should appear in the left navigation of Microsoft Teams. You can click this icon and then start the conversation by typing in the Type your questions here field.
  • If you created the app through Azure or the Microsoft Bot Framework:
    1. Open Microsoft Teams and select the Chat window.

    2. Select the bot channel and start communicating in the message field.

      If you don't see an entry for the bot channel, you can paste the Microsoft App Id of your bot channel registration in the To section of the Chat screen. For further details see https://docs.microsoft.com/en-us/microsoftteams/platform/concepts/bots/bots-test#adding-a-bot-for-personal-chat.

Supported Capabilities

Microsoft Teams channels in Digital Assistant support the following capabilities:

  • text (both sending and receiving)
  • images (both sending and receiving)
  • files (both sending and receiving)
  • emojis (both sending and receiving)
  • links
  • postbacks
  • custom properties
  • carousel components
  • list components

Message Constraints

Microsoft Teams channels in Digital Assistant have the following message constraints:

  • Text Messages
    • Maximum length of text action label: 1 line (about 50 characters)
    • Types of text actions allowed: Postback, Call, URL
  • Horizontal Cards
    • Maximum length of title: 2 lines (about 80 characters)
    • Maximum length of description: 25,000 characters
    • Maximum length of card action label: 1 line (about 50 characters)
    • Maximum number of cards: 10
    • Maximum number of card actions: 6. If the number of card actions exceeds 6, the card is duplicated to render remaining card actions.
    • Minimum number of card actions: 0
    • Maximum number of card list actions: 6
    • At least one description, image or action required?: No
    • Types of card actions allowed: Postback, Call, URL
    • Types of card list actions allowed: Postback, Call,URL
  • Vertical Cards
    • Maximum length of title: 2 lines (about 80 characters)
    • Maximum length of description: 25,000 characters
    • Maximum length of card action label: 1 line (about 50 characters)
    • Maximum number of cards: 10
    • Maximum number of card actions: 3
    • Minimum number of card actions: 0
    • Maximum number of card list actions: 6
    • At least one description, image or action required?: No
    • Types of card actions allowed: Postback, Call, URL
    • Types of card list actions allowed: Postback, Call, URL
  • Attachment Messages
    • Supported?: Yes
    • Types of actions allowed: Postback, Call, URL
  • Action Buttons
    • Maximum length of global action label: 1 line (about 50 characters)
    • Maximum number of global actions: 6
    • Types of global actions allowed: Postback, Call, URL

Adaptive Cards in Microsoft Teams

For skills that you expose through Microsoft Teams channels in Oracle Digital Assistant, you can use Adaptive Cards.

Note:

Adaptive Cards are not supported in Oracle Digital Assistant version 19.4.1 or earlier.

To do so, you use the channelCustomProperties element in a System.CommonResponse component and set the type property to "AdaptiveCard".

You can use this element at the following levels in the System.CommonResponse component:

  • At the level of a card element within a cards response item. This allows you to define a single adaptive card structure that will be stamped out multiple times when an iteratorVariable has been specified for the card element.
  • At the level of a text response item, typically to create a single adaptive card. ( Multiple cards can be defined but the iteratorVariable property is not supported here.)

Note:

Microsoft Teams currently does not support a carousel with adaptive cards. In System.CustomResponse component metadata terms, this means that the card layout property is ignored. The cards will always be laid out vertically because horizontal layout (carousel) is simply not supported.

A second limitation to be aware of is that when a user taps on a button that is included with the adaptive card, the button label will not be printed out as user message in the conversation history. In other words, the user does not get a visual confirmation of which button she selected. This can lead to an inconsistent user experience, because buttons displayed with simple text messages, or buttons displayed with standard System.CustomResponse component cards (using the Microsoft Hero card) do print out the button label.

Example: Adaptive Card in Cards Response Item

To stamp out multiple cards, you can use the iteratorVariable with the card element within a response item of type cards. Here is an example to use an adaptive card to stamp out multiple pizza cards:

responseItems:
  - type: "cards"
    headerText: "Here are our pizzas you can order today:"
    cardLayout: "horizontal"
    cards:
      - title: "${pizzas.name}"
        description: "${pizzas.description}"
        imageUrl: "${pizzas.image}"
        iteratorVariable: "pizzas"
        actions:
          - label: "Order Now"
            type: "postback"
            payload:
              action: "order"
              variables:
                orderedPizza: "${pizzas.name}"
                orderedPizzaImage: "${pizzas.image}"
        channelCustomProperties:
        - channel: "msteams"
          properties:
            adaptiveCard:
              type: "AdaptiveCard"
              version: "1.0"
              fallbackText: "Adaptive card version not supported"
              body:
              - type: "TextBlock"
                text: "${pizzas.name}"
                weight: "bolder"
              - type: "TextBlock"
                text: "${pizzas.description}"
                wrap: true
              - type: "Image"
                url: "${pizzas.image}"
                horizontalAlignment: "center"
              actions:
              - type: "Action.Submit"
                title: "Order"
                data: 
                  action: "order" 
                  variables:
                    orderedPizza: "${pizzas.name}"
                    orderedPizzaImage: "${pizzas.image}"

Example: Adaptive Card in Text Response Item

You can define an adaptive card with a text response item as follows:

responseItems:
  - type: "text"
    text: "This text is replaced with adaptive card defined in custom property"
    footerText: "Is that correct?"
    visible:
      expression: "${system.channelType=='msteams' && system.entityToResolve.value.name=='Confirmed'}"
    channelCustomProperties:
      - channel: "msteams"
        properties:
          adaptiveCard:
            type: "AdaptiveCard"
            version: '1.0'          
            fallbackText: "Adaptive card version not supported"                                             
            body:
            - type: TextBlock
              text: 'I have all information needed to create your expense. Just to verify my understanding, here is an overview of your expense:'
              wrap: true
            - type: FactSet
              facts:
              - title: Expense Type
                value: "${expense.value.Type}"
              - title: Amount
                value: "${expense.value.Amount.totalCurrency}"
              - title: Date
                value: "${expense.value.Date.date?number_to_date}"
              - title: Receipt URL
                value: "${expense.value.Receipt?has_content?then(expense.value.Receipt.url,'N/A')}"
 
            actions:
            - type: Action.ShowCard
              title: Edit
              id: edit
              card:
                type: AdaptiveCard             
                version: '1.0'
                body:
                - type: TextBlock
                  size: Medium
                  weight: Bolder
                  text: Edit Expense
                - type: TextBlock
                  text: Expense Type
                  weight: Bolder
                - type: Input.ChoiceSet
                  choices:
                  - title: Metro, bus, train
                    value: Public transport
                  - title: Taxi
                    value: Taxi
                  - title: Breakfast, lunch, dinner
                    value: dinner
                  id: Type
                  value: "${expense.value.Type!''}"
                  spacing: None
                - type: TextBlock
                  text: Amount
                  weight: Bolder
                - type: Input.Text
                  id: amount
                  spacing: None
                  value: "${expense.value.Amount?has_content?then(expense.value.Amount.totalCurrency,'')}"
                - type: TextBlock
                  text: Date
                  weight: Bolder
                - type: Input.Date
                  id: Date
                  value: "${expense.value.Date?has_content?then(expense.value.Date.date?number_to_date,'')}"
                  spacing: None
                actions:
                - type: Action.Submit
                  title: Submit
                  id: submit

You can also define multiple adaptive cards in this custom property. To do so, you prefix the type property with a hypen (-) to indicate a YAML list rather than a map:

channelCustomProperties:
  - channel: "msteams"
    properties:
      adaptiveCard:
      - type: AdaptiveCard
        body: ...
      - type: AdaptiveCard
        body: ...

This can be convenient if you need to stamp out multiple static cards, but it will be more common to stamp out multiple cards using the iteratorVariable property.

Submit Actions

Adaptive Cards has a submit action (Action.Submit), which you can use to gather user input and send it to the skill.

You define the action's payload in the data property of the submit action. If you want the System.CommonResponse component to transition after the button is selected or set some variables, you can use the standard action and variables properties:

actions:
- type: "Action.Submit"
  title: "Order"
  data: 
    action: "order" 
    variables:
      orderedPizza: "${pizzas.name}"
      orderedPizzaImage: "${pizzas.image}"

If you're using input fields in your card, the name and value of these fields will be added as key-value pairs to the data JSON object. The example above with the Edit Expense card includes three fields to modify the expense type, amount, and date. When the user taps the Submit button in this case, a JSON object like the following will be sent:

{
  "Type" : "Taxi",
  "Amount" : "10.0 dollar"
  "Date" : "2019-09-02"
}

The System.CommonResponse component doesn't know how to process this information, as it does not follow the common payload structure with action and variables properties. To solve this, you have these options:

  • Convert the JSON payload to a string, which will then be matched for entities. If any matches are found, the variable set with the System.CommonResponse component will be updated with the corresponding entity value or entity values (in case of a composite bag entity).

    To configure this option, you add the boolean system.convertToString property to the data property of the submit action:

    actions:
    - type: Action.Submit
      title: Submit
      id: submit                   
      data:
        system.convertToString: true
  • Have the skill update variables with the same name as the input fields. In the above example, the "Type", "Amount" and "Date" context variables would be updated.

    To configure this option, you add the boolean system.setVariables property to the data property of the submit action:

    actions:
    - type: Action.Submit
      title: Submit
      id: submit                   
      data:
        system.setVariables: true

If you don't configure any of these options, the submitted values will simply be ignored.

When using a System.CommonResponse component with a composite bag entity, you will typically use the first option, which will populate all the matched entities in the bag based on the stringified JSON payload.

Note:

You need to set the System.CommonResponse component processUserMessage property to true for these submit actions to work.

Echo Text of Selected Button in Adaptive Card

When a user selects a button in an Adaptive Card, the conversation isn't updated to show that the user selected that option unless you include a messageBack action for the card.

To set up a messageBack action, see https://docs.microsoft.com/en-us/microsoftteams/platform/task-modules-and-cards/cards/cards-actions#adaptive-cards-with-messageback-action.

Tips for Creating Adaptive Cards Definitions

The adaptive cards JSON schema is relatively complex with many different constructs supported. As such, it is error prone when you try to define the adaptive card content by hand directly inside the System.CommonResponse component. You may find it easier to use the following process to create the adaptive cards:

  1. With the visual tools in Microsoft's Adaptive Cards Designer, create the adaptive card definition.
  2. Click Copy Card JSON to get the definition in JSON format.
  3. Use an online JSON-to-YAML converter to convert the definition to YAML.
  4. Copy the result into a text editor and insert the indentation that is required for where it will appear in the the dialog flow definition.
  5. Paste the resulting text into the dialog flow.

Note:

As of September 2019, Microsoft Teams only supports adaptive cards version 1.0. See https://adaptivecards.io/explorer/ for list of all elements and properties and the version they were introduced.

Also, the adaptive card designer does not check on the combination of the elements used and the version number of adaptive cards. For example, the ActionSet element was introduced in version 1.2, but the designer doesn't present you from adding this element, even if you have specified 1.0 as the version number in the designer.

If you want to use actions with 1.0, you can use the separate actions property below the body property. This actions element can't be added using the visual designer, so you'd need to do it by hand.