-->

21/07/2018

Adaptive Cards in Bot Framework

If you are new to Bot development, you better check Basics from my earlier post.

As mentioned in earlier post we will learn various components that can be used for better interactions with users. As part of it we will look at Adaptive Cards, shown below.
And also how to handle the events generated from actions in adaptive cards.

From above mentioned Basics article, you should be able to create a bot and can test it in emulator.

Now i will show you a basic adaptive card.

Here is the code for that:
var basiccard = {
'contentType': 'application/vnd.microsoft.card.adaptive',
'content': {
 '$schema': 'http://adaptivecards.io/schemas/adaptive-card.json',
 'type': 'AdaptiveCard',
 'version': '1.0',
 'body': [
 {
  'type': 'Container',
  'speak': '<s>Hello!</s>',
  'items': [
     {
      'type': 'TextBlock',
      'text': 'Hello!',
      'weight': 'bolder',
      'isSubtle': true
     },
     {
      'type': 'TextBlock',
      'text': 'You are looking at a Basic Adaptive Card',
      'weight': 'bolder',
      'wrap': true
     }
    ]     
 }
 ]
}
};

After this instead of sending a test message like in a basics example, now we will create a message by attaching this card and will send that message in the session.
    var msg = new builder.Message(session)
        .addAttachment(basiccard);
    session.send(msg);

Now we will see how to have actions on top of the adaptive card.
Here is the code of the card with those 3 options shown above.
var card = {
'contentType': 'application/vnd.microsoft.card.adaptive',
'content': {
 '$schema': 'http://adaptivecards.io/schemas/adaptive-card.json',
 'type': 'AdaptiveCard',
 'version': '1.0',
 'body': [
  {
  'type': 'Container',
  'speak': '<s>Hello!</s>',
  'items': [
     {
      'type': 'TextBlock',
      'text': 'Hello!',
      'weight': 'bolder',
      'isSubtle': true
     },
     {
      'type': 'TextBlock',
      'text': 'Are you looking for a Option A or Option B or Option C?',
      'wrap': true
     }
    ]     
  }
 ],
 'actions': [
  
  {
   'type': 'Action.ShowCard',
   'title': 'Option A: Show me response',
   'speak': '<s>Option A: Show me response</s>',
   'card': {
    'type': 'AdaptiveCard',
    'body': [
     {
      'type': 'TextBlock',
      'text': 'You have selected Option A',
      'speak': '<s>You have selected Option A !</s>',
      'weight': 'bolder',
      'size': 'large'
     }
    ]
   }
  },
  {
   'type': 'Action.Submit',
   'title': 'Option B: Show me New Card',
   'speak': '<s>Option B: Show me New Card</s>',
   'data': {
        'type': 'OptionBevent'
     }
  },
  {
   'type': 'Action.Submit',
   'title': 'Option C: Show me Restart Card',
   'speak': '<s>Option C: Show me Restart Card</s>',
   'data': {
        'type': 'OptionCevent'
     }
  }
 ]
}
};

Here so the output for that:
Now we will see how to handle events generated from these actions and act accordingly.

Form the code for First action:
{
 'type': 'Action.ShowCard',
 'title': 'Option A: Show me response',
 'speak': '<s>Option A: Show me response</s>',
 'card': {
  'type': 'AdaptiveCard',
  'body': [
   {
    'type': 'TextBlock',
    'text': 'You have selected Option A',
    'speak': '<s>You have selected Option A !</s>',
    'weight': 'bolder',
    'size': 'large'
   }
  ]
 }
}
You can infer that its not causing an action, instead its just updating the existing card. Here is the output of Option A.
Now lets look at second action and third actions.
{
 'type': 'Action.Submit',
 'title': 'Option B: Show me New Card',
 'speak': '<s>Option B: Show me New Card</s>',
 'data': {
      'type': 'OptionBevent'
   }
},
{
 'type': 'Action.Submit',
 'title': 'Option C: Show me Restart Card',
 'speak': '<s>Option C: Show me Restart Card</s>',
 'data': {
      'type': 'OptionCevent'
   }
}

You can see that these 2 actions have type as Action.Submit so these will cause an event to trigger. But how we can differentiate both actions? That is where the "type" variable of those actions come to rescue.
Now here is the code how we handle it.
if (session.message && session.message.value) {
 // A Card's Submit Action obj was received
 switch (session.message.value.type) {
 case 'OptionBevent':
  
  var msg = new builder.Message(session)
     .addAttachment(cardB);
  session.send(msg);
  return;
  break;

 case 'OptionCevent':
  
  var msg = new builder.Message(session)
     .addAttachment(cardC);
  session.send(msg);
  return;
  break; 
 case 'OptionRestart':          
  
  session.send('Restarting Conversation . . .');   
  break;    
 }
}

This is how we handle any submit actions. Just by identifying the "type" variable of the events, i am showing different cards.
OptionBevent - To show cardB - A new card altogether.
OptionCevent-  To show cardC - A Reset card which has actions to restart conversation.
OptionRestart -  To actually restart the conversations.

I will attach the link to download whole code base for this at the end, from which you can get code for all cards.
Here are how other options work.

Option B:

Option C:

Here is the link for download code.

We will see more bot components for better communication with users.
Happy coding !

No comments:

Post a Comment