Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Johtaylo/messageextensions #1752

Merged
merged 3 commits into from
Sep 6, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

<ItemGroup>
<ProjectReference Include="..\Microsoft.Bot.Connector.Teams\Microsoft.Bot.Connector.Teams.csproj" Exclude="Runtime" DevelopmentDependency="true" />
<ProjectReference Include="..\Microsoft.Bot.Schema.Teams\Microsoft.Bot.Schema.Teams.csproj" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -49,40 +49,52 @@ public class TeamsActivityHandler : ActivityHandler

protected virtual Task<InvokeResponse> OnInvokeActivityAsync(ITurnContext<IInvokeActivity> turnContext, CancellationToken cancellationToken)
{
switch (turnContext.Activity.Name)
if (turnContext.Activity.Name == null)
{
case "signin/verifyState":
return OnSigninVerifyStateAsync(turnContext, cancellationToken);
return OnCardActionInvokeAsync(turnContext, cancellationToken);
}
else
{
switch (turnContext.Activity.Name)
{
case "signin/verifyState":
return OnSigninVerifyStateAsync(turnContext, cancellationToken);

case "fileConsent/invoke":
return OnFileConsent(turnContext, JObject.FromObject(turnContext.Activity.Value).ToObject<FileConsentCardResponse>(), cancellationToken);
case "fileConsent/invoke":
return OnFileConsent(turnContext, JObject.FromObject(turnContext.Activity.Value).ToObject<FileConsentCardResponse>(), cancellationToken);

case "composeExtension/query":
return OnMessagingExtensionQueryAsync(turnContext, JObject.FromObject(turnContext.Activity.Value).ToObject<MessagingExtensionQuery>(), cancellationToken);
case "composeExtension/query":
return OnMessagingExtensionQueryAsync(turnContext, JObject.FromObject(turnContext.Activity.Value).ToObject<MessagingExtensionQuery>(), cancellationToken);

case "actionableMessage/executeAction":
return OnO365ConnectorCardActionAsync(turnContext, cancellationToken);
case "actionableMessage/executeAction":
return OnO365ConnectorCardActionAsync(turnContext, cancellationToken);

case "composeExtension/queryLink":
return OnAppBasedLinkQueryAsync(turnContext, cancellationToken);
case "composeExtension/queryLink":
return OnAppBasedLinkQueryAsync(turnContext, cancellationToken);

case "composeExtension/fetchTask":
return OnMessagingExtensionFetchTaskAsync(turnContext, cancellationToken);
case "composeExtension/fetchTask":
return OnMessagingExtensionFetchTaskAsync(turnContext, cancellationToken);

case "composeExtension/submitAction":
return OnMessagingExtensionSubmitActionAsync(turnContext, cancellationToken);
case "composeExtension/submitAction":
return OnMessagingExtensionSubmitActionAsync(turnContext, cancellationToken);

case "task/fetch":
return OnTaskModuleFetchAsync(turnContext, cancellationToken);
case "task/fetch":
return OnTaskModuleFetchAsync(turnContext, cancellationToken);

case "task/submit":
return OnTaskModuleSubmitAsync(turnContext, cancellationToken);
case "task/submit":
return OnTaskModuleSubmitAsync(turnContext, cancellationToken);

default:
return Task.FromResult<InvokeResponse>(null);
default:
return Task.FromResult<InvokeResponse>(null);
}
}
}

protected virtual Task<InvokeResponse> OnCardActionInvokeAsync(ITurnContext<IInvokeActivity> turnContext, CancellationToken cancellationToken)
{
return Task.FromResult<InvokeResponse>(null);
}

protected virtual Task<InvokeResponse> OnSigninVerifyStateAsync(ITurnContext<IInvokeActivity> turnContext, CancellationToken cancellationToken)
{
return Task.FromResult<InvokeResponse>(null);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using Microsoft.Bot.Builder.Integration.AspNet.Core;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;

namespace Microsoft.BotBuilderSamples
{
public class AdapterWithErrorHandler : BotFrameworkHttpAdapter
{
public AdapterWithErrorHandler(IConfiguration configuration, ILogger<BotFrameworkHttpAdapter> logger)
: base(configuration, logger)
{
OnTurnError = async (turnContext, exception) =>
{
// Log any leaked exception from the application.
logger.LogError($"Exception caught : {exception.Message}");

// Send a catch-all apology to the user.
await turnContext.SendActivityAsync("Sorry, it looks like something went wrong.");
};
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Bot.Builder;
using Microsoft.Bot.Builder.Teams.Internal;
using Microsoft.Bot.Connector;
using Microsoft.Bot.Connector.Teams;
using Microsoft.Bot.Schema;
using Microsoft.Bot.Schema.Teams;
using Newtonsoft.Json.Linq;

namespace Microsoft.BotBuilderSamples.Bots
{
public class CardActionsBot : TeamsActivityHandler
{
protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
{
//await turnContext.SendActivityAsync(MessageFactory.Text($"MessagingExtensions echo: {turnContext.Activity.Text}"), cancellationToken);

var connectorClient = turnContext.TurnState.Get<IConnectorClient>();
var teamsConnectorClient = new TeamsConnectorClient(connectorClient.Credentials);
teamsConnectorClient.BaseUri = new Uri(turnContext.Activity.ServiceUrl);
var teamsContext = new TeamsContext(turnContext, teamsConnectorClient);

string actualText = teamsContext.GetActivityTextWithoutMentions();
if (actualText.Equals("Cards", StringComparison.OrdinalIgnoreCase))
{
// Demo card 1 - adaptive card with bot bulder actions
AdaptiveCards.AdaptiveCard adaptiveCard = new AdaptiveCards.AdaptiveCard();
adaptiveCard.Body.Add(new AdaptiveCards.AdaptiveTextBlock("Bot Builder actions"));

var action1 = new CardAction("imback", "imBack", null, null, null, "text");
var action2 = new CardAction("messageBack", "message back", null, "text received by bots", "text display to users", JObject.Parse(@"{ ""key"" : ""value"" }"));
var action3 = new CardAction("invoke", "invoke", null, null, null, JObject.Parse(@"{ ""key"" : ""value"" }"));
var action4 = new CardAction("openUrl", "Buckethead", null, null, null, "https://en.wikipedia.org/wiki/Buckethead");
var action5 = new CardAction("invoke", "a special invoke", null, "text on an invoke", "display text", JObject.Parse(@"{ ""key"" : ""value"" }"));
adaptiveCard.Actions.Add(action1.ToAdaptiveCardAction());
adaptiveCard.Actions.Add(action2.ToAdaptiveCardAction());
adaptiveCard.Actions.Add(action3.ToAdaptiveCardAction());
adaptiveCard.Actions.Add(action4.ToAdaptiveCardAction());
adaptiveCard.Actions.Add(action5.ToAdaptiveCardAction());

// Task module action
var taskModuleAction = new TaskModuleAction("Launch Task Module", @"{ ""hiddenKey"": ""hidden value from task module launcher"" }");

// Demo card 2 - launch task module from adaptive card
AdaptiveCards.AdaptiveCard taskModuleCard1 = new AdaptiveCards.AdaptiveCard();
taskModuleCard1.Body.Add(new AdaptiveCards.AdaptiveTextBlock("Task Module Adaptive Card"));
taskModuleCard1.Actions.Add(taskModuleAction.ToAdaptiveCardAction());

// Demo card 3 - launch task module from hero card (or any bot-builder framework card)
HeroCard taskModuleCard2 = new HeroCard("Launch Task Module", null, null, null, new List<CardAction> { taskModuleAction });


var replyActivity = MessageFactory.Attachment(new Attachment[] { adaptiveCard.ToAttachment(), taskModuleCard1.ToAttachment(), taskModuleCard2.ToAttachment() });

await turnContext.SendActivityAsync(replyActivity, cancellationToken);
}
else
{
await turnContext.SendActivityAsync(MessageFactory.Text($"You said: {turnContext.Activity.Text}"), cancellationToken);
}
}

protected override Task<InvokeResponse> OnInvokeActivityAsync(ITurnContext<IInvokeActivity> turnContext, CancellationToken cancellationToken)
{
return base.OnInvokeActivityAsync(turnContext, cancellationToken);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>netcoreapp2.1</TargetFramework>
<LangVersion>latest</LangVersion>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.Bot.Builder.Integration.AspNet.Core" Version="4.5.1" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\Microsoft.Bot.Builder.Teams\Microsoft.Bot.Builder.Teams.csproj" />
</ItemGroup>

<ItemGroup>
<Content Update="appsettings.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Bot.Builder;
using Microsoft.Bot.Builder.Integration.AspNet.Core;

namespace Microsoft.BotBuilderSamples.Controllers
{
// This ASP Controller is created to handle a request. Dependency Injection will provide the Adapter and IBot
// implementation at runtime. Multiple different IBot implementations running at different endpoints can be
// achieved by specifying a more specific type for the bot constructor argument.
[Route("api/messages")]
[ApiController]
public class BotController : ControllerBase
{
private readonly IBotFrameworkHttpAdapter Adapter;
private readonly IBot Bot;

public BotController(IBotFrameworkHttpAdapter adapter, IBot bot)
{
Adapter = adapter;
Bot = bot;
}

[HttpPost]
public async Task PostAsync()
{
// Delegate the processing of the HTTP POST to the adapter.
// The adapter will invoke the bot.
await Adapter.ProcessAsync(Request, Response, Bot);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;

namespace Microsoft.BotBuilderSamples
{
public class Program
{
public static void Main(string[] args)
{
CreateWebHostBuilder(args).Build().Run();
}

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"$schema": "http://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:3978",
"sslPort": 0
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"EchoBot": {
"commandName": "Project",
"launchBrowser": true,
"applicationUrl": "https://localhost:3979;http://localhost:3978",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Bot.Builder;
using Microsoft.Bot.Builder.Integration.AspNet.Core;
using Microsoft.BotBuilderSamples.Bots;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

namespace Microsoft.BotBuilderSamples
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}

public IConfiguration Configuration { get; }

// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

// Create the Bot Framework Adapter with error handling enabled.
services.AddSingleton<IBotFrameworkHttpAdapter, AdapterWithErrorHandler>();

// Create the bot as a transient. In this case the ASP Controller is expecting an IBot.
services.AddTransient<IBot, CardActionsBot>();
}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseHsts();
}

app.UseDefaultFiles();
app.UseStaticFiles();

//app.UseHttpsRedirection();
app.UseMvc();
}
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{
"$schema": "https://developer.microsoft.com/en-us/json-schemas/teams/v1.3/MicrosoftTeams.schema.json",
"manifestVersion": "1.3",
"version": "1.0.0",
"id": "528d4825-cca3-420a-bb88-712fbf54e6ca",
"packageName": "com.teams.sample.echobot",
"developer": {
"name": "Add & Remove Bot",
"websiteUrl": "https://www.microsoft.com",
"privacyUrl": "https://www.teams.com/privacy",
"termsOfUseUrl": "https://www.teams.com/termsofuser"
},
"icons": {
"color": "color.png",
"outline": "outline.png"
},
"name": {
"short": "Team Member Add & Remove",
"full": "Team Member Add & Remove"
},
"description": {
"short": "Team Member Add & Remove",
"full": "Team Member Add & Remove"
},
"accentColor": "#FFFFFF",
"bots": [
{
"botId": "528d4825-cca3-420a-bb88-712fbf54e6ca",
"scopes": [
"groupchat",
"team"
],
"supportsFiles": false,
"isNotificationOnly": false
}
],
"permissions": [
"identity",
"messageTeamMembers"
],
"validDomains": []
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading