8000 Support bot new invoke type: config · microsoft/botbuilder-dotnet@c93d725 · GitHub
[go: up one dir, main page]

Skip to content

Commit c93d725

Browse files
author
Ying Du
committed
Support bot new invoke type: config
1 parent bb6a077 commit c93d725

14 files changed

+431
-0
lines changed

libraries/Microsoft.Bot.Builder/Teams/TeamsActivityHandler.cs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,12 @@ protected override async Task<InvokeResponse> OnInvokeActivityAsync(ITurnContext
9292
case "tab/submit":
9393
return CreateInvokeResponse(await OnTeamsTabSubmitAsync(turnContext, SafeCast<TabSubmit>(turnContext.Activity.Value), cancellationToken).ConfigureAwait(false));
9494

95+
case "config/fetch":
96+
return CreateInvokeResponse(await OnTeamsConfigFetchAsync(turnContext, turnContext.Activity.Value as JObject, cancellationToken).ConfigureAwait(false));
97+
98+
case "config/submit":
99+
return CreateInvokeResponse(await OnTeamsConfigSubmitAsync(turnContext, turnContext.Activity.Value as JObject, cancellationToken).ConfigureAwait(false));
100+
95101
default:
96102
return await base.OnInvokeActivityAsync(turnContext, cancellationToken).ConfigureAwait(false);
97103
}
@@ -431,6 +437,32 @@ protected virtual Task<TabResponse> OnTeamsTabSubmitAsync(ITurnContext<IInvokeAc
431437
throw new InvokeResponseException(HttpStatusCode.NotImplemented);
432438
}
433439

440+
/// <summary>
441+
/// Override this in a derived class to provide logic for when a config is fetched.
442+
/// </summary>
443+
/// <param name="turnContext">A strongly-typed context object for this turn.</param>
444+
/// <param name="configData">The config fetch invoke request value payload.</param>
445+
/// <param name="cancellationToken">A cancellation token that can be used by other objects
446+
/// or threads to receive notice of cancellation.</param>
447+
/// <returns>A Config Response for the request.</returns>
448+
protected virtual Task<InvokeResponseBase> OnTeamsConfigFetchAsync(ITurnContext<IInvokeActivity> turnContext, JObject configData, CancellationToken cancellationToken)
449+
{
450+
throw new InvokeResponseException(HttpStatusCode.NotImplemented);
451+
}
452+
453+
/// <summary>
454+
/// Override this in a derived class to provide logic for when a config is submitted.
455+
/// </summary>
456+
/// <param name="turnContext">A strongly-typed context object for this turn.</param>
457+
/// <param name="configData">The config fetch invoke request value payload.</param>
458+
/// <param name="cancellationToken">A cancellation token that can be used by other objects
459+
/// or threads to receive notice of cancellation.</param>
460+
/// <returns>A Config Response for the request.</returns>
461+
protected virtual Task<InvokeResponseBase> OnTeamsConfigSubmitAsync(ITurnContext<IInvokeActivity> turnContext, JObject configData, CancellationToken cancellationToken)
462+
{
463+
throw new InvokeResponseException(HttpStatusCode.NotImplemented);
464+
}
465+
434466
/// <summary>
435467
/// Invoked when a conversation update activity is received from the channel.
436468
/// Conversation update activities are useful when it comes to responding to users being added to or removed from the channel.
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
using Newtonsoft.Json;
4+
5+
namespace Microsoft.Bot.Schema.Teams
6+
{
7+
/// <summary>
8+
/// Specifies bot config auth, including type and suggestedActions.
9+
/// </summary>
10+
public partial class BotConfigAuth
11+
{
12+
/// <summary>
13+
/// Initializes a new instance of the <see cref="BotConfigAuth"/> class.
14+
/// </summary>
15+
public BotConfigAuth()
16+
{
17+
CustomInit();
18+
}
19+
20+
/// <summary>
21+
/// Gets or sets type of bot config auth.
22+
/// </summary>
23+
/// <value>
24+
/// The type of bot config auth.
25+
/// </value>
26+
[JsonProperty(PropertyName = "type")]
27+
public string Type { get; set; } = "auth";
28+
29+
/// <summary>
30+
/// Gets or sets suggested actions.
31+
/// </summary>
32+
/// <value>
33+
/// The suggested actions of bot config auth.
34+
/// </value>
35+
[JsonProperty(PropertyName = "suggestedActions")]
36+
public SuggestedActions SuggestedActions { get; set; }
37+
38+
/// <summary>
39+
/// An initialization method that performs custom operations like setting defaults.
40+
/// </summary>
41+
partial void CustomInit();
42+
}
43+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
namespace Microsoft.Bot.Schema.Teams
5+
{
6+
/// <summary>
7+
/// Envelope for Config Auth Response.
8+
/// </summary>
9+
public partial class ConfigAuthResponse : ConfigResponse<BotConfigAuth>
10+
{
11+
/// <summary>
12+
/// Initializes a new instance of the <see cref="ConfigAuthResponse"/> class.
13+
/// </summary>
14+
public ConfigAuthResponse()
15+
{
16+
CustomInit();
17+
}
18+
19+
/// <summary>
20+
/// An initialization method that performs custom operations like setting defaults.
21+
/// </summary>
22+
partial void CustomInit();
23+
}
24+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
namespace Microsoft.Bot.Schema.Teams
5+
{
6+
using Newtonsoft.Json;
7+
8+
/// <summary>
9+
/// Envelope for Config Response Payload.
10+
/// </summary>
11+
/// <typeparam name="T">The first generic type parameter.</typeparam>.
12+
public partial class ConfigResponse<T> : InvokeResponseBase
13+
{
14+
/// <summary>
15+
/// Initializes a new instance of the <see cref="ConfigResponse{T}"/> class.
16+
/// </summary>
17+
public ConfigResponse()
18+
: base("config")
19+
{
20+
CustomInit();
21+
}
22+
23+
/// <summary>
24+
/// Gets or sets the response to the config message.
25+
/// Possible values for the config type include: 'auth'or 'task'.
26+
/// </summary>
27+
/// <value>
28+
/// Response to a config request.
29+
/// </value>
30+
[JsonProperty(PropertyName = "config")]
31+
public T Config { get; set; }
32+
33+
/// <summary>
34+
/// An initialization method that performs custom operations like setting defaults.
35+
/// </summary>
36+
partial void CustomInit();
37+
}
38+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
namespace Microsoft.Bot.Schema.Teams
5+
{
6+
/// <summary>
7+
/// Envelope for Config Task Response.
8+
/// </summary>
9+
public partial class ConfigTaskResponse : ConfigResponse<TaskModuleResponseBase>
10+
{
11+
/// <summary>
12+
/// Initializes a new instance of the <see cref="ConfigTaskResponse"/> class.
13+
/// </summary>
14+
public ConfigTaskResponse()
15+
{
16+
CustomInit();
17+
}
18+
19+
/// <summary>
20+
/// An initialization method that performs custom operations like setting defaults.
21+
/// </summary>
22+
partial void CustomInit();
23+
}
24+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
using Newtonsoft.Json;
5+
6+
namespace Microsoft.Bot.Schema.Teams
7+
{
8+
/// <summary>
9+
/// Specifies Invoke response base including response type.
10+
/// </summary>
11+
public partial class InvokeResponseBase
12+
{
13+
/// <summary>
14+
/// Initializes a new instance of the <see cref="InvokeResponseBase"/> class.
15+
/// </summary>
16+
protected InvokeResponseBase()
17+
{
18+
}
19+
20+
/// <summary>
21+
/// Initializes a new instance of the <see cref="InvokeResponseBase"/> class.
22+
/// </summary>
23+
/// <param name="responseType"> response type for invoke.</param>
24+
protected InvokeResponseBase(string responseType)
25+
{
26+
ResponseType = responseType;
27+
}
28+
29+
/// <summary>
30+
/// Gets or sets response type invoke request.
31+
/// </summary>
32+
/// <value> Invoke request response type.</value>
33+
[JsonProperty("responseType")]
34+
public string ResponseType { get; set; }
35+
36+
/// <summary>
37+
/// Gets or sets response cache Info.
38+
/// </summary>
39+
/// <value> Value of cache info. </value>
40+
[JsonProperty(PropertyName = "cacheInfo")]
41+
public CacheInfo CacheInfo { get; set; }
42+
}
43+
}

tests/Microsoft.Bot.Builder.Tests/Teams/TeamsActivityHandlerNotImplementedTests.cs

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -484,6 +484,66 @@ void CaptureSend(Activity[] arg)
484484
Assert.Equal(501, ((InvokeResponse)activitiesToSend[0].Value).Status);
485485
}
486486

487+
[Fact]
488+
public async Task TestConfigFetch()
489+
{
490+
// Arrange
491+
var activity = new Activity
492+
{
493+
Type = ActivityTypes.Invoke,
494+
Name = "config/fetch",
495+
Value = JObject.Parse(@"{""data"":{""key"":""value"",""type"":""config / fetch""},""context"":{""theme"":""default""}}"),
496+
};
497+
498+
Activity[] activitiesToSend = null;
499+
void CaptureSend(Activity[] arg)
500+
{
501+
activitiesToSend = arg;
502+
}
503+
504+
var turnContext = new TurnContext(new SimpleAdapter(CaptureSend), activity);
505+
506+
// Act
507+
var bot = new TestActivityHandler();
508+
await ((IBot)bot).OnTurnAsync(turnContext);
509+
510+
// Assert
511+
Assert.NotNull(activitiesToSend);
512+
Assert.Single(activitiesToSend);
513+
Assert.IsType<InvokeResponse>(activitiesToSend[0].Value);
514+
Assert.Equal(501, ((InvokeResponse)activitiesToSend[0].Value).Status);
515+
}
516+
517+
[Fact]
518+
public async Task TestConfigSubmit()
519+
{
520+
// Arrange
521+
var activity = new Activity
522+
{
523+
Type = ActivityTypes.Invoke,
524+
Name = "config/submit",
525+
Value = JObject.Parse(@"{""data"":{""key"":""value"",""type"":""config / submit""},""context"":{""theme"":""default""}}"),
526+
};
527+
528+
Activity[] activitiesToSend = null;
529+
void CaptureSend(Activity[] arg)
530+
{
531+
activitiesToSend = arg;
532+
}
533+
534+
var turnContext = new TurnContext(new SimpleAdapter(CaptureSend), activity);
535+
536+
// Act
537+
var bot = new TestActivityHandler();
538+
await ((IBot)bot).OnTurnAsync(turnContext);
539+
540+
// Assert
541+
Assert.NotNull(activitiesToSend);
542+
Assert.Single(activitiesToSend);
543+
Assert.IsType<InvokeResponse>(activitiesToSend[0].Value);
544+
Assert.Equal(501, ((InvokeResponse)activitiesToSend[0].Value).Status);
545+
}
546+
487547
[Fact]
488548
public async Task TestFileConsentAcceptImplemented()
489549
{

tests/Microsoft.Bot.Builder.Tests/Teams/TeamsActivityHandlerTests.cs

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1052,6 +1052,72 @@ void CaptureSend(Activity[] arg)
10521052
Assert.Equal(200, ((InvokeResponse)activitiesToSend[0].Value).Status);
10531053
}
10541054

1055+
[Fact]
1056+
public async Task TestConfigFetch()
1057+
{
1058+
// Arrange
1059+
var activity = new Activity
1060+
{
1061+
Type = ActivityTypes.Invoke,
1062+
Name = "config/fetch",
1063+
Value = JObject.Parse(@"{""data"":{""key"":""value"",""type"":""config / fetch""},""context"":{""theme"":""default""}}"),
1064+
};
1065+
1066+
Activity[] activitiesToSend = null;
1067+
void CaptureSend(Activity[] arg)
1068+
{
1069+
activitiesToSend = arg;
1070+
}
1071+
1072+
var turnContext = new TurnContext(new SimpleAdapter(CaptureSend), activity);
1073+
1074+
// Act
1075+
var bot = new TestActivityHandler();
1076+
await ((IBot)bot).OnTurnAsync(turnContext);
1077+
1078+
// Assert
1079+
//Assert.Equal(2, bot.Record.Count);
1080+
Assert.Equal("OnInvokeActivityAsync", bot.Record[0]);
1081+
Assert.Equal("OnTeamsConfigFetchAsync", bot.Record[1]);
1082+
Assert.NotNull(activitiesToSend);
1083+
Assert.Single(activitiesToSend);
1084+
Assert.IsType<InvokeResponse>(activitiesToSend[0].Value);
1085+
Assert.Equal(200, ((InvokeResponse)activitiesToSend[0].Value).Status);
1086+
}
1087+
1088+
[Fact]
1089+
public async Task TestConfigSubmit()
1090+
{
1091+
// Arrange
1092+
var activity = new Activity
1093+
{
1094+
Type = ActivityTypes.Invoke,
1095+
Name = "config/submit",
1096+
Value = JObject.Parse(@"{""data"":{""key"":""value"",""type"":""config / submit""},""context"":{""theme"":""default""}}"),
1097+
};
1098+
1099+
Activity[] activitiesToSend = null;
1100+
void CaptureSend(Activity[] arg)
1101+
{
1102+
activitiesToSend = arg;
1103+
}
1104+
1105+
var turnContext = new TurnContext(new SimpleAdapter(CaptureSend), activity);
1106+
1107+
// Act
1108+
var bot = new TestActivityHandler();
1109+
await ((IBot)bot).OnTurnAsync(turnContext);
1110+
1111+
// Assert
1112+
//Assert.Equal(2, bot.Record.Count);
1113+
Assert.Equal("OnInvokeActivityAsync", bot.Record[0]);
1114+
Assert.Equal("OnTeamsConfigSubmitAsync", bot.Record[1]);
1115+
Assert.NotNull(activitiesToSend);
1116+
Assert.Single(activitiesToSend);
1117+
Assert.IsType<InvokeResponse>(activitiesToSend[0].Value);
1118+
Assert.Equal(200, ((InvokeResponse)activitiesToSend[0].Value).Status);
1119+
}
1120+
10551121
[Fact]
10561122
public async Task TestSigninVerifyState()
10571123
{
@@ -1609,6 +1675,20 @@ protected override Task<TabResponse> OnTeamsTabSubmitAsync(ITurnContext<IInvokeA
16091675
return Task.FromResult(new TabResponse());
16101676
}
16111677

1678+
protected override Task<InvokeResponseBase> OnTeamsConfigFetchAsync(ITurnContext<IInvokeActivity> turnContext, JObject configRequest, CancellationToken cancellationToken)
1679+
{
1680+
InvokeResponseBase configResponse = new ConfigTaskResponse();
1681+
Record.Add(MethodBase.GetCurrentMethod().Name);
1682+
return Task.FromResult(configResponse);
1683+
}
1684+
1685+
protected override Task<InvokeResponseBase> OnTeamsConfigSubmitAsync(ITurnContext<IInvokeActivity> turnContext, JObject configRequest, CancellationToken cancellationToken)
1686+
{
1687+
InvokeResponseBase configResponse = new ConfigTaskResponse();
1688+
Record.Add(MethodBase.GetCurrentMethod().Name);
1689+
return Task.FromResult(configResponse);
1690+
}
1691+
16121692
protected override Task OnEventActivityAsync(ITurnContext<IEventActivity> turnContext, CancellationToken cancellationToken)
16131693
{
16141694
Record.Add(MethodBase.GetCurrentMethod().Name);

0 commit comments

Comments
 (0)
0