microsoft / BotFramework-Services

Microsoft Bot Framework Services
Creative Commons Attribution 4.0 International
38 stars 11 forks source link

Bot Connector service is not using latest Adaptive Cards #87

Closed v-kydela closed 4 years ago

v-kydela commented 5 years ago

[Edit by corinagum]:

Conclusion: Bot Connector service needs to be updated with latest Adaptive Cards

Screenshots

MicrosoftTeams-image

MicrosoftTeams-image (1)

Version

<script src="https://cdn.botframework.com/botframework-webchat/master/webchat.js"></script>

Describe the bug

Adaptive Cards 1.1 introduced media elements. Web Chat supports Adaptive Cards 1.1 but doesn't render those elements. However, Emulator uses Web Chat and does render them. This is impacting at least one customer: https://stackoverflow.com/a/56177322/2122672

To Reproduce

Steps to reproduce the behavior:

  1. Build a bot that sends an Adaptive Card with a media element
  2. Observe that the media is displayed correctly in Emulator
  3. Observe that the media is not displayed in Web Chat

Expected behavior

Any channel that supports Adaptive Cards 1.1 should render media elements

Additional context

Example card:

{
  "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
  "version": "1.1",
  "type": "AdaptiveCard",
  "body": [
    {
      "type": "TextBlock",
      "text": "Sample"
    },
    {
      "type": "Media",
      "poster": "https://adaptivecards.io/content/poster-video.png",
      "sources": [
        {
          "mimeType": "video/mp4",
          "url": "https://adaptivecardsblob.blob.core.windows.net/assets/AdaptiveCardsOverviewVideo.mp4"
        }
      ]
    }
  ]
}

[Bug]

corinagum commented 5 years ago

Thanks @v-kydela.

We actually began investigations over Teams. Let me share what I was looking into. I still haven't found the cause of this discrepancy.

corinagum commented 5 years ago

looping in @tonyanziano

tonyanziano commented 5 years ago

@corinagum I looked through the Emulator code for handling attachments and I was unable to find any special logic for the rendering of video / media cards. Also, like you said, we are relying on Web Chat's default host config and do not pass a custom one in when rendering Web Chat.

corinagum commented 5 years ago

@tonyanziano thanks for the help

tdurnford commented 5 years ago

I'm having the same issue with videos in AdaptiveCards, but VideoCard attachments are working fine. @v-kydela Might be a viable solution to unblock the customer for the moment.

const card = CardFactory.videoCard(
    '2018 Imagine Cup World Championship Intro',
    [{ url: 'https://adaptivecardsblob.blob.core.windows.net/assets/AdaptiveCardsOverviewVideo.mp4' }],
    [{
        type: 'openUrl',
        title: 'Lean More',
        value: 'https://channel9.msdn.com/Events/Imagine-Cup/World-Finals-2018/2018-Imagine-Cup-World-Championship-Intro'
    }],
    {
        subtitle: 'by Microsoft',
        text: 'Microsoft\'s Imagine Cup has empowered student developers around the world to create and innovate on the world stage for the past 16 years. These innovations will shape how we live, work and play.'
    }
);

await turnContext.sendActivity({
    attachments: [card]
});

Also seems related to this Adaptive Cards issue https://github.com/microsoft/AdaptiveCards/issues/2272

v-kydela commented 5 years ago

Thank you @tdurnford

I did see that issue, but it looks like the discussion ended before Adaptive Cards 1.1 were ever supported in Web Chat

tdurnford commented 5 years ago

It looks like the media element is being stripped out of the Adaptive Card somewhere between the Bot and WebChat.

AdaptiveCard

{
  "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
  "version": "1.1",
  "type": "AdaptiveCard",
  "body": [
    {
      "type": "TextBlock",
      "text": "**AdaptiveCard with Video**"
    },
    {
      "type": "Media",
      "poster": "https://adaptivecards.io/content/poster-video.png",
      "sources": [
        {
          "mimeType": "video/mp4",
          "url": "https://adaptivecardsblob.blob.core.windows.net/assets/AdaptiveCardsOverviewVideo.mp4"
        }
      ]
    }
  ]
}

DirectLine

import { DirectLine } from 'botframework-directlinejs';

global.XMLHttpRequest = require('xhr2');
global.WebSocket = require('ws');

var directLine = new DirectLine({
    secret: '<WEBCHAT_SECRET>'
});

directLine.postActivity({
  from: { id: 'myUserId', name: 'myUserName' }, 
  type: 'message',
  text: 'start'
}).subscribe();

directLine.activity$
.filter(activity => activity.from.name !== 'myUserName' && activity.attachments)
.subscribe(
    ({ attachments: [{content}] }) => console.log("Card ", content)
);

Output

Card  {
  type: 'AdaptiveCard',
  version: '1.1',
  body: [ { type: 'TextBlock', text: '**AdaptiveCard with Video**' } ]
}

The Adaptive Card sent by the bot has a media element, but the attachment received and processed by DirectLineJs does not.

EricDahlvang commented 5 years ago

@tdurnford is correct. The WebChat and Direct Line connector service Adaptive Cards version is 1.0.6

WebChat is on version ~1.1.3 https://github.com/microsoft/BotFramework-WebChat/blob/master/packages/bundle/package.json#L36 and is able to render the card. Since the emulator is receiving messages directly, and not through the connector service: it can render these cards.

This issue should be moved to https://github.com/microsoft/BotFramework-Services/

v-kydela commented 5 years ago

Good catch @EricDahlvang. But why would the connector service even have an Adaptive Cards version if it's not responsible for rendering anything? Also, stripping out elements is useless because if the Adaptive Cards version is higher than the channel client supports, the card won't render even with the special elements removed.

tdurnford commented 5 years ago

The DirectLine connector service maps the incoming activities from JSON to C# Objects, and since the connector service uses AdaptiveCards v1.0.6 it is not able to map AdaptiveCards attributes from v1.1.0 or greater. As a result, it drops items/media in the card like videos. Right or wrong, the limiting factor for AdaptiveCards in Web Chat is the AdaptiveCards version in the connector service. Ideally, the connector service would leave attachments as JSON and let the client handle the attachment scheme.

tdurnford commented 5 years ago

As a temporary workaround, you can set the contentType of the attachment to a custom value as exemplified in the Customization Card Components Web Chat Sample and change the type back to an AdaptiveCard before Web Chat renders it. By changing the contentType, the DirectLine Connector Service treats the AdaptiveCard as JSON and does not map it to a C# Object. As a result, the card does not lose any of the elements that are only available in newer versions of AdaptiveCards. Adding an attachment middleware to Web Chat allows you to monitor for the custom attachment and change the type back to an AdaptiveCard. For more details, take a look at the code snippets below.

Bot - NodeJs SDK

Set the attachment contentType property to 'application/vnd.microsoft.card.custom' when sending the AdaptiveCard.

const card = CardFactory.adaptiveCard({
    "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
    "version": "1.1",
    "type": "AdaptiveCard",
    "body": [
      {
        "type": "TextBlock",
        "text": "AdaptiveCard with Video"
      },
      {
        "type": "Media",
        "poster": "https://adaptivecards.io/content/poster-video.png",
        "sources": [
          {
            "mimeType": "video/mp4",
            "url": "https://adaptivecardsblob.blob.core.windows.net/assets/AdaptiveCardsOverviewVideo.mp4"
          }
        ]
      }
    ]
  });
card.contentType = 'application/vnd.microsoft.card.custom';

await context.sendActivity({
  attachments: [card]
});

Web Chat Attachment Middleware

In the attachment middleware, change the custom contentType back to 'application/vnd.microsoft.card.adaptive'.

const attachmentMiddleware = () => next => card => {
  if (card.attachment.contentType === 'application/vnd.microsoft.card.custom'){
    card.attachment.contentType = 'application/vnd.microsoft.card.adaptive'
  }
  return next(card)
};

window.WebChat.renderWebChat({
  directLine,
  attachmentMiddleware
}, document.getElementById('webchat'));

Screenshot

image

This is not a long term solution to the issue, and still needs to be addressed in the connector service.

mathurvarun84 commented 5 years ago

We are also facing the same issue. Is the video card issue is fixed in web chat or do we need to go with an above workaround?

v-kydela commented 5 years ago

@mathurvarun84 - It is not fixed yet. Use the workaround.

mathurvarun84 commented 5 years ago

@corinagum we also faced the same issue. when we are sending media based adaptive cards (version 1.1) then the webchat is failing to show the videos (we have the latest version of webchat). However, the above workaround solves our issue. But we can't use the above workaround as we have other channels for our bot too and they can't render custom content type adaptive cards. Any permanent fix for this issue? If you want I can send you our card json as well.

v-kydela commented 5 years ago

@mathurvarun84 - What channels? I don't think there are any other channels that support Adaptive Cards 1.1, but in any case that's irrelevant because this issue is about Direct Line.

tdurnford commented 5 years ago

@mathurvarun84 If you only want to apply the work around to AdaptiveCards being sent to Web Chat, you can check if the incoming activity's channel id is 'directline' before changing the content type. This should allow you to send AdaptiveCards to channels that support them while still using the work around for Web Chat.

const card = CardFactory.adaptiveCard(Card);
if (turnContext.activity.channelId === 'directline') {
    card.contentType = 'application/vnd.microsoft.card.custom';
}

await turnContext.sendActivity({ attachments: [ card ]})

Hope this helps!

mathurvarun84 commented 5 years ago

Hi tdurnford we have two channels one is directline and one is webchat. You mean to say that this issue exists if the channel is directline but doesn't if the channel is webchat. However, this is not the case it seems as for us both of it are failing.

Also, may I know why it is failing anyway if we have adaptive cards 1.2.0 in the webchat so ideally, it should support.

One more thing....does webchat support application/vnd.microsoft.card.videocard?? If we send the content as vidoecard (created by botbuilder) will that work in webchat.

v-kydela commented 5 years ago

@mathurvarun84 - Direct Line and Web Chat are not two distinct channels. Direct Line is a channel and Web Chat is a Direct Line client. That means Web Chat is a client application with a user interface that can be used to interact with the bot through the Direct Line channel.

Do you mean you have two clients? Are you using Web Chat in addition to your own Direct Line client?

mathurvarun84 commented 5 years ago

I apologize... .yes we have two clients... we are using salesforce which uses directline channel and we use normal app service in azure to use webchat as the channel (via the token)

tdurnford commented 5 years ago

In that case, you can add channel data to each activity sent from Web Chat to distinguish messages sent specifically from Web Chat.

Web Chat Store

<script src="https://unpkg.com/simple-update-in/dist/simple-update-in.production.min.js"></script>
const store = createStore(
  {},
  ({ dispatch}) => next => async action => {
     if (action.type === 'DIRECT_LINE/POST_ACTIVITY') {
      action = window.simpleUpdateIn(action, ['payload', 'activity', 'channelData', 'channel'], () => 'webchat');
    } else if ( ... ) {
      ...
   } ...
    return next(action)
  }
);

Bot

const card = CardFactory.adaptiveCard(Card);
if (turnContext.activity.channelData && turnContext.activity.channelData.channel === 'webchat') {
    card.contentType = 'application/vnd.microsoft.card.custom';
}

await turnContext.sendActivity({ test: 'hello', attachments: [ card ]})

For more details, take a look at the Backchannel Piggyback on Outgoing Activities sample.

Hope this helps!

v-kydela commented 5 years ago

@mathurvarun84 - Does the Salesforce client support Adaptive Cards 1.1?

v-kydela commented 5 years ago

@corinagum - Has this been fixed?

corinagum commented 5 years ago

Web Chat has been bumped to 1.2, but the issue linked above will finish up some of the work I missed.

v-kydela commented 5 years ago

@corinagum - Has the Direct Line connector service been updated to Adaptive Cards 1.2 (or become version-independent)? Can this issue be closed or has it not been addressed?

v-kydela commented 5 years ago

I just tested again and Direct Line is still stripping out media elements from Adaptive Cards. That's interesting because the new wrap property works in choice sets. I guess Direct Line removes unrecognized elements but not unrecognized properties.

compulim commented 5 years ago

Is there service team aware of AC 1.0.6 in their code base? If not, we should. CK and Daniel are probably good starting point.

CoHealer commented 5 years ago

Opened a bug in DevOps for investigation & costing.

v-kydela commented 5 years ago

I've encountered the same faulty behavior with actions sets, which were introduced in Adaptive Cards 1.2

jameslew commented 5 years ago

Sorry for the delay in responding; we've been remiss in following up here. The two primaries on this topic are on holiday so let me see who would be the next person "in the know".

Edwardfelix08 commented 5 years ago

When can we expect this feature be available in bot framework V4.x?

m903215339 commented 5 years ago

I am also facing same issue, unable to play videos and images in web browser with Direct Line channel, but same thing is working in Bot emulator without any changes in the code. Please try fixing this issue ASAP, I need video content in my bot with Adaptive cards.

tdurnford commented 5 years ago

@m903215339 I'm not sure when the development team intends to implement a fix, but in the meantime, there is a workaround in the thread above if you need an immediate solution.

jameslew commented 5 years ago

To the earlier questions; we have scheduled the work to update Adaptive Cards to v1.2. It is a little trickier than expected, some of our clients are still using Adaptive Cards 0.5 and the 1.2 version breaks compatibility with them and we're looking for a solution that doesn't break existing bots while unblocks those wishing to use 1.2 features.

v-kydela commented 5 years ago

@jameslew - From what you're saying, am I correct in understanding that when Direct Line deserializes an Adaptive Card using the 1.2 schema it removes tokens that are used by the 0.5 schema, which some Direct Line clients use?

If that is true then it's an even more persuasive case in favor of the recommendation made by TJ and me. To explain, there seem to be two possible fixes for the Web Chat problem:

  1. Update Direct Line to use Adaptive Cards 1.2 (which Corina stated in her edit at the top of the post)
  2. Update Direct Line to not have an Adaptive Cards version and just forward the JSON without deserializing it, allowing all validation to be done by the client

I had already thought option 2 would be best because it would be a permanent solution. That is to say, we wouldn't run into this problem again for future versions of Adaptive Cards. But based on what you're saying, it sounds like option 2 would also allow for more backward compatibility in addition to more forward compatibility.

compulim commented 5 years ago

@ckkashyap has a work item to bump Adaptive Cards in Direct Line channel to use 1.2.

I am unsure how current version (1.0.x) vs. 1.2. Looking at AC changelog but didn't see anything related to it.

Agree to @v-kydela that the best option is don't touch JSON. But need to fully understand why we do it today and what is the advantage. If we passthru JSON, what features we missed.

When bumping to 1.2, if the behavior changed, we will need to find a way to tell customers how our change will break stuff, and schedule, etc. In this case, we will need to loop in PM to coordinate.

FYI, in Direct Line Streaming Extensions, it is passthru. In my believe, we should reduce the difference of DL REST/WS and DL SE as much as we could.

cwhitten commented 4 years ago

@jameslew when it this scheduled to be addressed? We continue to get complaints from customers on the WebChat project.

dandriscoll commented 4 years ago

I have status on this from our last standup -- we are waiting on a bugfixed version of Adaptive Cards and are targeting ~11/22 for a fix in production.

paulio commented 4 years ago

Potential dumb question warning ;) A client is suggesting that when they use Web Sockets they don't see the issue. I confess I don't know too much about this, is there any truth/reason for this?

dandriscoll commented 4 years ago

It's a good question but I can't think of a reason for that as the processing occurs inbound from the bot, not outbound to the client (over GET vs. Web Socket). Not all cards trigger the issue in the current library.

v-kydela commented 4 years ago

@dandriscoll - Does the fix account for future versions of Adaptive Cards by allowing Adaptive Cards that Direct Line doesn't understand pass through unchanged? Or does the fix just incorporate the latest version of Adaptive Cards without changing the underlying design of Direct Line?

PiLp commented 4 years ago

I am also experiencing the same issue as brett-1hw in #2912, the adaptive card is rendering but cuts off when it should display ActionSets. I am also interacting with the bot using DirectLine.

paulio commented 4 years ago

Any news on the target release of 22nd Nov?

ckkashyap commented 4 years ago

Hi @paulio , Bot Framework services have been updated with AdaptiveCard 1.2.4 - as of last evening. Please let us know if you see any issues. Regards, Kashyap

MIRo2k commented 4 years ago

hello @ckkashyap , you can confirm which components and versions we have to update ??

ckkashyap commented 4 years ago

Hi @MIRo2k , We have upgraded the Adaptive Cards library used by the channels - to version 1.2.4. You don't really "have to" update anything. This upgrade fixes certain bugs in the channel such as dropping actionset from the adaptive card json payload. HTH Regards, Kashyap

paulio commented 4 years ago

FYI it seems to be working :)

ckkashyap commented 4 years ago

Thanks @paulio - I am going to close this issue.

rvallireply commented 4 years ago

Hello, I built and deployed the ITSM experimental skill for Virtual Assistant sample, and the Web Chat has an OpenUrl action in an ActionSet that still gives issues:

**

The card could not be rendered. It is either malformed or uses features not supported by this host.

**

using a 1.2.4 Adaptive Cards, on westeurope.

this is the card payload in the sample, it works in the Bot Emulator but not in Web Chat. If I remove the ActionSet element it renders without error:


{
  "type": "AdaptiveCard",
  "id": "KnowledgeCard",
  "body": [
    {
      "type": "Container",
      "backgroundImage": "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2aWV3Qm94PSIwIDAgMzA5LjA1IDMwOS4wNSI+PGRlZnM+PHN0eWxlPi5he2ZpbGw6IzY1YWZlMjt9LmJ7ZmlsbDojMDA1OGE4O30uYiwuZHtvcGFjaXR5OjAuMjU7fS5jLC5le29wYWNpdHk6MC4yO30uY3tmaWxsOnVybCgjYSk7fS5ke2ZpbGw6I2I2ZGNmMTt9LmV7ZmlsbDp1cmwoI2IpO308L3N0eWxlPjxsaW5lYXJHcmFkaWVudCBpZD0iYSIgeDE9IjI0MS4wMyIgeTE9IjEwNS45NyIgeDI9IjQ2MS41IiB5Mj0iMTA1Ljk3IiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+PHN0b3Agb2Zmc2V0PSIwIiBzdG9wLWNvbG9yPSIjZmZmIiBzdG9wLW9wYWNpdHk9IjAuNSIvPjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iI2ZmZiIvPjwvbGluZWFyR3JhZGllbnQ+PGxpbmVhckdyYWRpZW50IGlkPSJiIiB4MT0iMjQxLjAzIiB5MT0iNTkuOTUiIHgyPSI0NjEuNSIgeTI9IjU5Ljk1IiB4bGluazpocmVmPSIjYSIvPjwvZGVmcz48dGl0bGU+cGxhdGZvcm1zQXNzZXQgNDlxdWVzaXRvbnM8L3RpdGxlPjxwYXRoIGNsYXNzPSJhIiBkPSJNMjQyLjksNzYuNzcsMjU5LjcyLDYwbC02LjQ4LTYuNDhMMjQ3LDU5LjcxYTYuNDMsNi40MywwLDAsMS05LjA2LDBMMTc4LjI0LDBIMFYzMDkuMDVIMzA5LjA1VjE1MkwyNDIuOSw4NS44M0E2LjQzLDYuNDMsMCwwLDEsMjQyLjksNzYuNzdaIi8+PHBhdGggY2xhc3M9ImEiIGQ9Ik0yNDcsNTkuNzFsNi4yMy02LjI0TDIyNi4zMSwyNi41NGE2LjQyLDYuNDIsMCwwLDEsMC05TDI0My44LDBIMTc4LjI0TDIzOCw1OS43MUE2LjQzLDYuNDMsMCwwLDAsMjQ3LDU5LjcxWiIvPjxwYXRoIGNsYXNzPSJiIiBkPSJNMjQ3LDU5LjcxbDYuMjMtNi4yNEwyMjYuMzEsMjYuNTRhNi40Miw2LjQyLDAsMCwxLDAtOUwyNDMuOCwwSDE3OC4yNEwyMzgsNTkuNzFBNi40Myw2LjQzLDAsMCwwLDI0Nyw1OS43MVoiLz48cGF0aCBjbGFzcz0iYSIgZD0iTTI1OS43Miw2MCwyNDIuOSw3Ni43N2E2LjQzLDYuNDMsMCwwLDAsMCw5LjA2TDMwOS4wNSwxNTJ2LTQyLjdaIi8+PHBhdGggY2xhc3M9ImMiIGQ9Ik0yNTkuNzIsNjAsMjQyLjksNzYuNzdhNi40Myw2LjQzLDAsMCwwLDAsOS4wNkwzMDkuMDUsMTUydi00Mi43WiIvPjxwb2x5Z29uIGNsYXNzPSJhIiBwb2ludHM9IjMwOS4wNSAwIDMwNi43MiAwIDI1My4yNCA1My40NyAyNTkuNzIgNTkuOTUgMzA5LjA1IDEwLjYyIDMwOS4wNSAwIi8+PHBvbHlnb24gY2xhc3M9ImQiIHBvaW50cz0iMzA5LjA1IDAgMzA2LjcyIDAgMjUzLjI0IDUzLjQ3IDI1OS43MiA1OS45NSAzMDkuMDUgMTAuNjIgMzA5LjA1IDAiLz48cGF0aCBjbGFzcz0iYSIgZD0iTTI0My44LDAsMjI2LjMxLDE3LjQ5YTYuNDIsNi40MiwwLDAsMCwwLDkuMDVsMjYuOTMsMjYuOTNMMzA2LjcyLDBaIi8+PHBhdGggY2xhc3M9ImIiIGQ9Ik0yNDMuOCwwLDIyNi4zMSwxNy40OWE2LjQyLDYuNDIsMCwwLDAsMCw5LjA1bDI2LjkzLDI2LjkzTDMwNi43MiwwWiIvPjxwYXRoIGNsYXNzPSJkIiBkPSJNMjQzLjgsMCwyMjYuMzEsMTcuNDlhNi40Miw2LjQyLDAsMCwwLDAsOS4wNWwyNi45MywyNi45M0wzMDYuNzIsMFoiLz48cG9seWdvbiBjbGFzcz0iYSIgcG9pbnRzPSIyNTkuNzIgNTkuOTUgMzA5LjA1IDEwOS4yOCAzMDkuMDUgMTAuNjIgMjU5LjcyIDU5Ljk1Ii8+PHBvbHlnb24gY2xhc3M9ImUiIHBvaW50cz0iMjU5LjcyIDU5Ljk1IDMwOS4wNSAxMDkuMjggMzA5LjA1IDEwLjYyIDI1OS43MiA1OS45NSIvPjxwb2x5Z29uIGNsYXNzPSJkIiBwb2ludHM9IjI1OS43MiA1OS45NSAzMDkuMDUgMTA5LjI4IDMwOS4wNSAxMC42MiAyNTkuNzIgNTkuOTUiLz48L3N2Zz4=",
      "items": [
        {
          "type": "ColumnSet",
          "columns": [
            {
              "type": "Column",
              "horizontalAlignment": "Center",
              "verticalContentAlignment": "Center",
              "items": [
                {
                  "type": "Image",
                  "horizontalAlignment": "Center",
                  "url": "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIgogICB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgeG1sbnM6c29kaXBvZGk9Imh0dHA6Ly9zb2RpcG9kaS5zb3VyY2Vmb3JnZS5uZXQvRFREL3NvZGlwb2RpLTAuZHRkIgogICB4bWxuczppbmtzY2FwZT0iaHR0cDovL3d3dy5pbmtzY2FwZS5vcmcvbmFtZXNwYWNlcy9pbmtzY2FwZSIKICAgdmlld0JveD0iMCAwIDk2IDk2IgogICBpZD0iSWNvbnNfSGVhZFdpdGhHZWFycyIKICAgb3ZlcmZsb3c9ImhpZGRlbiIKICAgdmVyc2lvbj0iMS4xIgogICBzb2RpcG9kaTpkb2NuYW1lPSJLbm93bGVkZ2VJY29uLnN2ZyIKICAgaW5rc2NhcGU6dmVyc2lvbj0iMC45Mi40ICg1ZGE2ODljMzEzLCAyMDE5LTAxLTE0KSI+CiAgPG1ldGFkYXRhCiAgICAgaWQ9Im1ldGFkYXRhMTMiPgogICAgPHJkZjpSREY+CiAgICAgIDxjYzpXb3JrCiAgICAgICAgIHJkZjphYm91dD0iIj4KICAgICAgICA8ZGM6Zm9ybWF0PmltYWdlL3N2Zyt4bWw8L2RjOmZvcm1hdD4KICAgICAgICA8ZGM6dHlwZQogICAgICAgICAgIHJkZjpyZXNvdXJjZT0iaHR0cDovL3B1cmwub3JnL2RjL2RjbWl0eXBlL1N0aWxsSW1hZ2UiIC8+CiAgICAgIDwvY2M6V29yaz4KICAgIDwvcmRmOlJERj4KICA8L21ldGFkYXRhPgogIDxkZWZzCiAgICAgaWQ9ImRlZnMxMSIgLz4KICA8c29kaXBvZGk6bmFtZWR2aWV3CiAgICAgcGFnZWNvbG9yPSIjZmZmZmZmIgogICAgIGJvcmRlcmNvbG9yPSIjNjY2NjY2IgogICAgIGJvcmRlcm9wYWNpdHk9IjEiCiAgICAgb2JqZWN0dG9sZXJhbmNlPSIxMCIKICAgICBncmlkdG9sZXJhbmNlPSIxMCIKICAgICBndWlkZXRvbGVyYW5jZT0iMTAiCiAgICAgaW5rc2NhcGU6cGFnZW9wYWNpdHk9IjAiCiAgICAgaW5rc2NhcGU6cGFnZXNoYWRvdz0iMiIKICAgICBpbmtzY2FwZTp3aW5kb3ctd2lkdGg9IjE5MjAiCiAgICAgaW5rc2NhcGU6d2luZG93LWhlaWdodD0iMTE0NyIKICAgICBpZD0ibmFtZWR2aWV3OSIKICAgICBzaG93Z3JpZD0iZmFsc2UiCiAgICAgaW5rc2NhcGU6em9vbT0iMi40NTgzMzMzIgogICAgIGlua3NjYXBlOmN4PSI1LjI4ODEzNTYiCiAgICAgaW5rc2NhcGU6Y3k9IjQ4IgogICAgIGlua3NjYXBlOndpbmRvdy14PSItOCIKICAgICBpbmtzY2FwZTp3aW5kb3cteT0iLTgiCiAgICAgaW5rc2NhcGU6d2luZG93LW1heGltaXplZD0iMSIKICAgICBpbmtzY2FwZTpjdXJyZW50LWxheWVyPSJJY29uc19IZWFkV2l0aEdlYXJzIiAvPgogIDxwYXRoCiAgICAgZD0iTTQ3LjEgMTkuN0M0NC44IDE5LjcgNDIuOSAyMS42IDQyLjkgMjMuOSA0Mi45IDI2LjIgNDQuOCAyOC4xIDQ3LjEgMjguMSA0OS40IDI4LjEgNTEuMyAyNi4yIDUxLjMgMjMuOSA1MS4zIDIxLjYgNDkuNCAxOS43IDQ3LjEgMTkuN1oiCiAgICAgaWQ9InBhdGgyIgogICAgIHN0eWxlPSJmaWxsOiNmZmZmZmYiIC8+CiAgPGNpcmNsZQogICAgIGN4PSIzNC41IgogICAgIGN5PSI0NC4yIgogICAgIHI9IjQuMiIKICAgICBpZD0iY2lyY2xlNCIKICAgICBzdHlsZT0iZmlsbDojZmZmZmZmIiAvPgogIDxwYXRoCiAgICAgZD0iTTU5IDI1LjMgNTYuNSAyNi41QzU2LjMgMjcuMyA1NS45IDI4IDU1LjUgMjguN0w1Ni40IDMxLjMgNTQuNCAzMy4zIDUxLjggMzIuNEM1MS4xIDMyLjggNTAuNCAzMy4xIDQ5LjYgMzMuM0w0OC40IDM1LjcgNDUuNiAzNS43IDQ0LjQgMzMuMkM0My42IDMzIDQyLjkgMzIuNyA0Mi4yIDMyLjNMMzkuNiAzMy4yIDM3LjYgMzEuMiAzOC41IDI4LjZDMzguMSAyNy45IDM3LjggMjcuMiAzNy42IDI2LjRMMzUuMSAyNS4yIDM1LjEgMjIuNCAzNy42IDIxLjJDMzcuOCAyMC40IDM4LjEgMTkuNyAzOC41IDE5TDM3LjcgMTYuNCAzOS43IDE0LjQgNDIuMyAxNS4zQzQzIDE0LjkgNDMuNyAxNC42IDQ0LjUgMTQuNEw0NS43IDExLjkgNDguNSAxMS45IDQ5LjcgMTQuM0M1MC41IDE0LjUgNTEuMiAxNC44IDUxLjkgMTUuMkw1NC41IDE0LjMgNTYuNSAxNi4zIDU1LjYgMTguOUM1NiAxOS42IDU2LjMgMjAuMyA1Ni41IDIxLjFMNTkgMjIuMyA1OSAyNS4zWk00Ni40IDQ1LjYgNDMuOSA0Ni44QzQzLjcgNDcuNiA0My40IDQ4LjMgNDMgNDlMNDMuOCA1MS42IDQxLjggNTMuNiAzOS4yIDUyLjdDMzguNSA1My4xIDM3LjggNTMuNCAzNyA1My42TDM1LjkgNTYgMzMuMSA1NiAzMS45IDUzLjVDMzEuMSA1My4zIDMwLjQgNTMgMjkuNyA1Mi42TDI3LjEgNTMuNCAyNS4xIDUxLjQgMjYgNDguOEMyNS42IDQ4LjEgMjUuMyA0Ny40IDI1LjEgNDYuNkwyMi42IDQ1LjQgMjIuNiA0Mi42IDI1LjEgNDEuNEMyNS4zIDQwLjYgMjUuNiAzOS45IDI2IDM5LjJMMjUuMSAzNi42IDI3LjEgMzQuNiAyOS43IDM1LjVDMzAuNCAzNS4xIDMxLjEgMzQuOCAzMS45IDM0LjZMMzMuMSAzMi4xIDM2IDMyLjEgMzcuMiAzNC42QzM4IDM0LjggMzguNyAzNS4xIDM5LjQgMzUuNUw0MiAzNC42IDQ0IDM2LjYgNDMuMSAzOS4yQzQzLjUgMzkuOSA0My44IDQwLjYgNDQgNDEuNEw0Ni41IDQyLjYgNDYuNCA0NS42IDQ2LjQgNDUuNlpNODEgNDkuMyA3NC4xIDM3LjMgNzQuMSAzNi44Qzc0LjUgMjUuOCA2OC45IDE1LjUgNTkuNCA5LjggNDkuOSA0LjIgMzguMiA0LjIgMjguNyA5LjggMTkuMiAxNS40IDEzLjYgMjUuOCAxNCAzNi44IDE0IDQ2LjMgMTguMyA1NS4yIDI1LjggNjFMMjUuOCA4Ni4zIDU3LjQgODYuMyA1Ny40IDc0LjMgNjIuMyA3NC4zQzY1LjUgNzQuMyA2OC41IDczIDcwLjcgNzAuOCA3Mi45IDY4LjUgNzQuMSA2NS41IDc0LjEgNjIuM0w3NC4xIDU2LjMgNzguNSA1Ni4zQzgxLjEgNTYgODMuNCA1MyA4MSA0OS4zWiIKICAgICBpZD0icGF0aDYiCiAgICAgc3R5bGU9ImZpbGw6I2ZmZmZmZiIgLz4KPC9zdmc+Cg==",
                  "width": "35px",
                  "height": "35px"
                }
              ],
              "width": "auto"
            },
            {
              "type": "Column",
              "verticalContentAlignment": "Center",
              "items": [
                {
                  "type": "TextBlock",
                  "horizontalAlignment": "Left",
                  "size": "Medium",
                  "color": "Light",
                  "text": "{Title}",
                  "wrap": true
                }
              ],
              "width": "stretch"
            }
          ]
        },
        {
          "type": "TextBlock",
          "size": "Small",
          "color": "Light",
          "text": "{UpdatedTime}"
        },
        {
          "type": "TextBlock",
          "size": "Small",
          "color": "Light",
          "text": "{Number}"
        }
      ]
    },
    {
      "type": "TextBlock",
      "wrap": true,
      "text": "{Content}",
      "maxLines": 5
    },
    {
      "type": "ActionSet",
      "actions": [
        {
          "type": "Action.OpenUrl",
          "title": "{UrlTitle}",
          "url": "{UrlLink}"
        }
      ]
    },
    {
      "type": "Container",
      "separator": true,
      "items": [
        {
          "type": "TextBlock",
          "horizontalAlignment": "Right",
          "size": "Small",
          "color": "default",
          "text": "{ProviderDisplayText}"
        }
      ]
    }
  ],
  "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
  "version": "1.0",
  "speak": "{Speak}"
}