Skip to content

Commit

Permalink
fix class model, update reference. unit test. unit tests pass, manual…
Browse files Browse the repository at this point in the history
… tests pass
  • Loading branch information
Ying Du committed Jan 21, 2023
1 parent 9d9997b commit 2779c8c
Show file tree
Hide file tree
Showing 19 changed files with 340 additions and 204 deletions.
4 changes: 2 additions & 2 deletions libraries/Microsoft.Bot.Builder/Teams/TeamsInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -326,8 +326,8 @@ await turnContext.Adapter.CreateConversationAsync(
/// <param name="cancellationToken">Cancellation token.</param>
/// <remarks>InvalidOperationException will be thrown if meetingId or notification have not been
/// provided, and also cannot be retrieved from turnContext.Activity.</remarks>
/// <returns>List of <see cref="TeamsMeetingNotificationRecipientFailureInfo"/> for whom the notification failed.</returns>
public static async Task<TeamsMeetingNotificationRecipientFailureInfos> SendMeetingNotificationAsync(ITurnContext turnContext, TeamsMeetingNotification notification, string meetingId = null, CancellationToken cancellationToken = default)
/// <returns>List of <see cref="NotificationRecipientFailureInfo"/> for whom the notification failed.</returns>
public static async Task<NotificationRecipientFailureInfos> SendMeetingNotificationAsync(ITurnContext turnContext, BotMeetingNotificationBase notification, string meetingId = null, CancellationToken cancellationToken = default)
{
meetingId ??= turnContext.Activity.TeamsGetMeetingInfo()?.Id ?? throw new InvalidOperationException("This method is only valid within the scope of a MS Teams Meeting.");
notification = notification ?? throw new InvalidOperationException($"{nameof(notification)} is required.");
Expand Down
6 changes: 3 additions & 3 deletions libraries/Microsoft.Bot.Connector/Teams/TeamsOperations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ public TeamsOperations(TeamsConnectorClient client)
/// <returns>
/// A response object containing the response body and response headers.
/// </returns>
public async Task<HttpOperationResponse<TeamsMeetingNotificationRecipientFailureInfos>> SendMeetingNotificationMessageAsync(string meetingId, TeamsMeetingNotification notification, Dictionary<string, List<string>> customHeaders = null, CancellationToken cancellationToken = default(CancellationToken))
public async Task<HttpOperationResponse<NotificationRecipientFailureInfos>> SendMeetingNotificationMessageAsync(string meetingId, BotMeetingNotificationBase notification, Dictionary<string, List<string>> customHeaders = null, CancellationToken cancellationToken = default(CancellationToken))
{
if (meetingId == null)
{
Expand Down Expand Up @@ -351,7 +351,7 @@ public TeamsOperations(TeamsConnectorClient client)

// Create HTTP transport objects
#pragma warning disable CA2000 // Dispose objects before losing scope
var result = new HttpOperationResponse<TeamsMeetingNotificationRecipientFailureInfos>();
var result = new HttpOperationResponse<NotificationRecipientFailureInfos>();
#pragma warning restore CA2000 // Dispose objects before losing scope
try
{
Expand Down Expand Up @@ -416,7 +416,7 @@ public TeamsOperations(TeamsConnectorClient client)
responseContent = await httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false);
try
{
result.Body = Rest.Serialization.SafeJsonConvert.DeserializeObject<TeamsMeetingNotificationRecipientFailureInfos>(responseContent, Client.DeserializationSettings);
result.Body = Rest.Serialization.SafeJsonConvert.DeserializeObject<NotificationRecipientFailureInfos>(responseContent, Client.DeserializationSettings);
}
catch (JsonException ex)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ public static partial class TeamsOperationsExtensions
/// The cancellation token.
/// </param>
/// <returns>Information regarding which participant notifications failed.</returns>
public static async Task<TeamsMeetingNotificationRecipientFailureInfos> SendMeetingNotificationAsync(this ITeamsOperations operations, string meetingId, TeamsMeetingNotification notification, CancellationToken cancellationToken = default(CancellationToken))
public static async Task<NotificationRecipientFailureInfos> SendMeetingNotificationAsync(this ITeamsOperations operations, string meetingId, BotMeetingNotificationBase notification, CancellationToken cancellationToken = default(CancellationToken))
{
if (operations is TeamsOperations teamsOperations)
{
Expand Down
90 changes: 90 additions & 0 deletions libraries/Microsoft.Bot.Schema/Converters/SurfaceConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System;
using Microsoft.Bot.Schema.Teams;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace Microsoft.Bot.Schema.Converters
{
/// <summary>
/// Converter which allows json to be expression to object or static object.
/// </summary>
public class SurfaceConverter : JsonConverter
{
/// <summary>
/// Gets a value indicating whether this Converter can write JSON.
/// </summary>
/// <value>true if this Converter can write JSON; otherwise, false.</value>
public override bool CanWrite => false;

/// <summary>
/// Gets a value indicating whether this Converter can read JSON.
/// </summary>
/// <value>true if this Converter can read JSON; otherwise, false.</value>
public override bool CanRead => true;

/// <summary>
/// Determines whether this instance can convert the specified object type.
/// </summary>
/// <param name="objectType">Type of the object.</param>
/// <returns>
/// <c>true</c> if this instance can convert the specified object type; otherwise, <c>false</c>.
/// </returns>
public override bool CanConvert(Type objectType)
{
return objectType == typeof(Surface);
}

/// <summary>
/// Reads the JSON representation of the object.
/// </summary>
/// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
/// <param name="objectType">Type of the object.</param>
/// <param name="existingValue">The existing value of object being read.</param>
/// <param name="serializer">The calling serializer.</param>
/// <returns>The object value.</returns>
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var jsonObject = JObject.Load(reader);
var surfaceType = jsonObject["surface"]?.ToObject<SurfaceType>();

Surface parsedSurface;
switch (surfaceType)
{
case SurfaceType.MeetingStage:
var contentType = jsonObject["contentType"]?.ToObject<ContentType>();
parsedSurface = CreateMeetingStageSurfaceWithContentType(contentType);
break;
default:
throw new ArgumentException($"Invalid surface type: {surfaceType}");
}

serializer.Populate(jsonObject.CreateReader(), parsedSurface);
return parsedSurface;
}

/// <summary>
/// Writes the JSON representation of the object.
/// </summary>
/// <param name="writer">The Newtonsoft.Json.JsonWriter to write to.</param>
/// <param name="value">The value.</param>
/// <param name="serializer">The calling serializer.</param>
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotSupportedException();
}

private static Surface CreateMeetingStageSurfaceWithContentType(ContentType? contentType)
{
switch (contentType)
{
case ContentType.Task:
return new MeetingStageSurface<TaskModuleContinueResponse>();
default:
throw new ArgumentException($"Invalid content type: {contentType}");
}
}
}
}
23 changes: 23 additions & 0 deletions libraries/Microsoft.Bot.Schema/Teams/BotMeetingNotification.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

namespace Microsoft.Bot.Schema.Teams
{
using Newtonsoft.Json;

/// <summary>
/// Specifies bot meeting notification including channel data, type and value.
/// </summary>
/// <typeparam name="T">The first generic type parameter.</typeparam>.
public abstract class BotMeetingNotification<T> : BotMeetingNotificationBase
{
/// <summary>
/// Gets or sets Teams meeting notification information.
/// </summary>
/// <value>
/// Teams meeting notification information.
/// </value>
[JsonProperty(PropertyName = "value")]
public T Value { get; set; }
}
}
38 changes: 38 additions & 0 deletions libraries/Microsoft.Bot.Schema/Teams/BotMeetingNotificationBase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using Newtonsoft.Json;

namespace Microsoft.Bot.Schema.Teams
{
/// <summary>
/// Specifies bot meeting notification base including channel data and type.
/// </summary>
public class BotMeetingNotificationBase
{
/// <summary>
/// Initializes a new instance of the <see cref="BotMeetingNotificationBase"/> class.
/// </summary>
protected BotMeetingNotificationBase()
{
}

/// <summary>
/// Gets or sets Activty type.
/// </summary>
/// <value>
/// Activity type.
/// </value>
[JsonProperty("type")]
public string Type { get; set; }

/// <summary>
/// Gets or sets Teams meeting notification channel data.
/// </summary>
/// <value>
/// Teams meeting notification channel data.
/// </value>
[JsonProperty("channelData")]
public BotMeetingNotificationChannelData ChannelData { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ namespace Microsoft.Bot.Schema.Teams
using Newtonsoft.Json;

/// <summary>
/// Container for list of <see cref="OnBehalfOf"/> information for a meeting <see cref="TeamsMeetingNotificationChannelData"/>.
/// Container for list of <see cref="OnBehalfOf"/> information for a meeting <see cref="BotMeetingNotificationChannelData"/>.
/// </summary>
public partial class TeamsMeetingNotificationChannelData
public partial class BotMeetingNotificationChannelData
{
/// <summary>
/// Initializes a new instance of the <see cref="TeamsMeetingNotificationChannelData"/> class.
/// Initializes a new instance of the <see cref="BotMeetingNotificationChannelData"/> class.
/// </summary>
public TeamsMeetingNotificationChannelData()
public BotMeetingNotificationChannelData()
{
CustomInit();
}
Expand All @@ -25,7 +25,7 @@ public TeamsMeetingNotificationChannelData()
/// <value>The meeting notification's <see cref="OnBehalfOf"/>.</value>
#pragma warning disable CA2227 // Collection properties should be read only (we can't change this without breaking binary compat)>
[JsonProperty(PropertyName = "OnBehalfOf")]
public IList<TeamsMeetingNotificationOnBehalfOf> OnBehalfOf { get; set; }
public IList<OnBehalfOf> OnBehalfOf { get; set; }
#pragma warning restore CA2227 // Collection properties should be read only

/// <summary>
Expand Down
21 changes: 21 additions & 0 deletions libraries/Microsoft.Bot.Schema/Teams/ContentType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

namespace Microsoft.Bot.Schema.Teams
{
/// <summary>
/// Defines content type type.
/// </summary>
public enum ContentType
{
/// <summary>
/// Content type is Unknown.
/// </summary>
Unknown,

/// <summary>
/// Content type is Task.
/// </summary>
Task
}
}
48 changes: 48 additions & 0 deletions libraries/Microsoft.Bot.Schema/Teams/MeetingStageSurface.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

namespace Microsoft.Bot.Schema.Teams
{
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;

/// <summary>
/// Specifies if a notification is to be sent for the mentions.
/// </summary>
/// <typeparam name="T">The first generic type parameter.</typeparam>.
public partial class MeetingStageSurface<T> : Surface
{
/// <summary>
/// Initializes a new instance of the <see cref="MeetingStageSurface{T}"/> class.
/// </summary>
public MeetingStageSurface()
: base(SurfaceType.MeetingStage)
{
CustomInit();
}

/// <summary>
/// Gets or sets the content type of this <see cref="MeetingStageSurface{T}"/>.
/// </summary>
/// <value>
/// The content type of this <see cref="MeetingStageSurface{T}"/>.
/// </value>
[JsonConverter(typeof(StringEnumConverter))]
[JsonProperty(PropertyName = "contentType")]
public ContentType ContentType { get; set; }

/// <summary>
/// Gets or sets the content for this <see cref="MeetingStageSurface{T}"/>.
/// </summary>
/// <value>
/// The content type of this <see cref="MeetingStageSurface{T}"/>.
/// </value>
[JsonProperty(PropertyName = "content")]
public T Content { get; set; }

/// <summary>
/// An initialization method that performs custom operations like setting defaults.
/// </summary>
partial void CustomInit();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,28 @@
namespace Microsoft.Bot.Schema.Teams
{
/// <summary>
/// Information regarding failure to notify a recipient of a <see cref="TeamsMeetingNotification"/>.
/// Information regarding failure to notify a recipient of a <see cref="TargetedMeetingNotification"/>.
/// </summary>
public class TeamsMeetingNotificationRecipientFailureInfo
public class NotificationRecipientFailureInfo
{
/// <summary>
/// Gets or sets the mri for a recipient <see cref="TeamsMeetingNotification"/> failure.
/// Gets or sets the mri for a recipient <see cref="TargetedMeetingNotification"/> failure.
/// </summary>
/// <value>The type of this notification container.</value>
[JsonProperty(PropertyName = "recipientMri")]
public string RecipientMri { get; set; }

/// <summary>
/// Gets or sets the error code for a <see cref="TeamsMeetingNotification"/>.
/// Gets or sets the error code for a <see cref="TargetedMeetingNotification"/>.
/// </summary>
/// <value>The error code for a <see cref="TeamsMeetingNotification"/>.</value>
/// <value>The error code for a <see cref="TargetedMeetingNotification"/>.</value>
[JsonProperty(PropertyName = "errorcode")]
public string ErrorCode { get; set; }

/// <summary>
/// Gets or sets the failure reason for a <see cref="TeamsMeetingNotification"/> failure.
/// Gets or sets the failure reason for a <see cref="TargetedMeetingNotification"/> failure.
/// </summary>
/// <value>The reason why a participant <see cref="TeamsMeetingNotification"/> failed.</value>
/// <value>The reason why a participant <see cref="TargetedMeetingNotification"/> failed.</value>
[JsonProperty(PropertyName = "failureReason")]
public string FailureReason { get; set; }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,26 @@
namespace Microsoft.Bot.Schema.Teams
{
/// <summary>
/// Container for <see cref="TeamsMeetingNotificationRecipientFailureInfo"/>, which is the result of a
/// failure to notify recipients of a <see cref="TeamsMeetingNotification"/>.
/// Container for <see cref="NotificationRecipientFailureInfo"/>, which is the result of a
/// failure to notify recipients of a <see cref="TargetedMeetingNotification"/>.
/// </summary>
public partial class TeamsMeetingNotificationRecipientFailureInfos
public partial class NotificationRecipientFailureInfos
{
/// <summary>
/// Initializes a new instance of the <see cref="TeamsMeetingNotificationRecipientFailureInfos"/> class.
/// Initializes a new instance of the <see cref="NotificationRecipientFailureInfos"/> class.
/// </summary>
public TeamsMeetingNotificationRecipientFailureInfos()
public NotificationRecipientFailureInfos()
{
CustomInit();
}

/// <summary>
/// Gets or sets the list of <see cref="TeamsMeetingNotificationRecipientFailureInfos"/>.
/// Gets or sets the list of <see cref="NotificationRecipientFailureInfos"/>.
/// </summary>
/// <value>The list of recipients who did not receive a <see cref="TeamsMeetingNotification"/> including error information.</value>
/// <value>The list of recipients who did not receive a <see cref="TargetedMeetingNotification"/> including error information.</value>
[JsonProperty(PropertyName = "recipientsFailureInfo")]
#pragma warning disable CA2227 // Collection properties should be read only (we can't change this without breaking binary compat)>
public IList<TeamsMeetingNotificationRecipientFailureInfo> RecipientsFailureInfo { get; set; }
public IList<NotificationRecipientFailureInfo> RecipientsFailureInfo { get; set; }
#pragma warning restore CA2227 // Collection properties should be read only

/// <summary>
Expand Down
Loading

0 comments on commit 2779c8c

Please sign in to comment.