// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
using System.Text;
using System.Text.Json;
using Microsoft.Bot.Builder.Integration.AspNet.Core.Handlers;
using Microsoft.Bot.Schema;
using Microsoft.Bot.Schema.Teams;
using Microsoft.Teams.Core.Schema;
using Newtonsoft.Json;
namespace Microsoft.Teams.Apps.BotBuilder;
///
/// Extension methods for converting between Bot Framework Activity and CoreActivity/TeamsActivity.
///
public static class ActivitySchemaMapper
{
private static string? GetStringValue(object? value) => value switch
{
null => null,
string s => s,
JsonElement { ValueKind: JsonValueKind.String } el => el.GetString(),
JsonElement el => el.GetRawText(),
_ => value.ToString()
};
///
/// Converts a to a Bot Framework .
///
/// The core activity to convert.
/// The equivalent Bot Framework activity.
public static Activity ToBotFrameworkActivity(this CoreActivity activity)
{
ArgumentNullException.ThrowIfNull(activity);
using JsonTextReader reader = new(new StringReader(activity.ToJson()));
return BotMessageHandlerBase.BotMessageSerializer.Deserialize(reader)!;
}
///
/// Converts a Bot Framework to a .
///
/// The Bot Framework activity to convert.
/// The equivalent core activity.
public static CoreActivity FromBotFrameworkActivity(this Activity activity)
{
StringBuilder sb = new();
using StringWriter stringWriter = new(sb);
using JsonTextWriter json = new(stringWriter);
BotMessageHandlerBase.BotMessageSerializer.Serialize(json, activity);
string jsonString = sb.ToString();
return CoreActivity.FromJsonString(jsonString);
}
///
/// Converts a to a Bot Framework .
///
/// The conversation account to convert.
/// The equivalent channel account.
public static Microsoft.Bot.Schema.ChannelAccount ToCompatChannelAccount(this Microsoft.Teams.Core.Schema.ChannelAccount account)
{
ArgumentNullException.ThrowIfNull(account);
Microsoft.Bot.Schema.ChannelAccount channelAccount;
channelAccount = new()
{
Id = account.Id,
Name = account.Name
};
if (account.Properties.TryGetValue("aadObjectId", out object? aadObjectId))
{
channelAccount.AadObjectId = GetStringValue(aadObjectId);
}
if (account.Properties.TryGetValue("userRole", out object? userRole))
{
channelAccount.Role = GetStringValue(userRole);
}
if (account.Properties.TryGetValue("userPrincipalName", out object? userPrincipalName))
{
channelAccount.Properties.Add("userPrincipalName", GetStringValue(userPrincipalName) ?? string.Empty);
}
if (account.Properties.TryGetValue("givenName", out object? givenName))
{
channelAccount.Properties.Add("givenName", GetStringValue(givenName) ?? string.Empty);
}
if (account.Properties.TryGetValue("surname", out object? surname))
{
channelAccount.Properties.Add("surname", GetStringValue(surname) ?? string.Empty);
}
if (account.Properties.TryGetValue("email", out object? email))
{
channelAccount.Properties.Add("email", GetStringValue(email) ?? string.Empty);
}
if (account.Properties.TryGetValue("tenantId", out object? tenantId))
{
channelAccount.Properties.Add("tenantId", GetStringValue(tenantId) ?? string.Empty);
}
return channelAccount;
}
///
/// Converts a to a with all known properties.
///
/// The conversation account to convert.
/// The equivalent Teams channel account.
public static Microsoft.Bot.Schema.Teams.TeamsChannelAccount ToCompatTeamsChannelAccount2(this Microsoft.Teams.Core.Schema.ChannelAccount account)
{
ArgumentNullException.ThrowIfNull(account);
return new Microsoft.Bot.Schema.Teams.TeamsChannelAccount
{
Id = account.Id,
Name = account.Name,
AadObjectId = GetStringValue(account.Properties["aadObjectId"]) ?? string.Empty,
Email = GetStringValue(account.Properties["email"]) ?? string.Empty,
GivenName = GetStringValue(account.Properties["givenName"]) ?? string.Empty,
Surname = GetStringValue(account.Properties["surname"]) ?? string.Empty,
UserPrincipalName = GetStringValue(account.Properties["userPrincipalName"]) ?? string.Empty,
UserRole = GetStringValue(account.Properties["userRole"]) ?? string.Empty,
TenantId = GetStringValue(account.Properties["tenantId"]) ?? string.Empty
};
}
///
/// Converts a Core PagedMembersResult to a Bot Framework TeamsPagedMembersResult.
///
/// The paged members result to convert.
/// The equivalent Bot Framework paged members result.
public static Microsoft.Bot.Schema.Teams.TeamsPagedMembersResult ToCompatTeamsPagedMembersResult(this Microsoft.Teams.Core.PagedMembersResult pagedMembers)
{
ArgumentNullException.ThrowIfNull(pagedMembers);
return new Microsoft.Bot.Schema.Teams.TeamsPagedMembersResult
{
ContinuationToken = pagedMembers.ContinuationToken,
Members = pagedMembers.Members?.Select(m => m.ToCompatTeamsChannelAccount()).ToList()
};
}
///
/// Converts a to a .
///
/// The conversation account to convert.
/// The equivalent Teams channel account.
public static Microsoft.Bot.Schema.Teams.TeamsChannelAccount ToCompatTeamsChannelAccount(this Microsoft.Teams.Core.Schema.ChannelAccount account)
{
ArgumentNullException.ThrowIfNull(account);
TeamsChannelAccount teamsChannelAccount = new()
{
Id = account.Id,
Name = account.Name
};
// Extract properties from Properties dictionary
if (account.Properties.TryGetValue("aadObjectId", out object? aadObjectId))
{
teamsChannelAccount.AadObjectId = GetStringValue(aadObjectId);
}
if (account.Properties.TryGetValue("userPrincipalName", out object? userPrincipalName))
{
teamsChannelAccount.UserPrincipalName = GetStringValue(userPrincipalName);
}
if (account.Properties.TryGetValue("givenName", out object? givenName))
{
teamsChannelAccount.GivenName = GetStringValue(givenName);
}
if (account.Properties.TryGetValue("surname", out object? surname))
{
teamsChannelAccount.Surname = GetStringValue(surname);
}
if (account.Properties.TryGetValue("email", out object? email))
{
teamsChannelAccount.Email = GetStringValue(email);
}
if (account.Properties.TryGetValue("tenantId", out object? tenantId))
{
teamsChannelAccount.Properties.Add("tenantId", GetStringValue(tenantId) ?? string.Empty);
}
return teamsChannelAccount;
}
///
/// Converts a Bot Framework ChannelAccount to a Core ChannelAccount.
///
public static Microsoft.Teams.Core.Schema.ChannelAccount FromCompatChannelAccount(this Microsoft.Bot.Schema.ChannelAccount account)
{
ArgumentNullException.ThrowIfNull(account);
Microsoft.Teams.Core.Schema.ChannelAccount result = new() { Id = account.Id, Name = account.Name };
if (!string.IsNullOrEmpty(account.AadObjectId))
{
result.Properties["aadObjectId"] = account.AadObjectId;
}
if (!string.IsNullOrEmpty(account.Role))
{
result.Properties["userRole"] = account.Role;
}
return result;
}
///
/// Converts a Bot Framework ConversationParameters to a Core ConversationParameters.
///
public static Microsoft.Teams.Core.ConversationParameters FromCompatConversationParameters(this Microsoft.Bot.Schema.ConversationParameters parameters)
{
ArgumentNullException.ThrowIfNull(parameters);
return new Microsoft.Teams.Core.ConversationParameters
{
IsGroup = parameters.IsGroup,
Bot = parameters.Bot?.FromCompatChannelAccount(),
Members = parameters.Members?.Select(m => m.FromCompatChannelAccount()).ToList(),
TopicName = parameters.TopicName,
Activity = parameters.Activity?.FromBotFrameworkActivity(),
ChannelData = parameters.ChannelData,
TenantId = parameters.TenantId,
};
}
///
/// Gets the TeamInfo object from the current activity.
///
/// The activity.
/// The current activity's team's information, or null.
public static TeamInfo? TeamsGetTeamInfo(this IActivity activity)
{
ArgumentNullException.ThrowIfNull(activity);
Microsoft.Bot.Schema.Teams.TeamsChannelData channelData = activity.GetChannelData();
return channelData?.Team;
}
}