Action Messageback card not rendering - c#

I am trying to post a Messageback Adaptive card but I am below getting error in emulator:
The card could not be rendered. It is either malformed or uses features not supported by this host.
I am using AdaptiveCards 1.2.2 version. I am using C# to post this adaptive card but I am not able to figure out the issue.
My Json File:
{
"type": "AdaptiveCard",
"selectAction": {
"type": "Action.Submit"
},
"body": [
{
"type": "TextBlock",
"text": "1:1 with John Doe",
"weight": "Bolder"
},
{
"type": "ColumnSet",
"columns": [
{
"type": "Column",
"items": [
{
"type": "Image",
"url": "https://images.idgesg.net/images/article/2019/04/google-calendar-android-100794956-large.jpg",
"altText": "Calendar",
"size": "small"
}
],
"width": "auto"
},
{
"type": "Column",
"items": [
{
"type": "TextBlock",
"text": "Tomorrow, 30 May"
}
],
"width": "stretch"
}
]
},
{
"type": "ColumnSet",
"columns": [
{
"type": "Column",
"items": [
{
"type": "Image",
"url": "https://pbs.twimg.com/profile_images/3647943215/d7f12830b3c17a5a9e4afcc370e3a37e_400x400.jpeg",
"altText": "Calendar",
"height": "20px"
}
],
"width": "auto"
},
{
"type": "Column",
"items": [
{
"type": "TextBlock",
"text": "John Doe",
"spacing": "Medium"
}
],
"width": "stretch"
}
]
},
{
"type": "TextBlock",
"text": "Slots available - **1 hr duration**",
"separator": true,
"spacing": "Medium",
"isSubtle": true
},
{
"type": "ColumnSet",
"columns": [
{
"type": "Column",
"items": [
{
"actions": [
{
"type": "Action.Submit",
"title": "11:00 AM",
"data": {
"msteams": {
"type": "messageBack",
"displayText": "11:00 AM",
"text": "text to bots",
"value": "{\"bfKey\": \"bfVal\", \"conflictKey\": \"from value\"}"
}
}
}
]
}
],
"width": "auto"
},
{
"actions": [
{
"type": "Action.Submit",
"title": "Cancel",
"data": {
"msteams": {
"type": "messageBack",
"displayText": "Cancel",
"text": "text to bots",
"value": "{\"bfKey\": \"bfVal\", \"conflictKey\": \"from value\"}"
}
}
},
{
"type": "Action.Submit",
"title": "Confirm",
"data": {
"msteams": {
"type": "messageBack",
"displayText": "Confirm",
"text": "text to bots",
"value": "{\"bfKey\": \"bfVal\", \"conflictKey\": \"from value\"}"
}
}
}
]
}
],
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"version": "1.0"
}

A great way to test your Adaptive Cards is to use the Adaptive Card Designer or the card editor in App Studio in Microsoft Teams. If a preview isn't rendered then there's something wrong with your card.
In your case, you say you want to use Adaptive Cards 1.2.2 but you're including "version": "1.0" in your JSON. You might want to say "version": "1.2" instead, but keep in mind that the higher the version of your Adaptive Card the fewer clients will be able to render it.
More importantly, you're putting an actions property in both columns and column sets and neither of those have an actions property. Please refer to the schema to see what elements have what properties. You might mean to use an action set (a 1.2 feature), or you might just want to use the actions property of the card itself outside of the card's body.
More importantly still, you have more opening brackets than closing brackets and so your JSON is invalid. I suspect you forgot to close your last column set and its columns array. Please use an editor like Visual Studio Code to automatically format your JSON and make sure it's valid. It's also good etiquette to correctly format your JSON in your Stack Overflow question so that other people can read it without formatting it for you.
Please read my latest blog post for more information about Adaptive Cards and using them with the Microsoft Bot Framework.

Related

Getting an error of Existing Resource while using function ARM template

I am wrting a Function ARM template for CI/CD the function is already hosted on the Azure portal Now I decided to create an ARM function template and am getting the below error. It saying I cannot create a resource which already exists. I know the resource already exists but I want to create a CI/CD pipline based on the template. I have tried the incremental mode but it seems I am missing something. Is there any guidance online? I have taken the Azure Function Template from the AZURE Git.
C:\Program Files\Microsoft SDKs\Azure.NET SDK\v2.9> az group deployment validate --mode Incremental --resource-group cloud-shell-storage-southeastasia --template-file azuredeploy.json
Please provide string value for 'appName' (? for help): SchedulerHttpFunctionSample
azuredeploy.json
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"appName": {
"type": "string",
"metadata": {
"description": "The name of the function app that you wish to create."
}
},
"storageAccountType": {
"type": "string",
"defaultValue": "Standard_LRS",
"allowedValues": [
"Standard_LRS",
"Standard_GRS",
"Standard_RAGRS"
],
"metadata": {
"description": "Storage Account type"
}
},
"location": {
"type": "string",
"defaultValue": "[resourceGroup().location]",
"metadata": {
"description": "Location for all resources."
}
},
"runtime": {
"type": "string",
"defaultValue": "node",
"allowedValues": [
"node",
"dotnet",
"java"
],
"metadata": {
"description": "The language worker runtime to load in the function app."
}
}
},
"variables": {
"functionAppName": "[parameters('appName')]",
"hostingPlanName": "[parameters('appName')]",
"applicationInsightsName": "[parameters('appName')]",
"storageAccountName": "[concat(uniquestring(resourceGroup().id), 'azfunctions')]",
"storageAccountid": "[concat(resourceGroup().id,'/providers/','Microsoft.Storage/storageAccounts/', variables('storageAccountName'))]",
"functionWorkerRuntime": "[parameters('runtime')]"
},
"resources": [
{
"type": "Microsoft.Storage/storageAccounts",
"name": "[variables('storageAccountName')]",
"apiVersion": "2018-12-01",
"location": "[parameters('location')]",
"kind": "Storage",
"sku": {
"name": "[parameters('storageAccountType')]"
},
"properties":{
"mode":"Incremental"
}
},
{
"type": "Microsoft.Web/serverfarms",
"apiVersion": "2018-02-01",
"name": "[variables('hostingPlanName')]",
"location": "[parameters('location')]",
"sku": {
"name": "Y1",
"tier": "Dynamic"
},
"properties": {
"mode":"Incremental",
"name": "[variables('hostingPlanName')]",
"computeMode": "Dynamic"
}
},
{
"apiVersion": "2018-02-01",
"type": "Microsoft.Web/sites",
"name": "[variables('functionAppName')]",
"location": "[parameters('location')]",
"kind": "functionapp",
"dependsOn": [
"[resourceId('Microsoft.Web/serverfarms', variables('hostingPlanName'))]",
"[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]"
],
"properties": {
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('hostingPlanName'))]",
"mode":"Incremental",
"siteConfig": {
"appSettings": [
{
"name": "AzureWebJobsStorage",
"value": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('storageAccountName'), ';AccountKey=', listKeys(variables('storageAccountid'),'2015-05-01-preview').key1)]"
},
{
"name": "WEBSITE_CONTENTAZUREFILECONNECTIONSTRING",
"value": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('storageAccountName'), ';AccountKey=', listKeys(variables('storageAccountid'),'2015-05-01-preview').key1)]"
},
{
"name": "WEBSITE_CONTENTSHARE",
"value": "[toLower(variables('functionAppName'))]"
},
{
"name": "FUNCTIONS_EXTENSION_VERSION",
"value": "~2"
},
{
"name": "WEBSITE_NODE_DEFAULT_VERSION",
"value": "~10"
},
{
"name": "APPINSIGHTS_INSTRUMENTATIONKEY",
"value": "[reference(resourceId('microsoft.insights/components/', variables('applicationInsightsName')), '2015-05-01').InstrumentationKey]"
},
{
"name": "FUNCTIONS_WORKER_RUNTIME",
"value": "[variables('functionWorkerRuntime')]"
}
]
}
}
},
{
"apiVersion": "2018-02-01",
"name": "[variables('applicationInsightsName')]",
"type": "microsoft.insights/components",
"location": "East US",
"tags": {
"[concat('hidden-link:', resourceGroup().id, '/providers/Microsoft.Web/sites/', variables('applicationInsightsName'))]": "Resource"
},
"properties": {
"ApplicationId": "[variables('applicationInsightsName')]",
"Request_Source": "IbizaWebAppExtensionCreate",
"mode":"Incremental"
}
}
]
}
Azure Error: InvalidResourceLocation
Message: The resource 'SchedulerHttpFunctionSample' already exists in location 'southcentralus' in resource group 'cloud-shell-storage-southeastasia'. A resource with the same name cannot be created in location 'southeastasia'. Please select a new resource name.
It's because that name is already taken. Function App name need to be globally unique.
I would suggest using a suffix. In the variables section create some variables:
"variables": {
"suffix": "[uniqueString(resourceGroup().id, resourceGroup().location)]",
"functionAppName": "[concat(parameters('appName'), variables('suffix'))]"
}
The function uniqueString will generate a unique string base on the information received. So if you redeploy in the same resource group and region the suffix will be the same.
Have a look to this post: http://www.frankysnotes.com/2019/05/how-to-make-your-deployment-successful.html or this video https://www.youtube.com/watch?v=dnb-f4C052w

could not find app configuration tab when trying to deploy bot in teams

when i am trying to configure tab in teams channel,i followed the steps from article https://learn.microsoft.com/en-in/microsoftteams/platform/tutorials/get-started-dotnet-app-studio i could not find selection of tab and save button enabled , why this happned? how to solve it?, I am using echo bot template which is running on bot emulator properly.
Following is the json
{
"$schema": "https://developer.microsoft.com/en-us/json-schemas/teams/v1.5/MicrosoftTeams.schema.json",
"manifestVersion": "1.5",
"version": "1.0.0",
"id": "2fac8fdd-7fa3-451f-8562-adba3ab84c8d",
"packageName": "com.contoso.helloworld",
"developer": {
"name": "Hello World App ",
"websiteUrl": "https://www.microsoft.com",
"privacyUrl": "https://www.microsoft.com/privacy",
"termsOfUseUrl": "https://www.microsoft.com/termsofuse"
},
"icons": {
"color": "color.png",
"outline": "outline.png"
},
"name": {
"short": "janApp",
"full": "janApp"
},
"description": {
"short": "SWAN Bot App for Microsoft Teams",
"full": "This sample app provides a very simple app for Microsoft Teams. You can extend this to add more content and capabilities."
},
"accentColor": "#A4D344",
"configurableTabs": [
{
"configurationUrl": "https://echobot57.azurewebsites.net/configure",
"canUpdateConfiguration": true,
"scopes": [
"team",
"groupchat"
]
}
],
"staticTabs": [
{
"entityId": "com.contoso.helloworld.hellotab",
"name": "Botdemo",
"contentUrl": "https://echobot57.azurewebsites.net/hello",
"websiteUrl": "https://echobot57.azurewebsites.net/hello",
"scopes": [
"personal"
]
}
],
"bots": [
{
"botId": "330b4c4d-5f92-4053-a38f-7d4593cfd18a",
"scopes": [
"personal",
"team",
"groupchat"
],
"supportsFiles": true,
"isNotificationOnly": true
}
],
"composeExtensions": [
{
"botId": "330b4c4d-5f92-4053-a38f-7d4593cfd18a",
"canUpdateConfiguration": true,
"commands": [
{
"id": "getRandomText",
"type": "query",
"title": "Get some random text for fun",
"description": "Gets some random text and images",
"initialRun": true,
"fetchTask": false,
"context": [
"commandBox",
"compose",
"message"
],
"parameters": [
{
"name": "cardTitle",
"title": "Card title",
"description": "Card title to use",
"inputType": "text"
}
]
}
]
}
],
"permissions": [
"identity",
"messageTeamMembers"
],
"validDomains": [
"echobot57.azurewebsites.net"
]
}
Please make sure the tab configuration url is correct.
If it is correct, you should be able to access it.
https://microsoftteamssampleshelloworldweb20200107021253.azurewebsites.net/configure

How to mount a File Storage volume to an azure container instance using REST api

I'm trying to create an Azure container instance and mounting a File Storage volume via REST API, but I'm getting 400 response.
I'm able to create the container and keep it running but when I add the volume part it returns a 400 response (Bad request) without further explanation
Here is the JSON payload I'm sending to the REST endpoint:
{
"id": "/subscriptions/111111111/resourceGroups/OraResourceGroup/providers/Microsoft.ContainerInstance/containerGroups/solver",
"location": "West Europe",
"name": "solver",
"properties": {
"volumes": [
{
"azureFile": {
"shareName": "orafileshare",
"storageAccountKey": "somekey",
"storageAccountName": "myaccountname"
},
"name": "Volume1"
}
],
"containers": [
{
"name": "solver",
"properties": {
"command": [],
"environmentVariables": [],
"image": "acraccount/solver:v1",
"ports": [
{
"port": 12345
}
],
"resources": {
"requests": {
"cpu": 1.0,
"memoryInGB": 1.5
}
},
"volumeMounts": [
{
"name": "Volume1",
"mountPath": "/mountFolder"
}
]
}
}
],
"imageRegistryCredentials": [
{
"password": "123123123213123",
"server": "acr.server.io",
"username": "acrOra"
}
],
"ipAddress": {
"ports": [
{
"protocol": "TCP",
"port": 12345
}
],
"type": "Public"
},
"osType": "Linux",
"restartPolicy": "Always"
},
"type": "Microsoft.ContainerInstance/containerGroups"
}
The expected results is a 200 or 201 response and the container should appear on my Azure portal dashboard but the actual response is 400.
There are 2 issues with this correction. I also received 400 bad request but later corrected it and I was able to run it successfully.
Name of volume, capital letter is not allowed.
Change "Volume1" to "volume1"
Reference Error :
{"error":{"code":"InvalidVolumeName","message":"The volume name 'Volume1' is invalid. The volume name must match the regex '[a-z0-9]([-a-z0-9]*[a-z0-9])?' (e.g. 'my-name')."}}
Sku is not a valid property, Remove it
{"error":{"code":"InvalidRequestContent","message":"The request
content was invalid and could not be deserialized: 'Could not find
member 'sku' on object of type 'ComputeResources'. Path
'properties.containers[0].properties.resources.requests.sku', line 32,
position 22.'."}}
Reference https://learn.microsoft.com/en-us/rest/api/container-instances/containergroups/createorupdate#resourcerequests
Sample configuration
{
"id": "/subscriptions/xxxx/resourceGroups/teststoragerest/providers/Microsoft.ContainerInstance/containerGroups/solver",
"location": "West Europe",
"name": "demo1forrahul",
"properties": {
"volumes": [
{
"azureFile": {
"shareName": "testfilestorage",
"storageAccountKey": "xxxx",
"storageAccountName": "xxxxxx"
},
"name": "volume1"
}
],
"containers": [
{
"name": "demo1forrahul",
"properties": {
"command": [],
"environmentVariables": [],
"image": "nginx",
"ports": [
{
"port": 80
}
],
"resources": {
"requests": {
"cpu": 1.0,
"memoryInGB": 1.5
}
},
"volumeMounts": [
{
"name": "volume1",
"mountPath": "/testfolder"
}
]
}
}
],
"imageRegistryCredentials": [],
"ipAddress": {
"ports": [
{
"protocol": "TCP",
"port": 80
}
],
"type": "Public"
},
"osType": "Linux",
"restartPolicy": "Always"
},
"type": "Microsoft.ContainerInstance/containerGroups"
}

How to use "selectAction" Attribute of AdaptiveColumnSet() in AdaptiveCard? C#

private Attachment CardExample()
{
AdaptiveCard card = new AdaptiveCard("1.0");
card.Body.Add(new AdaptiveContainer()
{
Style = AdaptiveContainerStyle.Emphasis,
Items = new List<AdaptiveElement>()
{
new AdaptiveColumnSet()
{
Type = "ColumnSet",
Height = AdaptiveHeight.Auto,
SelectAction = new AdaptiveSubmitAction()
{
Type="Action.Submit",
Id = "Submit",
Title="Submit",
}
},
}
});
Attachment TestCard = new Attachment
{
ContentType = AdaptiveCard.ContentType,
Content= JsonConvert.DeserializeObject(JsonConvert.SerializeObject(card)),
};
return TestCard;
}
//It doesn't have any compiling error but when the adaptive card is rendered the Submit button don't come up
//only an empty container
ColumnSets are able to contain an on click action but there is no button dispayed, it's really as simple as that. If I click on the ColumnSet, it performs the action.
I've included some images, etc. below that illustrate it working. It's a bit clunky but you can see what I mean.
The example is an OpenUrl and it opens up to google.com, a Submit action works the same, just include the data you want to send back to the bot and the catch it and deal with it in OnTurnAsync (if you're using v4 framework) ...
I know this answer is lacking but ... it is the answer. :-)
The issue with your implementation is that you are adding a selectAction on an empty container. A column set needs columns and each column needs content. In your case, there are no actual items in the columns and hence there will be nothing to click on.
Here is an example of how the column set should be implemented :
{
"type": "AdaptiveCard",
"version": "1.0",
"body": [
{
"type": "ColumnSet",
"spacing": "medium",
"columns": [
{
"type": "Column",
"width": "auto",
"items": [
{
"type": "Image",
"url": "https://unsplash.it/80?image=1083",
"size": "medium"
}
]
},
{
"type": "Column",
"width": 4,
"items": [
{
"type": "TextBlock",
"text": "Silver Star Mountain"
},
{
"type": "TextBlock",
"text": "Maps",
"isSubtle": true,
"spacing": "none"
}
]
}
],
"selectAction": {
"type": "Action.OpenUrl",
"title": "Silver Star Mountain",
"url": "ms-cortana:silver-star-mountain"
}
}
]
}

Botframework v4: Can't render cards

This is the sample on Botframework v4 docs. But it does not work.
It says "Can't Render Card" on the Microsoft bot emulator.
What i'm trying to do is a carouselCard but this simple card from Microsoft's sample is already not working.
{
"type": "message",
"text": "Plain text is ok, but sometimes I long for more...",
"attachments": [
{
"contentType": "application/vnd.microsoft.card.adaptive",
"content": {
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"type": "AdaptiveCard",
"version": "1.0",
"body": [
{
"type": "TextBlock",
"text": "Hello World!",
"size": "large"
},
{
"type": "TextBlock",
"text": "*Sincerely yours,*"
},
{
"type": "TextBlock",
"text": "Adaptive Cards",
"separation": "none"
}
],
"actions": [
{
"type": "Action.OpenUrl",
"url": "http://adaptivecards.io",
"title": "Learn More"
}
]
}
}
]
}
However, if i remove the top part of the code this code works:
{
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"type": "AdaptiveCard",
"version": "1.0",
"body": [
{
"type": "TextBlock",
"text": "Hello World!",
"size": "large"
},
{
"type": "TextBlock",
"text": "*Sincerely yours,*"
},
{
"type": "TextBlock",
"text": "Adaptive Cards",
"separation": "none"
}
],
"actions": [
{
"type": "Action.OpenUrl",
"url": "http://adaptivecards.io",
"title": "Learn More"
}
]
}
This is how i call the card. Is there a better way to do this?
public class GetNameAndAgeDialog : WaterfallDialog
{
private readonly string _cards = #".\Resources\TryCarouselCard.json";
private static Attachment CreateAdaptiveCardAttachment(string filePath)
{
var adaptiveCardJson = File.ReadAllText(filePath);
var adaptiveCardAttachment = new Attachment()
{
ContentType = "application/vnd.microsoft.card.adaptive",
Content = JsonConvert.DeserializeObject(adaptiveCardJson),
};
return adaptiveCardAttachment;
}
public GetNameAndAgeDialog(string dialogId, IEnumerable<WaterfallStep> steps = null) : base(dialogId, steps)
{
AddStep(async (stepContext, cancellationToken) =>
{
var cardAttachment = CreateAdaptiveCardAttachment(_cards);
var reply = stepContext.Context.Activity.CreateReply();
reply.Attachments = new List<Attachment>() { cardAttachment };
await stepContext.Context.SendActivityAsync(reply, cancellationToken);
return await stepContext.ContinueDialogAsync();
});
}
}
The "top part" of the first block of JSON you posted is the card contained within an activity. The second block of JSON posted is indeed just the card itself and what you'd want to put into an Attachment.
As for your code, it looks correct to me. I might consider caching the attachment JSON as you probably don't want to hit the file system every time you want to display the card, but that would just be an optimization.
I'm unclear if you are experiencing any further problems or just looking for validation of the approach now. If you are still experiencing a problem please update the question with some more details and I'll update my answer to try and help.

Categories