Skip to content

Commit

Permalink
[50.teams-messaging-extensions-search]: Sample enhancement Messaging …
Browse files Browse the repository at this point in the history
…Extension C# All commands Implementation (microsoft#3076)

* teams-messaging-extension-auth-config for search action and link unfurling

* Commit Read Me

* ReadMe Fix

* Manifest commit

* Teams messaging extension auth configuration code refactor and issue fix

* Removed unused method along with adaptive card json file.

* Messaging Extension C# All commands Implementation

We have integrated following in the existing sample
1. Adaptive card on search
2. Connector Card on search
3. Result Grid
3. Default Query initial run set to true

* ME Search Review comments Update

* ME Search Build issue Fixes

* Removed commented code from connector card json

* Messaging Extension Review comments fixes

* Manifest Update

* Search review fixes

* ME Search Issue fixes

* Review comments update

* ME Search Review comment fixes

* Revert "ME Search Review comment fixes"

This reverts commit 1996329.

* Code cleanup

* Merge issue Fix

* ME Search Merge issues Fixes

* ME Search Revert changes

* msgext search cards update

* Update appsettings.json

* Fixing Build issues and comments

Co-authored-by: Wajeed-msft <[email protected]>
  • Loading branch information
Trinetra-MSFT and Wajeed-msft authored Jun 10, 2021
1 parent 6d7b2b9 commit d360da1
Show file tree
Hide file tree
Showing 15 changed files with 261 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the MIT License.

using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Threading;
Expand All @@ -10,36 +11,60 @@
using Microsoft.Bot.Builder.Teams;
using Microsoft.Bot.Schema;
using Microsoft.Bot.Schema.Teams;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace Microsoft.BotBuilderSamples.Bots
{
public class TeamsMessagingExtensionsSearchBot : TeamsActivityHandler
public class TeamsMessagingExtensionsSearchBot : TeamsActivityHandler
{
public readonly string _baseUrl;
public TeamsMessagingExtensionsSearchBot(IConfiguration configuration):base()
{
this._baseUrl = configuration["BaseUrl"];
}

protected override async Task<MessagingExtensionResponse> OnTeamsMessagingExtensionQueryAsync(ITurnContext<IInvokeActivity> turnContext, MessagingExtensionQuery query, CancellationToken cancellationToken)
{
var text = query?.Parameters?[0]?.Value as string ?? string.Empty;

switch (text)
{
case "adaptive card":
MessagingExtensionResponse response = GetAdaptiveCard();
return response;

case "connector card":
MessagingExtensionResponse connectorCard = GetConnectorCard();
return connectorCard;

case "result grid":
MessagingExtensionResponse resultGrid = GetResultGrid();
return resultGrid;
}

var packages = await FindPackages(text);

// We take every row of the results and wrap them in cards wrapped in in MessagingExtensionAttachment objects.
// We take every row of the results and wrap them in cards wrapped in MessagingExtensionAttachment objects.
// The Preview is optional, if it includes a Tap, that will trigger the OnTeamsMessagingExtensionSelectItemAsync event back on this bot.
var attachments = packages.Select(package => {
var previewCard = new ThumbnailCard { Title = package.Item1, Tap = new CardAction { Type = "invoke", Value = package } };
if (!string.IsNullOrEmpty(package.Item5))
{
previewCard.Images = new List<CardImage>() { new CardImage(package.Item5, "Icon") };
}
var attachments = packages.Select(package =>
{
var previewCard = new ThumbnailCard { Title = package.Item1, Tap = new CardAction { Type = "invoke", Value = package } };
if (!string.IsNullOrEmpty(package.Item5))
{
previewCard.Images = new List<CardImage>() { new CardImage(package.Item5, "Icon") };
}

var attachment = new MessagingExtensionAttachment
{
ContentType = HeroCard.ContentType,
Content = new HeroCard { Title = package.Item1 },
Preview = previewCard.ToAttachment()
};
return attachment;
}).ToList();
var attachment = new MessagingExtensionAttachment
{
ContentType = HeroCard.ContentType,
Content = new HeroCard { Title = package.Item1 },
Preview = previewCard.ToAttachment()
};

return attachment;
}).ToList();

// The list of MessagingExtensionAttachments must we wrapped in a MessagingExtensionResult wrapped in a MessagingExtensionResponse.
return new MessagingExtensionResponse
Expand All @@ -52,14 +77,14 @@ protected override async Task<MessagingExtensionResponse> OnTeamsMessagingExtens
}
};
}

protected override Task<MessagingExtensionResponse> OnTeamsMessagingExtensionSelectItemAsync(ITurnContext<IInvokeActivity> turnContext, JObject query, CancellationToken cancellationToken)
{
// The Preview card's Tap should have a Value property assigned, this will be returned to the bot in this event.
var (packageId, version, description, projectUrl, iconUrl) = query.ToObject<(string, string, string, string, string)>();

// We take every row of the results and wrap them in cards wrapped in in MessagingExtensionAttachment objects.
// The Preview is optional, if it includes a Tap, that will trigger the OnTeamsMessagingExtensionSelectItemAsync event back on this bot.

var card = new ThumbnailCard
{
Title = $"{packageId}, {version}",
Expand Down Expand Up @@ -99,5 +124,114 @@ protected override Task<MessagingExtensionResponse> OnTeamsMessagingExtensionSel
var obj = JObject.Parse(await (new HttpClient()).GetStringAsync($"https://azuresearch-usnc.nuget.org/query?q=id:{text}&prerelease=true"));
return obj["data"].Select(item => (item["id"].ToString(), item["version"].ToString(), item["description"].ToString(), item["projectUrl"]?.ToString(), item["iconUrl"]?.ToString()));
}

public MessagingExtensionResponse GetAdaptiveCard()
{
var paths = new[] { ".", "Resources", "RestaurantCard.json" };
string filepath = Path.Combine(paths);
var previewcard = new ThumbnailCard
{
Title = "Adaptive Card",
Text = "Please select to get Adaptive card"
};
var adaptiveList = FetchAdaptive(filepath);
var attachment = new MessagingExtensionAttachment
{
ContentType = "application/vnd.microsoft.card.adaptive",
Content = adaptiveList.Content,
Preview = previewcard.ToAttachment()
};

return new MessagingExtensionResponse
{
ComposeExtension = new MessagingExtensionResult
{
Type = "result",
AttachmentLayout = "list",
Attachments = new List<MessagingExtensionAttachment> { attachment }
}
};
}
public MessagingExtensionResponse GetConnectorCard()
{
var path = new[] { ".", "Resources", "connectorCard.json" };
var filepath = Path.Combine(path);
var previewcard = new ThumbnailCard
{
Title = "O365 Connector Card",
Text = "Please select to get Connector card"
};

var connector = FetchConnector(filepath);
var attachment = new MessagingExtensionAttachment
{
ContentType = O365ConnectorCard.ContentType,
Content = connector.Content,
Preview = previewcard.ToAttachment()
};

return new MessagingExtensionResponse
{
ComposeExtension = new MessagingExtensionResult
{
Type = "result",
AttachmentLayout = "list",
Attachments = new List<MessagingExtensionAttachment> { attachment }
}
};
}

public Attachment FetchAdaptive(string filepath)
{
var adaptiveCardJson = File.ReadAllText(filepath);
var adaptiveCardAttachment = new Attachment
{
ContentType = "application/vnd.microsoft.card.adaptive",
Content = JsonConvert.DeserializeObject(adaptiveCardJson)
};
return adaptiveCardAttachment;
}

public Attachment FetchConnector(string filepath)
{
var connectorCardJson = File.ReadAllText(filepath);
var connectorCardAttachment = new MessagingExtensionAttachment
{
ContentType = O365ConnectorCard.ContentType,
Content = JsonConvert.DeserializeObject(connectorCardJson),

};
return connectorCardAttachment;
}

public MessagingExtensionResponse GetResultGrid()
{
var imageFiles = Directory.EnumerateFiles("wwwroot", "*.*", SearchOption.AllDirectories)
.Where(s => s.EndsWith(".jpg"));

List<MessagingExtensionAttachment> attachments = new List<MessagingExtensionAttachment>();

foreach (string img in imageFiles)
{
var image = img.Split("\\");
var thumbnailCard = new ThumbnailCard();
thumbnailCard.Images = new List<CardImage>() { new CardImage(_baseUrl + "/" + image[1]) };
var attachment = new MessagingExtensionAttachment
{
ContentType = ThumbnailCard.ContentType,
Content = thumbnailCard,
};
attachments.Add(attachment);
}
return new MessagingExtensionResponse
{
ComposeExtension = new MessagingExtensionResult
{
Type = "result",
AttachmentLayout = "grid",
Attachments = attachments
}
};
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
{
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"type": "AdaptiveCard",
"version": "1.0",
"body": [
{
"speak": "Tom's Pie is a pizza restaurant which is rated 9.3 by customers.",
"type": "ColumnSet",
"columns": [
{
"type": "Column",
"width": 2,
"items": [
{
"type": "TextBlock",
"text": "**PIZZA**"
},
{
"type": "TextBlock",
"text": "Tom's Pie",
"weight": "bolder",
"size": "extraLarge",
"spacing": "none"
},
{
"type": "TextBlock",
"text": "4.2 $",
"isSubtle": true,
"spacing": "none"
},
{
"type": "TextBlock",
"text": "**Matt H. said** \"I'm compelled to give this place 5 stars due to the number of times I've chosen to eat here this past year!\"",
"size": "small",
"wrap": true
}
]
},
{
"type": "Column",
"width": 1,
"items": [
{
"type": "Image",
"url": "https://picsum.photos/300?image=882",
"size": "auto"
}
]
}
]
}
],
"actions": [
{
"type": "Action.OpenUrl",
"title": "More Info",
"url": "https://www.youtube.com/watch?v=CH2seLS5Wb0"
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"@context": "https://schema.org/extensions",
"@type": "MessageCard",
"sections": [
{
"activityTitle": "Steve Tweeted",
"activitySubtitle": "With #MicrosoftTeams",
"activityImage": "<<YOUR-BASE-URL>>/MSC12_Oscar_002.jpg"
},
{
"facts": [
{
"name": "Posted By:",
"value": "Steve"
},
{
"name": "Posted At:",
"value": "12:00 PM"
},
{
"name": "Tweet:",
"value": "Hello Everyone!! Good Afternoon :-)"
}
],
"text": "A tweet with #MicrosoftTeams has been posted:"
}
],
"potentialAction": [
{
"@context": "http://schema.org",
"@type": "ViewAction",
"name": "View all Tweets",
"target": [
"https://twitter.com/search?q=%23MicrosoftTeams"
]
}
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

namespace Microsoft.BotBuilderSamples
{
public class Startup
public class Startup
{
public Startup(IConfiguration configuration)
{
Expand Down Expand Up @@ -50,8 +50,6 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
endpoints.MapControllers();
});

// app.UseHttpsRedirection();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,14 @@
"commands": [
{
"id": "searchQuery",
"context": [ "compose", "commandBox" ],
"context": [
"compose",
"commandBox"
],
"description": "Test command to run query",
"title": "Search",
"type": "query",
"initialRun": true,
"parameters": [
{
"name": "searchQuery",
Expand All @@ -45,5 +49,8 @@
}
]
}
],
"validDomains": [
"<<YOUR-BASE-URL-DOMAIN>>"
]
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"MicrosoftAppId": "",
"MicrosoftAppPassword": ""
"MicrosoftAppPassword": "",
"BaseURL":""
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit d360da1

Please sign in to comment.