* Rebasing Teams GetParticipant

* remove meeting parameter from TeamsChannelData

* Add inMeeting to TeamsParticipantChannelAccount

* Add Send Task Module Continue and Message adaptive responses

* add some comments

* Add more teams actions

* Fix copy/paste 'url' issue

* Cleanup SendMessagingExtensionActionResponse

* Add CacheInfo base class for InvokeResponses

* Add GetMember and some schema files

* Continue response updates

* Schema updates

* Add actions for TeamsInfo methods

* updaete schema and uischema

* Cleanup teams responses and schema files

* More teams adaptive schema cleanup

* New teams actions and some cleanup

* More Teams adaptive additions and cleanup

* schema updates

* Revert TeamsInfo app credentials breaking change

* Rebasing Teams GetParticipant

* remove meeting parameter from TeamsChannelData

* Add inMeeting to TeamsParticipantChannelAccount

* Add Send Task Module Continue and Message adaptive responses

* add some comments

* Add more teams actions

* Fix copy/paste 'url' issue

* Cleanup SendMessagingExtensionActionResponse

* Add CacheInfo base class for InvokeResponses

* Add GetMember and some schema files

* Continue response updates

* Schema updates

* Add actions for TeamsInfo methods

* updaete schema and uischema

* Cleanup teams responses and schema files

* More teams adaptive schema cleanup

* New teams actions and some cleanup

* More Teams adaptive additions and cleanup

* schema updates

* Revert TeamsInfo app credentials breaking change

* Lowerase teams enums

* schema updates

* Change 'activity' to 'card' where appropriate

* Add Michael Richardsons Teams Actions tests

* Teams ActionTests

* cleanup adaptive teams tests

* sync tests w/ @mdrichardson branch

* fix schema errors

* check for missing Card

* Some cleanup and code consolidation

* Update ExpressionExtensions.cs

* Review feedback

* Fix Teams trigger and action namespaces

* schema updates

Co-authored-by: Michael Richardson <v-micric@microsoft.com>
This commit is contained in:
Eric Dahlvang 2021-02-01 16:56:20 -08:00 коммит произвёл GitHub
Родитель 512604fa4b
Коммит 93290fa0f8
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
175 изменённых файлов: 8570 добавлений и 221 удалений

Просмотреть файл

@ -0,0 +1,52 @@
// Licensed under the MIT License.
// Copyright (c) Microsoft Corporation. All rights reserved.
using AdaptiveExpressions.Properties;
using Newtonsoft.Json;
namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Teams.Actions
{
/// <summary>
/// Base class for a url and card Task Module Continue responses.
/// </summary>
public abstract class BaseSendTaskModuleContinueResponse : BaseTeamsCacheInfoResponseDialog
{
/// <summary>
/// Gets or sets the text or expression to use to generate the title of the response.
/// </summary>
/// <value>
/// Title of the response.
/// </value>
[JsonProperty("title")]
public StringExpression Title { get; set; }
/// <summary>
/// Gets or sets an optional expression for the height of the response.
/// </summary>
/// <value>
/// An integer expression.
/// </value>
[JsonProperty("height")]
public IntExpression Height { get; set; }
/// <summary>
/// Gets or sets an optional expression for the width of the response.
/// </summary>
/// <value>
/// An integer expression.
/// </value>
[JsonProperty("width")]
public IntExpression Width { get; set; }
/// <summary>
/// Gets or sets an optional expression for the Completion Bot Id of the Task Module Task Info response.
/// This is a bot App ID to send the result of the user's interaction with the task module to. If
/// specified, the bot will receive a task/submit invoke event with a JSON object in the event payload.
/// </summary>
/// <value>
/// An string expression.
/// </value>
[JsonProperty("completionBotId")]
public StringExpression CompletionBotId { get; set; }
}
}

Просмотреть файл

@ -0,0 +1,107 @@
// Licensed under the MIT License.
// Copyright (c) Microsoft Corporation. All rights reserved.
using System;
using System.Net;
using AdaptiveExpressions.Properties;
using Microsoft.Bot.Schema;
using Microsoft.Bot.Schema.Teams;
using Newtonsoft.Json;
namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Teams.Actions
{
/// <summary>
/// Base dialog for Teams Invoke Responses having a CacheInfo property.
/// </summary>
public abstract class BaseTeamsCacheInfoResponseDialog : Dialog
{
/// <summary>
/// Gets or sets an optional expression which if is true will disable this action.
/// </summary>
/// <example>
/// "user.age > 18".
/// </example>
/// <value>
/// A boolean expression.
/// </value>
[JsonProperty("disabled")]
public BoolExpression Disabled { get; set; }
/// <summary>
/// Gets or sets config CacheType.
/// </summary>
/// <value>
/// "cache" or "no_cache".
/// </value>
[JsonProperty("cacheType")]
public StringExpression CacheType { get; set; }
/// <summary>
/// Gets or sets cache duration in seconds for which the cached object should remain in the cache.
/// </summary>
/// <value>
/// Duration the result should be cached in seconds.
/// </value>
[JsonProperty("cacheDuration")]
public IntExpression CacheDuration { get; set; }
/// <summary>
/// Create an InvokeResponse activity with the specified body.
/// </summary>
/// <param name="body">The body to return in the InvokeResponse.</param>
/// <param name="statusCode"><see cref="HttpStatusCode"/> for the InvokeResponse. Default is HttpStatusCode.OK.</param>
/// <returns>An Activity of type InvokeResponse, containing a Value of InvokeResponse.</returns>
protected static Activity CreateInvokeResponseActivity(object body, int statusCode = (int)HttpStatusCode.OK)
{
return new Activity
{
Value = new InvokeResponse
{
Status = statusCode,
Body = body
},
Type = ActivityTypesEx.InvokeResponse
};
}
protected Activity CreateMessagingExtensionInvokeResponseActivity(DialogContext dc, MessagingExtensionResult result)
{
switch (dc.Context.Activity.Name)
{
case "composeExtension/queryLink":
case "composeExtension/query":
case "composeExtension/selectItem":
case "composeExtension/querySettingUrl":
return CreateInvokeResponseActivity(new MessagingExtensionResponse() { ComposeExtension = result, CacheInfo = GetCacheInfo(dc) });
case "composeExtension/submitAction":
case "composeExtension/fetchTask":
return CreateInvokeResponseActivity(new MessagingExtensionActionResponse() { ComposeExtension = result, CacheInfo = GetCacheInfo(dc) });
default:
throw new InvalidOperationException($"GetMessagingExtensionResponse Invalid Activity.Name: {dc.Context.Activity.Name}");
}
}
/// <summary>
/// Retrieve a Cache Info object from the CacheType and CacheDuration, if present.
/// </summary>
/// <param name="dc">Dialog Context to use for retrieving CacheType and CacheDuration from state.</param>
/// <returns>A <see cref="CacheInfo"/> object if <see cref="CacheDuration"/>
/// and <see cref="CacheType"/> resolve to valid values.</returns>
protected CacheInfo GetCacheInfo(DialogContext dc)
{
if (CacheType != null && CacheDuration != null)
{
var cacheType = CacheType.GetValueOrNull(dc.State);
var cacheDuration = CacheDuration.GetValueOrNull(dc.State);
if (cacheDuration.HasValue && cacheDuration.Value > 0 && !string.IsNullOrEmpty(cacheType))
{
// Valid ranges for CacheDuration are 60 < > 2592000
cacheDuration = Math.Min(Math.Max(60, cacheDuration.Value), 2592000);
return new CacheInfo(cacheType: cacheType, cacheDuration: cacheDuration.Value);
}
}
return null;
}
}
}

Просмотреть файл

@ -0,0 +1,44 @@
// Licensed under the MIT License.
// Copyright (c) Microsoft Corporation. All rights reserved.
using System;
using AdaptiveExpressions.Properties;
using Microsoft.Bot.Builder.Dialogs.Memory;
namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Teams.Actions
{
internal static class ExpressionExtensions
{
internal static int? GetValueOrNull(this IntExpression expression, DialogStateManager state)
{
if (expression != null)
{
var (value, valueError) = expression.TryGetValue(state);
if (valueError != null)
{
throw new InvalidOperationException($"Expression evaluation resulted in an error. Expression: {expression.ExpressionText}. Error: {valueError}");
}
return value;
}
return null;
}
internal static string GetValueOrNull(this StringExpression expression, DialogStateManager state)
{
if (expression != null)
{
var (value, valueError) = expression.TryGetValue(state);
if (valueError != null)
{
throw new InvalidOperationException($"Expression evaluation resulted in an error. Expression: {expression.ExpressionText}. Error: {valueError}");
}
return value as string;
}
return null;
}
}
}

Просмотреть файл

@ -6,12 +6,12 @@ using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using AdaptiveExpressions.Properties;
using Microsoft.Bot.Builder.Dialogs.Adaptive.Teams.Actions;
using Microsoft.Bot.Builder.Teams;
using Microsoft.Bot.Connector;
using Microsoft.Bot.Schema.Teams;
using Newtonsoft.Json;
namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Teams.Actions
{
/// <summary>
/// Calls TeamsInfo.GetMeetingParticipantAsync and sets the result to a memory property.
@ -99,31 +99,34 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
throw new ArgumentException($"{nameof(options)} cannot be a cancellation token");
}
if (this.Disabled != null && this.Disabled.GetValue(dc.State) == true)
if (this.Disabled != null && this.Disabled.GetValue(dc.State))
{
return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
}
if (dc.Context.Activity.ChannelId != Channels.Msteams)
{
throw new InvalidOperationException("TeamsInfo.GetMeetingParticipantAsync() works only on the Teams channel.");
throw new InvalidOperationException($"{Kind} works only on the Teams channel.");
}
string meetingId = GetValueOrNull(dc, this.MeetingId);
string participantId = GetValueOrNull(dc, this.ParticipantId);
string tenantId = GetValueOrNull(dc, this.TenantId);
string meetingId = MeetingId.GetValueOrNull(dc.State);
string participantId = ParticipantId.GetValueOrNull(dc.State);
string tenantId = TenantId.GetValueOrNull(dc.State);
if (participantId == null)
{
// TeamsInfo.GetMeetingParticipantAsync will default to retrieving the current meeting's participant
// if none is provided. This could lead to unexpected results. Therefore, GetMeetingParticipant action
// throws an exception if the expression provided somehow maps to an invalid result.
throw new InvalidOperationException($"GetMeetingParticipant could determine the participant id by expression value provided. {nameof(participantId)} is required.");
throw new InvalidOperationException($"{Kind} could not determine the participant id by expression value provided. {nameof(participantId)} is required.");
}
var result = await TeamsInfo.GetMeetingParticipantAsync(dc.Context, meetingId, participantId, tenantId, cancellationToken: cancellationToken).ConfigureAwait(false);
dc.State.SetValue(this.Property.GetValue(dc.State), result);
if (this.Property != null)
{
dc.State.SetValue(this.Property.GetValue(dc.State), result);
}
return await dc.EndDialogAsync(result, cancellationToken: cancellationToken).ConfigureAwait(false);
}
@ -136,21 +139,5 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions
{
return $"{this.GetType().Name}[{this.MeetingId?.ToString() ?? string.Empty},{this.ParticipantId?.ToString() ?? string.Empty},{this.TenantId?.ToString() ?? string.Empty},{this.Property?.ToString() ?? string.Empty}]";
}
private string GetValueOrNull(DialogContext dc, StringExpression stringExpression)
{
if (stringExpression != null)
{
var (value, valueError) = stringExpression.TryGetValue(dc.State);
if (valueError != null)
{
throw new InvalidOperationException($"Expression evaluation resulted in an error. Expression: \"{stringExpression.ExpressionText}\". Error: {valueError}");
}
return value as string;
}
return null;
}
}
}

Просмотреть файл

@ -0,0 +1,120 @@
// Licensed under the MIT License.
// Copyright (c) Microsoft Corporation. All rights reserved.
using System;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using AdaptiveExpressions.Properties;
using Microsoft.Bot.Builder.Dialogs.Adaptive.Teams.Actions;
using Microsoft.Bot.Builder.Teams;
using Microsoft.Bot.Connector;
using Microsoft.Bot.Schema.Teams;
using Newtonsoft.Json;
namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Teams.Actions
{
/// <summary>
/// Calls TeamsInfo.GetMember and sets the result to a memory property.
/// </summary>
public class GetMember : Dialog
{
/// <summary>
/// Class identifier.
/// </summary>
[JsonProperty("$kind")]
public const string Kind = "Teams.GetMember";
/// <summary>
/// Initializes a new instance of the <see cref="GetMember"/> class.
/// </summary>
/// <param name="callerPath">Optional, source file full path.</param>
/// <param name="callerLine">Optional, line number in source file.</param>
[JsonConstructor]
public GetMember([CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
: base()
{
this.RegisterSourceLocation(callerPath, callerLine);
}
/// <summary>
/// Gets or sets an optional expression which if is true will disable this action.
/// </summary>
/// <example>
/// "user.age > 18".
/// </example>
/// <value>
/// A boolean expression.
/// </value>
[JsonProperty("disabled")]
public BoolExpression Disabled { get; set; }
/// <summary>
/// Gets or sets property path to put the value in.
/// </summary>
/// <value>
/// Property path to put the value in.
/// </value>
[JsonProperty("property")]
public StringExpression Property { get; set; }
/// <summary>
/// Gets or sets the expression to get the value to use for member id.
/// </summary>
/// <value>
/// The expression to get the value to use for member id. Default value is turn.activity.from.id.
/// </value>
[JsonProperty("memberId")]
public StringExpression MemberId { get; set; } = "=turn.activity.from.id";
/// <summary>
/// Called when the dialog is started and pushed onto the dialog stack.
/// </summary>
/// <param name="dc">The <see cref="DialogContext"/> for the current turn of conversation.</param>
/// <param name="options">Optional, initial information to pass to the dialog.</param>
/// <param name="cancellationToken">A cancellation token that can be used by other objects
/// or threads to receive notice of cancellation.</param>
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
public override async Task<DialogTurnResult> BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken))
{
if (options is CancellationToken)
{
throw new ArgumentException($"{nameof(options)} cannot be a cancellation token");
}
if (this.Disabled != null && this.Disabled.GetValue(dc.State))
{
return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
}
if (dc.Context.Activity.ChannelId != Channels.Msteams)
{
throw new InvalidOperationException($"{Kind} works only on the Teams channel.");
}
string memberId = MemberId.GetValueOrNull(dc.State);
if (string.IsNullOrEmpty(memberId))
{
throw new InvalidOperationException($"Missing {nameof(MemberId)} in {Kind}.");
}
var result = await TeamsInfo.GetMemberAsync(dc.Context, memberId, cancellationToken: cancellationToken).ConfigureAwait(false);
if (this.Property != null)
{
dc.State.SetValue(this.Property.GetValue(dc.State), result);
}
return await dc.EndDialogAsync(result, cancellationToken: cancellationToken).ConfigureAwait(false);
}
/// <summary>
/// Builds the compute Id for the dialog.
/// </summary>
/// <returns>A string representing the compute Id.</returns>
protected override string OnComputeId()
{
return $"{this.GetType().Name}[{this.MemberId?.ToString() ?? string.Empty},{this.Property?.ToString() ?? string.Empty}]";
}
}
}

Просмотреть файл

@ -0,0 +1,126 @@
// Licensed under the MIT License.
// Copyright (c) Microsoft Corporation. All rights reserved.
using System;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using AdaptiveExpressions.Properties;
using Microsoft.Bot.Builder.Dialogs.Adaptive.Teams.Actions;
using Microsoft.Bot.Builder.Teams;
using Microsoft.Bot.Connector;
using Newtonsoft.Json;
namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Teams.Actions
{
/// <summary>
/// Calls TeamsInfo.GetPagedMembers to retrieve a paginated list of members of
/// one-on-one, group, or team conversation and sets the result to a memory property.
/// </summary>
public class GetPagedMembers : Dialog
{
/// <summary>
/// Class identifier.
/// </summary>
[JsonProperty("$kind")]
public const string Kind = "Teams.GetPagedMembers";
/// <summary>
/// Initializes a new instance of the <see cref="GetPagedMembers"/> class.
/// </summary>
/// <param name="callerPath">Optional, source file full path.</param>
/// <param name="callerLine">Optional, line number in source file.</param>
[JsonConstructor]
public GetPagedMembers([CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
: base()
{
RegisterSourceLocation(callerPath, callerLine);
}
/// <summary>
/// Gets or sets an optional expression which if is true will disable this action.
/// </summary>
/// <example>
/// "user.age > 18".
/// </example>
/// <value>
/// A boolean expression.
/// </value>
[JsonProperty("disabled")]
public BoolExpression Disabled { get; set; }
/// <summary>
/// Gets or sets property path to put the value in.
/// </summary>
/// <value>
/// Property path to put the value in.
/// </value>
[JsonProperty("property")]
public StringExpression Property { get; set; }
/// <summary>
/// Gets or sets the expression to get the value to use for the continuationToken.
/// </summary>
/// <value>
/// The expression to get the value to use for continuationToken. Default value is null.
/// </value>
[JsonProperty("continuationToken")]
public StringExpression ContinuationToken { get; set; }
/// <summary>
/// Gets or sets the expression to get the value to use for the page size.
/// </summary>
/// <value>
/// The expression to get the value to use for page size. Default value is null.
/// </value>
[JsonProperty("pageSize")]
public IntExpression PageSize { get; set; }
/// <summary>
/// Called when the dialog is started and pushed onto the dialog stack.
/// </summary>
/// <param name="dc">The <see cref="DialogContext"/> for the current turn of conversation.</param>
/// <param name="options">Optional, initial information to pass to the dialog.</param>
/// <param name="cancellationToken">A cancellation token that can be used by other objects
/// or threads to receive notice of cancellation.</param>
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
public override async Task<DialogTurnResult> BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default)
{
if (options is CancellationToken)
{
throw new ArgumentException($"{nameof(options)} cannot be a cancellation token");
}
if (Disabled != null && Disabled.GetValue(dc.State) == true)
{
return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
}
if (dc.Context.Activity.ChannelId != Channels.Msteams)
{
throw new InvalidOperationException($"{Kind} works only on the Teams channel.");
}
string continuationToken = ContinuationToken.GetValueOrNull(dc.State);
int? pageSize = PageSize.GetValueOrNull(dc.State);
var result = await TeamsInfo.GetPagedMembersAsync(dc.Context, pageSize, continuationToken, cancellationToken: cancellationToken).ConfigureAwait(false);
if (Property != null)
{
dc.State.SetValue(Property.GetValue(dc.State), result);
}
return await dc.EndDialogAsync(result, cancellationToken: cancellationToken).ConfigureAwait(false);
}
/// <summary>
/// Builds the compute Id for the dialog.
/// </summary>
/// <returns>A string representing the compute Id.</returns>
protected override string OnComputeId()
{
return $"{GetType().Name}[{ContinuationToken?.ToString() ?? string.Empty},{PageSize?.ToString() ?? string.Empty},{Property?.ToString() ?? string.Empty}]";
}
}
}

Просмотреть файл

@ -0,0 +1,136 @@
// Licensed under the MIT License.
// Copyright (c) Microsoft Corporation. All rights reserved.
using System;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using AdaptiveExpressions.Properties;
using Microsoft.Bot.Builder.Dialogs.Adaptive.Teams.Actions;
using Microsoft.Bot.Builder.Teams;
using Microsoft.Bot.Connector;
using Newtonsoft.Json;
namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Teams.Actions
{
/// <summary>
/// Calls TeamsInfo.GetPagedTeamMembers to retrieve a paginated list of members of a team.
/// Also sets the result to a memory property.
/// </summary>
public class GetPagedTeamMembers : Dialog
{
/// <summary>
/// Class identifier.
/// </summary>
[JsonProperty("$kind")]
public const string Kind = "Teams.GetPagedTeamMembers";
/// <summary>
/// Initializes a new instance of the <see cref="GetPagedTeamMembers"/> class.
/// </summary>
/// <param name="callerPath">Optional, source file full path.</param>
/// <param name="callerLine">Optional, line number in source file.</param>
[JsonConstructor]
public GetPagedTeamMembers([CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
: base()
{
this.RegisterSourceLocation(callerPath, callerLine);
}
/// <summary>
/// Gets or sets an optional expression which if is true will disable this action.
/// </summary>
/// <example>
/// "user.age > 18".
/// </example>
/// <value>
/// A boolean expression.
/// </value>
[JsonProperty("disabled")]
public BoolExpression Disabled { get; set; }
/// <summary>
/// Gets or sets property path to put the value in.
/// </summary>
/// <value>
/// Property path to put the value in.
/// </value>
[JsonProperty("property")]
public StringExpression Property { get; set; }
/// <summary>
/// Gets or sets the expression to get the value to use for the continuationToken.
/// </summary>
/// <value>
/// The expression to get the value to use for continuationToken. Default value is null.
/// </value>
[JsonProperty("continuationToken")]
public StringExpression ContinuationToken { get; set; }
/// <summary>
/// Gets or sets the expression to get the value to use for the page size.
/// </summary>
/// <value>
/// The expression to get the value to use for page size. Default value is null.
/// </value>
[JsonProperty("pageSize")]
public IntExpression PageSize { get; set; }
/// <summary>
/// Gets or sets the expression to get the value to use for team id.
/// </summary>
/// <value>
/// The expression to get the value to use for team id. Default value is turn.activity.channelData.team.id.
/// </value>
[JsonProperty("teamId")]
public StringExpression TeamId { get; set; } = "=turn.activity.channelData.team.id";
/// <summary>
/// Called when the dialog is started and pushed onto the dialog stack.
/// </summary>
/// <param name="dc">The <see cref="DialogContext"/> for the current turn of conversation.</param>
/// <param name="options">Optional, initial information to pass to the dialog.</param>
/// <param name="cancellationToken">A cancellation token that can be used by other objects
/// or threads to receive notice of cancellation.</param>
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
public override async Task<DialogTurnResult> BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken))
{
if (options is CancellationToken)
{
throw new ArgumentException($"{nameof(options)} cannot be a cancellation token");
}
if (this.Disabled != null && this.Disabled.GetValue(dc.State))
{
return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
}
if (dc.Context.Activity.ChannelId != Channels.Msteams)
{
throw new InvalidOperationException($"{Kind} works only on the Teams channel.");
}
string continuationToken = ContinuationToken.GetValueOrNull(dc.State);
string teamId = TeamId.GetValueOrNull(dc.State);
int? pageSize = PageSize.GetValueOrNull(dc.State);
var result = await TeamsInfo.GetPagedTeamMembersAsync(dc.Context, teamId, continuationToken, pageSize, cancellationToken: cancellationToken).ConfigureAwait(false);
if (this.Property != null)
{
dc.State.SetValue(this.Property.GetValue(dc.State), result);
}
return await dc.EndDialogAsync(result, cancellationToken: cancellationToken).ConfigureAwait(false);
}
/// <summary>
/// Builds the compute Id for the dialog.
/// </summary>
/// <returns>A string representing the compute Id.</returns>
protected override string OnComputeId()
{
return $"{this.GetType().Name}[{this.TeamId?.ToString() ?? string.Empty},{this.PageSize?.ToString() ?? string.Empty},{this.ContinuationToken?.ToString() ?? string.Empty},{this.Property?.ToString() ?? string.Empty}]";
}
}
}

Просмотреть файл

@ -0,0 +1,117 @@
// Licensed under the MIT License.
// Copyright (c) Microsoft Corporation. All rights reserved.
using System;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using AdaptiveExpressions.Properties;
using Microsoft.Bot.Builder.Dialogs.Adaptive.Teams.Actions;
using Microsoft.Bot.Builder.Teams;
using Microsoft.Bot.Connector;
using Microsoft.Bot.Schema.Teams;
using Newtonsoft.Json;
namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Teams.Actions
{
/// <summary>
/// Calls TeamsInfo.GetTeamChannels to retrieve a list of channels in a
/// Team and sets the result to a memory property. This only works in
/// teams scoped conversations.
/// </summary>
public class GetTeamChannels : Dialog
{
/// <summary>
/// Class identifier.
/// </summary>
[JsonProperty("$kind")]
public const string Kind = "Teams.GetTeamChannels";
/// <summary>
/// Initializes a new instance of the <see cref="GetTeamChannels"/> class.
/// </summary>
/// <param name="callerPath">Optional, source file full path.</param>
/// <param name="callerLine">Optional, line number in source file.</param>
[JsonConstructor]
public GetTeamChannels([CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
: base()
{
this.RegisterSourceLocation(callerPath, callerLine);
}
/// <summary>
/// Gets or sets an optional expression which if is true will disable this action.
/// </summary>
/// <example>
/// "user.age > 18".
/// </example>
/// <value>
/// A boolean expression.
/// </value>
[JsonProperty("disabled")]
public BoolExpression Disabled { get; set; }
/// <summary>
/// Gets or sets property path to put the value in.
/// </summary>
/// <value>
/// Property path to put the value in.
/// </value>
[JsonProperty("property")]
public StringExpression Property { get; set; }
/// <summary>
/// Gets or sets the expression to get the value to use for team id.
/// </summary>
/// <value>
/// The expression to get the value to use for team id. Default value is turn.activity.channelData.team.id.
/// </value>
[JsonProperty("teamId")]
public StringExpression TeamId { get; set; } = "=turn.activity.channelData.team.id";
/// <summary>
/// Called when the dialog is started and pushed onto the dialog stack.
/// </summary>
/// <param name="dc">The <see cref="DialogContext"/> for the current turn of conversation.</param>
/// <param name="options">Optional, initial information to pass to the dialog.</param>
/// <param name="cancellationToken">A cancellation token that can be used by other objects
/// or threads to receive notice of cancellation.</param>
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
public override async Task<DialogTurnResult> BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken))
{
if (options is CancellationToken)
{
throw new ArgumentException($"{nameof(options)} cannot be a cancellation token");
}
if (this.Disabled != null && this.Disabled.GetValue(dc.State))
{
return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
}
if (dc.Context.Activity.ChannelId != Channels.Msteams)
{
throw new InvalidOperationException($"{Kind} works only on the Teams channel.");
}
string teamId = TeamId.GetValueOrNull(dc.State);
var result = await TeamsInfo.GetTeamChannelsAsync(dc.Context, teamId, cancellationToken: cancellationToken).ConfigureAwait(false);
if (this.Property != null)
{
dc.State.SetValue(this.Property.GetValue(dc.State), result);
}
return await dc.EndDialogAsync(result, cancellationToken: cancellationToken).ConfigureAwait(false);
}
/// <summary>
/// Builds the compute Id for the dialog.
/// </summary>
/// <returns>A string representing the compute Id.</returns>
protected override string OnComputeId()
{
return $"{this.GetType().Name}[{this.TeamId?.ToString() ?? string.Empty},{this.Property?.ToString() ?? string.Empty}]";
}
}
}

Просмотреть файл

@ -0,0 +1,115 @@
// Licensed under the MIT License.
// Copyright (c) Microsoft Corporation. All rights reserved.
using System;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using AdaptiveExpressions.Properties;
using Microsoft.Bot.Builder.Dialogs.Adaptive.Teams.Actions;
using Microsoft.Bot.Builder.Teams;
using Microsoft.Bot.Connector;
using Microsoft.Bot.Schema.Teams;
using Newtonsoft.Json;
namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Teams.Actions
{
/// <summary>
/// Calls TeamsInfo.GetTeamDetails and sets the result to a memory property.
/// </summary>
public class GetTeamDetails : Dialog
{
/// <summary>
/// Class identifier.
/// </summary>
[JsonProperty("$kind")]
public const string Kind = "Teams.GetTeamDetails";
/// <summary>
/// Initializes a new instance of the <see cref="GetTeamDetails"/> class.
/// </summary>
/// <param name="callerPath">Optional, source file full path.</param>
/// <param name="callerLine">Optional, line number in source file.</param>
[JsonConstructor]
public GetTeamDetails([CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
: base()
{
this.RegisterSourceLocation(callerPath, callerLine);
}
/// <summary>
/// Gets or sets an optional expression which if is true will disable this action.
/// </summary>
/// <example>
/// "user.age > 18".
/// </example>
/// <value>
/// A boolean expression.
/// </value>
[JsonProperty("disabled")]
public BoolExpression Disabled { get; set; }
/// <summary>
/// Gets or sets property path to put the value in.
/// </summary>
/// <value>
/// Property path to put the value in.
/// </value>
[JsonProperty("property")]
public StringExpression Property { get; set; }
/// <summary>
/// Gets or sets the expression to get the value to use for team id.
/// </summary>
/// <value>
/// The expression to get the value to use for team id. Default value is turn.activity.channelData.team.id.
/// </value>
[JsonProperty("teamId")]
public StringExpression TeamId { get; set; } = "=turn.activity.channelData.team.id";
/// <summary>
/// Called when the dialog is started and pushed onto the dialog stack.
/// </summary>
/// <param name="dc">The <see cref="DialogContext"/> for the current turn of conversation.</param>
/// <param name="options">Optional, initial information to pass to the dialog.</param>
/// <param name="cancellationToken">A cancellation token that can be used by other objects
/// or threads to receive notice of cancellation.</param>
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
public override async Task<DialogTurnResult> BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken))
{
if (options is CancellationToken)
{
throw new ArgumentException($"{nameof(options)} cannot be a cancellation token");
}
if (this.Disabled != null && this.Disabled.GetValue(dc.State))
{
return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
}
if (dc.Context.Activity.ChannelId != Channels.Msteams)
{
throw new InvalidOperationException($"{Kind} works only on the Teams channel.");
}
string teamId = TeamId.GetValueOrNull(dc.State);
var result = await TeamsInfo.GetTeamDetailsAsync(dc.Context, teamId, cancellationToken: cancellationToken).ConfigureAwait(false);
if (this.Property != null)
{
dc.State.SetValue(this.Property.GetValue(dc.State), result);
}
return await dc.EndDialogAsync(result, cancellationToken: cancellationToken).ConfigureAwait(false);
}
/// <summary>
/// Builds the compute Id for the dialog.
/// </summary>
/// <returns>A string representing the compute Id.</returns>
protected override string OnComputeId()
{
return $"{this.GetType().Name}[{this.TeamId?.ToString() ?? string.Empty},{this.Property?.ToString() ?? string.Empty}]";
}
}
}

Просмотреть файл

@ -0,0 +1,131 @@
// Licensed under the MIT License.
// Copyright (c) Microsoft Corporation. All rights reserved.
using System;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using AdaptiveExpressions.Properties;
using Microsoft.Bot.Builder.Dialogs.Adaptive.Teams.Actions;
using Microsoft.Bot.Builder.Teams;
using Microsoft.Bot.Connector;
using Newtonsoft.Json;
namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Teams.Actions
{
/// <summary>
/// Calls TeamsInfo.GetTeamMember to retrieve the list of members in a teams
/// scoped conversation and sets the result to a memory property.
/// </summary>
public class GetTeamMember : Dialog
{
/// <summary>
/// Class identifier.
/// </summary>
[JsonProperty("$kind")]
public const string Kind = "Teams.GetTeamMember";
/// <summary>
/// Initializes a new instance of the <see cref="GetTeamMember"/> class.
/// </summary>
/// <param name="callerPath">Optional, source file full path.</param>
/// <param name="callerLine">Optional, line number in source file.</param>
[JsonConstructor]
public GetTeamMember([CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
: base()
{
this.RegisterSourceLocation(callerPath, callerLine);
}
/// <summary>
/// Gets or sets an optional expression which if is true will disable this action.
/// </summary>
/// <example>
/// "user.age > 18".
/// </example>
/// <value>
/// A boolean expression.
/// </value>
[JsonProperty("disabled")]
public BoolExpression Disabled { get; set; }
/// <summary>
/// Gets or sets property path to put the value in.
/// </summary>
/// <value>
/// Property path to put the value in.
/// </value>
[JsonProperty("property")]
public StringExpression Property { get; set; }
/// <summary>
/// Gets or sets the expression to get the value to use for member id.
/// </summary>
/// <value>
/// The expression to get the value to use for member id. Default value is turn.activity.from.id.
/// </value>
[JsonProperty("memberId")]
public StringExpression MemberId { get; set; } = "=turn.activity.from.id";
/// <summary>
/// Gets or sets the expression to get the value to use for team id.
/// </summary>
/// <value>
/// The expression to get the value to use for team id. Default value is turn.activity.channelData.team.id.
/// </value>
[JsonProperty("teamId")]
public StringExpression TeamId { get; set; } = "=turn.activity.channelData.team.id";
/// <summary>
/// Called when the dialog is started and pushed onto the dialog stack.
/// </summary>
/// <param name="dc">The <see cref="DialogContext"/> for the current turn of conversation.</param>
/// <param name="options">Optional, initial information to pass to the dialog.</param>
/// <param name="cancellationToken">A cancellation token that can be used by other objects
/// or threads to receive notice of cancellation.</param>
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
public override async Task<DialogTurnResult> BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken))
{
if (options is CancellationToken)
{
throw new ArgumentException($"{nameof(options)} cannot be a cancellation token");
}
if (this.Disabled != null && this.Disabled.GetValue(dc.State))
{
return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
}
if (dc.Context.Activity.ChannelId != Channels.Msteams)
{
throw new InvalidOperationException($"{Kind} works only on the Teams channel.");
}
string memberId = MemberId.GetValueOrNull(dc.State);
if (string.IsNullOrEmpty(memberId))
{
throw new InvalidOperationException($"Missing {nameof(MemberId)} in {Kind}.");
}
string teamId = TeamId.GetValueOrNull(dc.State);
var result = await TeamsInfo.GetTeamMemberAsync(dc.Context, memberId, teamId, cancellationToken: cancellationToken).ConfigureAwait(false);
if (this.Property != null)
{
dc.State.SetValue(this.Property.GetValue(dc.State), result);
}
return await dc.EndDialogAsync(result, cancellationToken: cancellationToken).ConfigureAwait(false);
}
/// <summary>
/// Builds the compute Id for the dialog.
/// </summary>
/// <returns>A string representing the compute Id.</returns>
protected override string OnComputeId()
{
return $"{this.GetType().Name}[{this.MemberId?.ToString() ?? string.Empty},{this.TeamId?.ToString() ?? string.Empty},{this.Property?.ToString() ?? string.Empty}]";
}
}
}

Просмотреть файл

@ -0,0 +1,27 @@
// Licensed under the MIT License.
// Copyright (c) Microsoft Corporation. All rights reserved.
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Teams.Actions
{
/// <summary>
/// Enum representing Messaging Extension Attachment Layout types.
/// </summary>
[JsonConverter(typeof(StringEnumConverter), /*camelCase*/ true)]
public enum MessagingExtensionAttachmentLayoutResponseType
{
/// <summary>
/// List layout type.
/// </summary>
#pragma warning disable SA1300 // Element should begin with upper-case letter
list,
/// <summary>
/// Grid layout type.
/// </summary>
grid
#pragma warning restore SA1300 // Element should begin with upper-case letter
}
}

Просмотреть файл

@ -0,0 +1,42 @@
// Licensed under the MIT License.
// Copyright (c) Microsoft Corporation. All rights reserved.
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Teams.Actions
{
/// <summary>
/// Enum representing Messaging Extension Result Response types.
/// </summary>
[JsonConverter(typeof(StringEnumConverter), /*camelCase*/ true)]
public enum MessagingExtensionResultResponseType
{
/// <summary>
/// Result response type.
/// </summary>
#pragma warning disable SA1300 // Element should begin with upper-case letter
result,
/// <summary>
/// Auth response type.
/// </summary>
auth,
/// <summary>
/// Config response type.
/// </summary>
config,
/// <summary>
/// Message response type.
/// </summary>
message,
/// <summary>
/// BotMessagePreview response type.
/// </summary>
botMessagePreview
#pragma warning restore SA1300 // Element should begin with upper-case letter
}
}

Просмотреть файл

@ -0,0 +1,102 @@
// Licensed under the MIT License.
// Copyright (c) Microsoft Corporation. All rights reserved.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Bot.Schema;
using Microsoft.Bot.Schema.Teams;
using Newtonsoft.Json;
namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Teams.Actions
{
/// <summary>
/// Send a messaging extension 'result' response when a Teams Invoke Activity is received with activity.name='composeExtension/queryLink'.
/// </summary>
public class SendAppBasedLinkQueryResponse : BaseTeamsCacheInfoResponseDialog
{
/// <summary>
/// Class identifier.
/// </summary>
[JsonProperty("$kind")]
public const string Kind = "Teams.SendAppBasedLinkQueryResponse";
/// <summary>
/// Initializes a new instance of the <see cref="SendAppBasedLinkQueryResponse"/> class.
/// </summary>
/// <param name="callerPath">Optional, source file full path.</param>
/// <param name="callerLine">Optional, line number in source file.</param>
[JsonConstructor]
public SendAppBasedLinkQueryResponse([CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
: base()
{
RegisterSourceLocation(callerPath, callerLine);
}
/// <summary>
/// Gets or sets template for the attachment template of a Thumbnail or Hero Card to send.
/// </summary>
/// <value>
/// Template for the card.
/// </value>
[JsonProperty("card")]
public ITemplate<Activity> Card { get; set; }
/// <summary>
/// Called when the dialog is started and pushed onto the dialog stack.
/// </summary>
/// <param name="dc">The <see cref="DialogContext"/> for the current turn of conversation.</param>
/// <param name="options">Optional, initial information to pass to the dialog.</param>
/// <param name="cancellationToken">A cancellation token that can be used by other objects
/// or threads to receive notice of cancellation.</param>
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
public override async Task<DialogTurnResult> BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken))
{
if (options is CancellationToken)
{
throw new ArgumentException($"{nameof(options)} cannot be a cancellation token");
}
if (Disabled != null && Disabled.GetValue(dc.State) == true)
{
return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
}
if (Card == null)
{
throw new ArgumentException($"An activity with attachments is required for {Kind}.");
}
Activity activity = await Card.BindAsync(dc, dc.State).ConfigureAwait(false);
if (activity?.Attachments?.Any() != true)
{
throw new InvalidOperationException($"Invalid activity. An attachment is required for {Kind}.");
}
var attachments = activity.Attachments.Select(a => new MessagingExtensionAttachment(a.ContentType, null, a.Content));
var result = new MessagingExtensionResult
{
Type = MessagingExtensionResultResponseType.result.ToString(),
AttachmentLayout = MessagingExtensionAttachmentLayoutResponseType.list.ToString(), // 'list', 'grid' // TODO: make this configurable
Attachments = attachments.ToList(),
};
var invokeResponse = CreateMessagingExtensionInvokeResponseActivity(dc, result);
ResourceResponse resourceResponse = await dc.Context.SendActivityAsync(invokeResponse, cancellationToken: cancellationToken).ConfigureAwait(false);
return await dc.EndDialogAsync(resourceResponse, cancellationToken: cancellationToken).ConfigureAwait(false);
}
/// <summary>
/// Builds the compute Id for the dialog.
/// </summary>
/// <returns>A string representing the compute Id.</returns>
protected override string OnComputeId()
{
return $"{GetType().Name}[{Card?.ToString() ?? string.Empty}]";
}
}
}

Просмотреть файл

@ -0,0 +1,167 @@
// Licensed under the MIT License.
// Copyright (c) Microsoft Corporation. All rights reserved.
using System;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using AdaptiveExpressions.Properties;
using Microsoft.Bot.Builder.Dialogs.Adaptive.Teams.Actions;
using Microsoft.Bot.Builder.Teams;
using Microsoft.Bot.Connector;
using Microsoft.Bot.Connector.Authentication;
using Microsoft.Bot.Schema;
using Microsoft.Bot.Schema.Teams;
using Newtonsoft.Json;
namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Teams.Actions
{
/// <summary>
/// Calls TeamsInfo.SendMessageToTeamsChannel and sets the result to a memory property.
/// </summary>
public class SendMessageToTeamsChannel : Dialog
{
/// <summary>
/// Class identifier.
/// </summary>
[JsonProperty("$kind")]
public const string Kind = "Teams.SendMessageToTeamsChannel";
/// <summary>
/// Initializes a new instance of the <see cref="SendMessageToTeamsChannel"/> class.
/// </summary>
/// <param name="callerPath">Optional, source file full path.</param>
/// <param name="callerLine">Optional, line number in source file.</param>
[JsonConstructor]
public SendMessageToTeamsChannel([CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
: base()
{
this.RegisterSourceLocation(callerPath, callerLine);
}
/// <summary>
/// Gets or sets an optional expression which if is true will disable this action.
/// </summary>
/// <example>
/// "user.age > 18".
/// </example>
/// <value>
/// A boolean expression.
/// </value>
[JsonProperty("disabled")]
public BoolExpression Disabled { get; set; }
/// <summary>
/// Gets or sets property path to put the newly created activity's Conversation Reference.
/// This can be used to later send messages to this same conversation.
/// </summary>
/// <value>
/// Property path to put the newly created activity's conversation reference.
/// </value>
[JsonProperty("conversationReferenceProperty")]
public StringExpression ConversationReferenceProperty { get; set; }
/// <summary>
/// Gets or sets property path to put the id of the activity sent.
/// </summary>
/// <value>
/// Property path to put the id of the activity sent.
/// </value>
[JsonProperty("activityIdProperty")]
public StringExpression ActivityIdProperty { get; set; }
/// <summary>
/// Gets or sets the expression to get the value to use for the teams channel id where the message should be sent. Default is turn.activity.channelData.channel.id.
/// </summary>
/// <value>
/// The expression to get the value to use for teams channel id.
/// </value>
[JsonProperty("teamsChannelId")]
public StringExpression TeamsChannelId { get; set; } = "=turn.activity.channelData.channel.id";
/// <summary>
/// Gets or sets template for the activity expression containing the activity to send.
/// </summary>
/// <value>
/// Template for the activity.
/// </value>
[JsonProperty("activity")]
public ITemplate<Activity> Activity { get; set; }
/// <summary>
/// Called when the dialog is started and pushed onto the dialog stack.
/// </summary>
/// <param name="dc">The <see cref="DialogContext"/> for the current turn of conversation.</param>
/// <param name="options">Optional, initial information to pass to the dialog.</param>
/// <param name="cancellationToken">A cancellation token that can be used by other objects
/// or threads to receive notice of cancellation.</param>
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
public override async Task<DialogTurnResult> BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken))
{
if (options is CancellationToken)
{
throw new ArgumentException($"{nameof(options)} cannot be a cancellation token");
}
if (this.Disabled != null && this.Disabled.GetValue(dc.State))
{
return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
}
if (dc.Context.Activity.ChannelId != Channels.Msteams)
{
throw new InvalidOperationException($"{Kind} works only on the Teams channel.");
}
IActivity activity = null;
if (Activity != null)
{
activity = await Activity.BindAsync(dc, dc.State).ConfigureAwait(false);
}
string teamsChannelId = TeamsChannelId.GetValueOrNull(dc.State);
if (string.IsNullOrEmpty(teamsChannelId))
{
teamsChannelId = dc.Context.Activity.TeamsGetChannelId();
}
if (!(dc.Context.Adapter is BotFrameworkAdapter))
{
throw new InvalidOperationException($"{Kind} is not supported by the current adapter.");
}
// TODO: this will NOT work with certificate app credentials
// TeamsInfo.SendMessageToTeamsChannelAsync requires AppCredentials
var credentials = dc.Context.TurnState.Get<IConnectorClient>()?.Credentials as MicrosoftAppCredentials;
if (credentials == null)
{
throw new InvalidOperationException($"Missing credentials as {nameof(MicrosoftAppCredentials)} in {nameof(IConnectorClient)} from TurnState");
}
// The result comes back as a tuple, which is used to set the two properties (if present).
var result = await TeamsInfo.SendMessageToTeamsChannelAsync(dc.Context, activity, teamsChannelId, credentials, cancellationToken: cancellationToken).ConfigureAwait(false);
if (this.ConversationReferenceProperty != null)
{
dc.State.SetValue(this.ConversationReferenceProperty.GetValue(dc.State), result.Item1);
}
if (this.ActivityIdProperty != null)
{
dc.State.SetValue(this.ActivityIdProperty.GetValue(dc.State), result.Item2);
}
return await dc.EndDialogAsync(result, cancellationToken: cancellationToken).ConfigureAwait(false);
}
/// <summary>
/// Builds the compute Id for the dialog.
/// </summary>
/// <returns>A string representing the compute Id.</returns>
protected override string OnComputeId()
{
return $"{this.GetType().Name}[{this.TeamsChannelId?.ToString() ?? string.Empty},{this.ActivityIdProperty?.ToString() ?? string.Empty},{this.ConversationReferenceProperty?.ToString() ?? string.Empty}]";
}
}
}

Просмотреть файл

@ -0,0 +1,113 @@
// Licensed under the MIT License.
// Copyright (c) Microsoft Corporation. All rights reserved.
using System;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Bot.Builder.Dialogs.Adaptive.Teams.Actions;
using Microsoft.Bot.Schema;
using Microsoft.Bot.Schema.Teams;
using Newtonsoft.Json;
namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Teams.Actions
{
/// <summary>
/// Send a messaging extension action response.
/// </summary>
public class SendMessagingExtensionActionResponse : BaseSendTaskModuleContinueResponse
{
/// <summary>
/// Class identifier.
/// </summary>
[JsonProperty("$kind")]
public const string Kind = "Teams.SendMessagingExtensionActionResponse";
/// <summary>
/// Initializes a new instance of the <see cref="SendMessagingExtensionActionResponse"/> class.
/// </summary>
/// <param name="callerPath">Optional, source file full path.</param>
/// <param name="callerLine">Optional, line number in source file.</param>
[JsonConstructor]
public SendMessagingExtensionActionResponse([CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
: base()
{
this.RegisterSourceLocation(callerPath, callerLine);
}
/// <summary>
/// Gets or sets template for the activity expression containing a Card to send.
/// </summary>
/// <value>
/// Template for the activity containing an Adaptive Card to send.
/// </value>
[JsonProperty("card")]
public ITemplate<Activity> Card { get; set; }
/// <summary>
/// Called when the dialog is started and pushed onto the dialog stack.
/// </summary>
/// <param name="dc">The <see cref="DialogContext"/> for the current turn of conversation.</param>
/// <param name="options">Optional, initial information to pass to the dialog.</param>
/// <param name="cancellationToken">A cancellation token that can be used by other objects
/// or threads to receive notice of cancellation.</param>
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
public override async Task<DialogTurnResult> BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken))
{
if (options is CancellationToken)
{
throw new ArgumentException($"{nameof(options)} cannot be a cancellation token");
}
if (this.Disabled != null && this.Disabled.GetValue(dc.State))
{
return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
}
Activity activity = null;
if (Card != null)
{
activity = await Card.BindAsync(dc, dc.State).ConfigureAwait(false);
}
if (activity?.Attachments?.Any() != true)
{
throw new InvalidOperationException($"Missing attachments in {Kind}.");
}
var title = Title.GetValueOrNull(dc.State);
var height = Height.GetValueOrNull(dc.State);
var width = Width.GetValueOrNull(dc.State);
var completionBotId = CompletionBotId.GetValueOrNull(dc.State);
var response = new MessagingExtensionActionResponse
{
Task = new TaskModuleContinueResponse
{
Value = new TaskModuleTaskInfo
{
Card = activity.Attachments[0],
Height = height,
Width = width,
Title = title,
CompletionBotId = completionBotId
},
},
};
var invokeResponse = CreateInvokeResponseActivity(response);
var resourceResponse = await dc.Context.SendActivityAsync(invokeResponse, cancellationToken).ConfigureAwait(false);
return await dc.EndDialogAsync(resourceResponse, cancellationToken: cancellationToken).ConfigureAwait(false);
}
/// <summary>
/// Builds the compute Id for the dialog.
/// </summary>
/// <returns>A string representing the compute Id.</returns>
protected override string OnComputeId()
{
return $"{GetType().Name}[{Card?.ToString() ?? string.Empty}]";
}
}
}

Просмотреть файл

@ -0,0 +1,113 @@
// Licensed under the MIT License.
// Copyright (c) Microsoft Corporation. All rights reserved.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using AdaptiveExpressions.Properties;
using Microsoft.Bot.Schema;
using Microsoft.Bot.Schema.Teams;
using Newtonsoft.Json;
namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Teams.Actions
{
/// <summary>
/// Send a messaging extension 'result' in response to a Teams Invoke with name of 'composeExtension/query'.
/// </summary>
public class SendMessagingExtensionAttachmentsResponse : BaseTeamsCacheInfoResponseDialog
{
/// <summary>
/// Class identifier.
/// </summary>
[JsonProperty("$kind")]
public const string Kind = "Teams.SendMessagingExtensionAttachmentsResponse";
/// <summary>
/// Initializes a new instance of the <see cref="SendMessagingExtensionAttachmentsResponse"/> class.
/// </summary>
/// <param name="callerPath">Optional, source file full path.</param>
/// <param name="callerLine">Optional, line number in source file.</param>
[JsonConstructor]
public SendMessagingExtensionAttachmentsResponse([CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
: base()
{
this.RegisterSourceLocation(callerPath, callerLine);
}
/// <summary>
/// Gets or sets the Activity containing the Attachments to send.
/// </summary>
/// <value>
/// Activity with the Attachments to send in response to the Query.
/// </value>
[JsonProperty("attachments")]
public ITemplate<Activity> Attachments { get; set; }
/// <summary>
/// Gets or sets the Attachment Layout type for the response ('grid' or 'list').
/// </summary>
/// <value>
/// The Attachment Layout type.
/// </value>
[JsonProperty("attachmentLayout")]
public EnumExpression<MessagingExtensionAttachmentLayoutResponseType> AttachmentLayout { get; set; } = MessagingExtensionAttachmentLayoutResponseType.list;
/// <summary>
/// Called when the dialog is started and pushed onto the dialog stack.
/// </summary>
/// <param name="dc">The <see cref="DialogContext"/> for the current turn of conversation.</param>
/// <param name="options">Optional, initial information to pass to the dialog.</param>
/// <param name="cancellationToken">A cancellation token that can be used by other objects
/// or threads to receive notice of cancellation.</param>
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
public override async Task<DialogTurnResult> BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken))
{
if (options is CancellationToken)
{
throw new ArgumentException($"{nameof(options)} cannot be a cancellation token");
}
if (this.Disabled != null && this.Disabled.GetValue(dc.State))
{
return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
}
Activity activity = null;
if (Attachments != null)
{
activity = await Attachments.BindAsync(dc, dc.State).ConfigureAwait(false);
}
if (activity?.Attachments?.Any() != true)
{
throw new InvalidOperationException($"Missing attachments in {Kind}.");
}
var layout = AttachmentLayout.GetValue(dc.State);
var attachments = activity.Attachments.Select(a => new MessagingExtensionAttachment(a.ContentType, null, a.Content));
var result = new MessagingExtensionResult
{
Type = MessagingExtensionResultResponseType.result.ToString(),
AttachmentLayout = layout.ToString(),
Attachments = attachments.ToList(),
};
var invokeResponse = CreateMessagingExtensionInvokeResponseActivity(dc, result);
ResourceResponse resourceResponse = await dc.Context.SendActivityAsync(invokeResponse, cancellationToken: cancellationToken).ConfigureAwait(false);
return await dc.EndDialogAsync(resourceResponse, cancellationToken: cancellationToken).ConfigureAwait(false);
}
/// <summary>
/// Builds the compute Id for the dialog.
/// </summary>
/// <returns>A string representing the compute Id.</returns>
protected override string OnComputeId()
{
return $"{this.GetType().Name}[{this.Attachments?.ToString() ?? string.Empty}]";
}
}
}

Просмотреть файл

@ -0,0 +1,183 @@
// Licensed under the MIT License.
// Copyright (c) Microsoft Corporation. All rights reserved.
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using AdaptiveExpressions.Properties;
using Microsoft.Bot.Builder.Dialogs.Adaptive.Teams.Actions;
using Microsoft.Bot.Schema;
using Microsoft.Bot.Schema.Teams;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Teams.Actions
{
/// <summary>
/// Send a messaging extension 'auth' response.
/// </summary>
public class SendMessagingExtensionAuthResponse : BaseTeamsCacheInfoResponseDialog
{
/// <summary>
/// Class identifier.
/// </summary>
[JsonProperty("$kind")]
public const string Kind = "Teams.SendMessagingExtensionAuthResponse";
/// <summary>
/// Initializes a new instance of the <see cref="SendMessagingExtensionAuthResponse"/> class.
/// </summary>
/// <param name="callerPath">Optional, source file full path.</param>
/// <param name="callerLine">Optional, line number in source file.</param>
[JsonConstructor]
public SendMessagingExtensionAuthResponse([CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
: base()
{
RegisterSourceLocation(callerPath, callerLine);
}
/// <summary>
/// Gets or sets property path to put the TokenResponse value in once retrieved.
/// </summary>
/// <value>
/// Property path to put the value in.
/// </value>
[JsonProperty("resultProperty")]
public StringExpression Property { get; set; }
/// <summary>
/// Gets or sets the name of the OAuth connection.
/// </summary>
/// <value>String or expression which evaluates to a connection string.</value>
[JsonProperty("connectionName")]
public StringExpression ConnectionName { get; set; }
/// <summary>
/// Gets or sets an Title of the response.
/// </summary>
/// <value>
/// An string or expression which evaluates to a string for the response title.
/// </value>
[JsonProperty("title")]
public StringExpression Title { get; set; }
/// <summary>
/// Called when the dialog is started and pushed onto the dialog stack.
/// </summary>
/// <param name="dc">The <see cref="DialogContext"/> for the current turn of conversation.</param>
/// <param name="options">Optional, initial information to pass to the dialog.</param>
/// <param name="cancellationToken">A cancellation token that can be used by other objects
/// or threads to receive notice of cancellation.</param>
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
public override async Task<DialogTurnResult> BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default)
{
if (options is CancellationToken)
{
throw new ArgumentException($"{nameof(options)} cannot be a cancellation token");
}
if (!(dc.Context.Adapter is IExtendedUserTokenProvider tokenProvider))
{
throw new InvalidOperationException($"{Kind}: not supported by the current adapter");
}
if (Disabled != null && Disabled.GetValue(dc.State) == true)
{
return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
}
var connectionName = ConnectionName.GetValueOrNull(dc.State);
if (string.IsNullOrEmpty(connectionName))
{
throw new InvalidOperationException($"A valid {nameof(ConnectionName)} is required for {Kind}.");
}
var title = Title.GetValueOrNull(dc.State);
if (string.IsNullOrEmpty(title))
{
throw new InvalidOperationException($"A valid {nameof(Title)} is required for {Kind}.");
}
var tokenResponse = await GetUserTokenAsync(dc, tokenProvider, connectionName, cancellationToken).ConfigureAwait(false);
if (tokenResponse != null && !string.IsNullOrEmpty(tokenResponse.Token))
{
// we have the token, so the user is already signed in.
// Similar to OAuthInput, just return the token in the property.
if (Property != null)
{
dc.State.SetValue(Property.GetValue(dc.State), tokenResponse);
}
// End the dialog and return the token response
return await dc.EndDialogAsync(tokenResponse, cancellationToken: cancellationToken).ConfigureAwait(false);
}
// There is no token, so the user has not signed in yet.
var activity = await GetInvokeResponseWithSignInLinkAsync(dc, title, tokenProvider, connectionName, cancellationToken).ConfigureAwait(false);
await dc.Context.SendActivityAsync(activity, cancellationToken: cancellationToken).ConfigureAwait(false);
// Since a token was not retrieved above, end the turn.
return Dialog.EndOfTurn;
}
/// <summary>
/// Builds the compute Id for the dialog.
/// </summary>
/// <returns>A string representing the compute Id.</returns>
protected override string OnComputeId()
{
return $"{GetType().Name}[{Title?.ToString() ?? string.Empty}]";
}
private static Task<TokenResponse> GetUserTokenAsync(DialogContext dc, IExtendedUserTokenProvider tokenProvider, string connectionName, CancellationToken cancellationToken)
{
// When the Bot Service Auth flow completes, the action.State will contain a magic code used for verification.
string state = null;
if (dc.Context.Activity.Value is JObject valueAsObject)
{
state = valueAsObject.Value<string>("state");
}
string magicCode = null;
if (!string.IsNullOrEmpty(state))
{
if (int.TryParse(state, out var parsed))
{
magicCode = parsed.ToString(CultureInfo.InvariantCulture);
}
}
// TODO: SSO and skills token exchange
return tokenProvider.GetUserTokenAsync(dc.Context, connectionName, magicCode, cancellationToken: cancellationToken);
}
private async Task<Activity> GetInvokeResponseWithSignInLinkAsync(DialogContext dc, string title, IExtendedUserTokenProvider tokenProvider, string connectionName, CancellationToken cancellationToken)
{
// Retrieve the OAuth Sign in Link to use in the MessagingExtensionResult Suggested Actions
var signInLink = await tokenProvider.GetOauthSignInLinkAsync(dc.Context, connectionName, cancellationToken: cancellationToken).ConfigureAwait(false);
var result = new MessagingExtensionResult
{
Type = MessagingExtensionResultResponseType.auth.ToString(),
SuggestedActions = new MessagingExtensionSuggestedAction
{
Actions = new List<CardAction>
{
new CardAction
{
Type = ActionTypes.OpenUrl,
Value = signInLink,
Title = title,
},
},
},
};
return CreateMessagingExtensionInvokeResponseActivity(dc, result);
}
}
}

Просмотреть файл

@ -0,0 +1,110 @@
// Licensed under the MIT License.
// Copyright (c) Microsoft Corporation. All rights reserved.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Bot.Schema;
using Microsoft.Bot.Schema.Teams;
using Newtonsoft.Json;
namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Teams.Actions
{
/// <summary>
/// Send a messaging extension 'botMessagePreview' response.
/// </summary>
public class SendMessagingExtensionBotMessagePreviewResponse : BaseSendTaskModuleContinueResponse
{
/// <summary>
/// Class identifier.
/// </summary>
[JsonProperty("$kind")]
public const string Kind = "Teams.SendMessagingExtensionBotMessagePreviewResponse";
/// <summary>
/// Initializes a new instance of the <see cref="SendMessagingExtensionBotMessagePreviewResponse"/> class.
/// </summary>
/// <param name="callerPath">Optional, source file full path.</param>
/// <param name="callerLine">Optional, line number in source file.</param>
[JsonConstructor]
public SendMessagingExtensionBotMessagePreviewResponse([CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
: base()
{
RegisterSourceLocation(callerPath, callerLine);
}
/// <summary>
/// Gets or sets template for the expression containing a Hero Card or Adaptive Card to send.
/// </summary>
/// <value>
/// Template for the activity.
/// </value>
[JsonProperty("card")]
public ITemplate<Activity> Card { get; set; }
/// <summary>
/// Called when the dialog is started and pushed onto the dialog stack.
/// </summary>
/// <param name="dc">The <see cref="DialogContext"/> for the current turn of conversation.</param>
/// <param name="options">Optional, initial information to pass to the dialog.</param>
/// <param name="cancellationToken">A cancellation token that can be used by other objects
/// or threads to receive notice of cancellation.</param>
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
public override async Task<DialogTurnResult> BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken))
{
if (options is CancellationToken)
{
throw new ArgumentException($"{nameof(options)} cannot be a cancellation token");
}
if (Disabled != null && Disabled.GetValue(dc.State) == true)
{
return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
}
if (Card == null)
{
throw new ArgumentException($"A valid {nameof(Card)} is required for {Kind}.");
}
var activity = await Card.BindAsync(dc, dc.State).ConfigureAwait(false);
if (activity?.Attachments?.Any() != true)
{
throw new InvalidOperationException($"Invalid activity. An attachment is required for {Kind}.");
}
Attachment attachment = activity.Attachments[0];
var response = new MessagingExtensionActionResponse
{
ComposeExtension = new MessagingExtensionResult
{
Type = MessagingExtensionResultResponseType.botMessagePreview.ToString(),
ActivityPreview = MessageFactory.Attachment(new Attachment
{
Content = attachment.Content,
ContentType = attachment.ContentType,
}) as Activity,
},
CacheInfo = GetCacheInfo(dc),
};
var invokeResponse = CreateInvokeResponseActivity(response);
ResourceResponse sendResponse = await dc.Context.SendActivityAsync(invokeResponse, cancellationToken: cancellationToken).ConfigureAwait(false);
return await dc.EndDialogAsync(sendResponse, cancellationToken: cancellationToken).ConfigureAwait(false);
}
/// <summary>
/// Builds the compute Id for the dialog.
/// </summary>
/// <returns>A string representing the compute Id.</returns>
protected override string OnComputeId()
{
return $"{GetType().Name}[{Card?.ToString() ?? string.Empty}]";
}
}
}

Просмотреть файл

@ -0,0 +1,110 @@
// Licensed under the MIT License.
// Copyright (c) Microsoft Corporation. All rights reserved.
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using AdaptiveExpressions.Properties;
using Microsoft.Bot.Builder.Dialogs.Adaptive.Teams.Actions;
using Microsoft.Bot.Schema;
using Microsoft.Bot.Schema.Teams;
using Newtonsoft.Json;
namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Teams.Actions
{
/// <summary>
/// Send a messaging extension 'config' response. This is the type of response used for a 'composeExtension/querySettingUrl' request.
/// </summary>
public class SendMessagingExtensionConfigQuerySettingUrlResponse : BaseTeamsCacheInfoResponseDialog
{
/// <summary>
/// Class identifier.
/// </summary>
[JsonProperty("$kind")]
public const string Kind = "Teams.SendMessagingExtensionConfigQuerySettingUrlResponse";
/// <summary>
/// Initializes a new instance of the <see cref="SendMessagingExtensionConfigQuerySettingUrlResponse"/> class.
/// </summary>
/// <param name="callerPath">Optional, source file full path.</param>
/// <param name="callerLine">Optional, line number in source file.</param>
[JsonConstructor]
public SendMessagingExtensionConfigQuerySettingUrlResponse([CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
: base()
{
RegisterSourceLocation(callerPath, callerLine);
}
/// <summary>
/// Gets or sets config url response to send. i.e $"{config.siteUrl}/searchSettings.html?settings={escapedSettings}".
/// </summary>
/// <value>
/// Message to send.
/// </value>
[JsonProperty("configUrl")]
public StringExpression ConfigUrl { get; set; }
/// <summary>
/// Called when the dialog is started and pushed onto the dialog stack.
/// </summary>
/// <param name="dc">The <see cref="DialogContext"/> for the current turn of conversation.</param>
/// <param name="options">Optional, initial information to pass to the dialog.</param>
/// <param name="cancellationToken">A cancellation token that can be used by other objects
/// or threads to receive notice of cancellation.</param>
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
public override async Task<DialogTurnResult> BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken))
{
if (options is CancellationToken)
{
throw new ArgumentException($"{nameof(options)} cannot be a cancellation token");
}
if (Disabled != null && Disabled.GetValue(dc.State) == true)
{
return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
}
string configUrl = ConfigUrl.GetValueOrNull(dc.State);
if (string.IsNullOrEmpty(configUrl))
{
throw new InvalidOperationException($"{nameof(ConfigUrl)} is required for {Kind}.");
}
var response = new MessagingExtensionResponse
{
ComposeExtension = new MessagingExtensionResult
{
Type = MessagingExtensionResultResponseType.config.ToString(),
SuggestedActions = new MessagingExtensionSuggestedAction
{
Actions = new List<CardAction>
{
new CardAction
{
Type = ActionTypes.OpenUrl,
Value = configUrl,
},
},
},
},
CacheInfo = GetCacheInfo(dc)
};
var invokeResponse = CreateInvokeResponseActivity(response);
ResourceResponse sendResponse = await dc.Context.SendActivityAsync(invokeResponse, cancellationToken: cancellationToken).ConfigureAwait(false);
return await dc.EndDialogAsync(sendResponse, cancellationToken: cancellationToken).ConfigureAwait(false);
}
/// <summary>
/// Builds the compute Id for the dialog.
/// </summary>
/// <returns>A string representing the compute Id.</returns>
protected override string OnComputeId()
{
return $"{GetType().Name}[{ConfigUrl?.ToString() ?? string.Empty}]";
}
}
}

Просмотреть файл

@ -0,0 +1,99 @@
// Licensed under the MIT License.
// Copyright (c) Microsoft Corporation. All rights reserved.
using System;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using AdaptiveExpressions.Properties;
using Microsoft.Bot.Builder.Dialogs.Adaptive.Teams.Actions;
using Microsoft.Bot.Schema;
using Microsoft.Bot.Schema.Teams;
using Newtonsoft.Json;
namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Teams.Actions
{
/// <summary>
/// Send a messaging extension 'message' response.
/// </summary>
public class SendMessagingExtensionMessageResponse : BaseTeamsCacheInfoResponseDialog
{
/// <summary>
/// Class identifier.
/// </summary>
[JsonProperty("$kind")]
public const string Kind = "Teams.SendMessagingExtensionMessageResponse";
/// <summary>
/// Initializes a new instance of the <see cref="SendMessagingExtensionMessageResponse"/> class.
/// </summary>
/// <param name="callerPath">Optional, source file full path.</param>
/// <param name="callerLine">Optional, line number in source file.</param>
[JsonConstructor]
public SendMessagingExtensionMessageResponse([CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
: base()
{
RegisterSourceLocation(callerPath, callerLine);
}
/// <summary>
/// Gets or sets the template or text to use to generate the response message to send.
/// </summary>
/// <value>
/// Message to send.
/// </value>
[JsonProperty("message")]
public StringExpression Message { get; set; }
/// <summary>
/// Called when the dialog is started and pushed onto the dialog stack.
/// </summary>
/// <param name="dc">The <see cref="DialogContext"/> for the current turn of conversation.</param>
/// <param name="options">Optional, initial information to pass to the dialog.</param>
/// <param name="cancellationToken">A cancellation token that can be used by other objects
/// or threads to receive notice of cancellation.</param>
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
public override async Task<DialogTurnResult> BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken))
{
if (options is CancellationToken)
{
throw new ArgumentException($"{nameof(options)} cannot be a cancellation token");
}
if (Disabled != null && Disabled.GetValue(dc.State) == true)
{
return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
}
string message = Message.GetValueOrNull(dc.State);
if (string.IsNullOrEmpty(message))
{
throw new ArgumentException($"A {nameof(Message)} is required for {Kind}.");
}
var response = new MessagingExtensionResponse
{
ComposeExtension = new MessagingExtensionResult
{
Type = MessagingExtensionResultResponseType.message.ToString(),
Text = message,
},
CacheInfo = GetCacheInfo(dc)
};
var invokeResponse = CreateInvokeResponseActivity(response);
ResourceResponse sendResponse = await dc.Context.SendActivityAsync(invokeResponse, cancellationToken: cancellationToken).ConfigureAwait(false);
return await dc.EndDialogAsync(sendResponse, cancellationToken: cancellationToken).ConfigureAwait(false);
}
/// <summary>
/// Builds the compute Id for the dialog.
/// </summary>
/// <returns>A string representing the compute Id.</returns>
protected override string OnComputeId()
{
return $"{GetType().Name}[{Message?.ToString() ?? string.Empty}]";
}
}
}

Просмотреть файл

@ -0,0 +1,107 @@
// Licensed under the MIT License.
// Copyright (c) Microsoft Corporation. All rights reserved.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Bot.Schema;
using Microsoft.Bot.Schema.Teams;
using Newtonsoft.Json;
namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Teams.Actions
{
/// <summary>
/// Send a messaging extension 'message' response.
/// </summary>
public class SendMessagingExtensionSelectItemResponse : BaseTeamsCacheInfoResponseDialog
{
/// <summary>
/// Class identifier.
/// </summary>
[JsonProperty("$kind")]
public const string Kind = "Teams.SendMessagingExtensionSelectItemResponse";
/// <summary>
/// Initializes a new instance of the <see cref="SendMessagingExtensionSelectItemResponse"/> class.
/// </summary>
/// <param name="callerPath">Optional, source file full path.</param>
/// <param name="callerLine">Optional, line number in source file.</param>
[JsonConstructor]
public SendMessagingExtensionSelectItemResponse([CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
: base()
{
RegisterSourceLocation(callerPath, callerLine);
}
/// <summary>
/// Gets or sets template for the expression containing a Hero Card or Adaptive Card to send.
/// </summary>
/// <value>
/// Template for the card.
/// </value>
[JsonProperty("card")]
public ITemplate<Activity> Card { get; set; }
/// <summary>
/// Called when the dialog is started and pushed onto the dialog stack.
/// </summary>
/// <param name="dc">The <see cref="DialogContext"/> for the current turn of conversation.</param>
/// <param name="options">Optional, initial information to pass to the dialog.</param>
/// <param name="cancellationToken">A cancellation token that can be used by other objects
/// or threads to receive notice of cancellation.</param>
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
public override async Task<DialogTurnResult> BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken))
{
if (options is CancellationToken)
{
throw new ArgumentException($"{nameof(options)} cannot be a cancellation token");
}
if (Disabled != null && Disabled.GetValue(dc.State) == true)
{
return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
}
if (Card == null)
{
throw new ArgumentException($"A valid card is required for {Kind}.");
}
var activity = await Card.BindAsync(dc, dc.State).ConfigureAwait(false);
if (activity?.Attachments?.Any() != true)
{
throw new InvalidOperationException($"Invalid activity. An attachment is required for {Kind}.");
}
var attachment = activity.Attachments[0];
var extensionAttachment = new MessagingExtensionAttachment(attachment.ContentType, null, attachment.Content);
var response = new MessagingExtensionResponse
{
ComposeExtension = new MessagingExtensionResult
{
Type = MessagingExtensionResultResponseType.result.ToString(),
AttachmentLayout = MessagingExtensionAttachmentLayoutResponseType.list.ToString(), // TODO: enum this
Attachments = new List<MessagingExtensionAttachment> { extensionAttachment }
},
CacheInfo = GetCacheInfo(dc),
};
var invokeResponse = CreateInvokeResponseActivity(response);
ResourceResponse sendResponse = await dc.Context.SendActivityAsync(invokeResponse, cancellationToken: cancellationToken).ConfigureAwait(false);
return await dc.EndDialogAsync(sendResponse, cancellationToken: cancellationToken).ConfigureAwait(false);
}
/// <summary>
/// Builds the compute Id for the dialog.
/// </summary>
/// <returns>A string representing the compute Id.</returns>
protected override string OnComputeId()
{
return $"{GetType().Name}[{Card?.ToString() ?? string.Empty}]";
}
}
}

Просмотреть файл

@ -0,0 +1,122 @@
// Licensed under the MIT License.
// Copyright (c) Microsoft Corporation. All rights reserved.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Bot.Builder.Dialogs.Adaptive.Teams.Actions;
using Microsoft.Bot.Builder.Dialogs.Adaptive.Templates;
using Microsoft.Bot.Schema;
using Microsoft.Bot.Schema.Teams;
using Newtonsoft.Json;
namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Teams.Actions
{
/// <summary>
/// Send an Card Task Module Continue response to the user.
/// </summary>
public class SendTaskModuleCardResponse : BaseSendTaskModuleContinueResponse
{
/// <summary>
/// Class identifier.
/// </summary>
[JsonProperty("$kind")]
public const string Kind = "Teams.SendTaskModuleCardResponse";
/// <summary>
/// Initializes a new instance of the <see cref="SendTaskModuleCardResponse"/> class.
/// </summary>
/// <param name="callerPath">Optional, source file full path.</param>
/// <param name="callerLine">Optional, line number in source file.</param>
[JsonConstructor]
public SendTaskModuleCardResponse([CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
{
RegisterSourceLocation(callerPath, callerLine);
}
/// <summary>
/// Gets or sets template for the activity expression containing a Hero Card or Adaptive Card to send.
/// </summary>
/// <value>
/// Template for the card.
/// </value>
[JsonProperty("card")]
public ITemplate<Activity> Card { get; set; }
/// <summary>
/// Called when the dialog is started and pushed onto the dialog stack.
/// </summary>
/// <param name="dc">The <see cref="DialogContext"/> for the current turn of conversation.</param>
/// <param name="options">Optional, initial information to pass to the dialog.</param>
/// <param name="cancellationToken">A cancellation token that can be used by other objects
/// or threads to receive notice of cancellation.</param>
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
public override async Task<DialogTurnResult> BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken))
{
if (options is CancellationToken)
{
throw new ArgumentException($"{nameof(options)} cannot be a cancellation token");
}
if (Disabled != null && Disabled.GetValue(dc.State) == true)
{
return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
}
if (Card == null)
{
throw new ArgumentException($"A valid {nameof(Card)} is required for {Kind}.");
}
var activity = await Card.BindAsync(dc, dc.State).ConfigureAwait(false);
if (activity?.Attachments?.Any() != true)
{
throw new InvalidOperationException($"Invalid activity. An attachment is required for {Kind}.");
}
Attachment attachment = activity.Attachments[0];
var title = Title.GetValueOrNull(dc.State);
var height = Height.GetValueOrNull(dc.State);
var width = Width.GetValueOrNull(dc.State);
var completionBotId = CompletionBotId.GetValueOrNull(dc.State);
var response = new TaskModuleResponse
{
Task = new TaskModuleContinueResponse
{
Value = new TaskModuleTaskInfo
{
Title = title,
Card = attachment,
Height = height,
Width = width,
CompletionBotId = completionBotId,
},
},
CacheInfo = GetCacheInfo(dc),
};
var responseActivity = CreateInvokeResponseActivity(response);
ResourceResponse sendResponse = await dc.Context.SendActivityAsync(responseActivity, cancellationToken: cancellationToken).ConfigureAwait(false);
return await dc.EndDialogAsync(sendResponse, cancellationToken: cancellationToken).ConfigureAwait(false);
}
/// <summary>
/// Builds the compute Id for the dialog.
/// </summary>
/// <returns>A string representing the compute Id.</returns>
protected override string OnComputeId()
{
if (Card is ActivityTemplate at)
{
return $"{GetType().Name}({StringUtils.Ellipsis(at.Template.Trim(), 30)})";
}
return $"{GetType().Name}('{StringUtils.Ellipsis(Card?.ToString().Trim(), 30)}')";
}
}
}

Просмотреть файл

@ -0,0 +1,96 @@
// Licensed under the MIT License.
// Copyright (c) Microsoft Corporation. All rights reserved.
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using AdaptiveExpressions.Properties;
using Microsoft.Bot.Builder.Dialogs.Adaptive.Teams.Actions;
using Microsoft.Bot.Schema;
using Microsoft.Bot.Schema.Teams;
using Newtonsoft.Json;
namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Teams.Actions
{
/// <summary>
/// Send a simple message task module response.
/// </summary>
public class SendTaskModuleMessageResponse : BaseTeamsCacheInfoResponseDialog
{
/// <summary>
/// Class identifier.
/// </summary>
[JsonProperty("$kind")]
public const string Kind = "Teams.SendTaskModuleMessageResponse";
/// <summary>
/// Initializes a new instance of the <see cref="SendTaskModuleMessageResponse"/> class.
/// </summary>
/// <param name="callerPath">Optional, source file full path.</param>
/// <param name="callerLine">Optional, line number in source file.</param>
[JsonConstructor]
public SendTaskModuleMessageResponse([CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
: base()
{
RegisterSourceLocation(callerPath, callerLine);
}
/// <summary>
/// Gets or sets response message to send.
/// </summary>
/// <value>
/// Message to send.
/// </value>
[JsonProperty("message")]
public StringExpression Message { get; set; }
/// <summary>
/// Called when the dialog is started and pushed onto the dialog stack.
/// </summary>
/// <param name="dc">The <see cref="DialogContext"/> for the current turn of conversation.</param>
/// <param name="options">Optional, initial information to pass to the dialog.</param>
/// <param name="cancellationToken">A cancellation token that can be used by other objects
/// or threads to receive notice of cancellation.</param>
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
public override async Task<DialogTurnResult> BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken))
{
if (options is CancellationToken)
{
throw new ArgumentException($"{nameof(options)} cannot be a cancellation token");
}
if (Disabled != null && Disabled.GetValue(dc.State) == true)
{
return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
}
string message = Message.GetValueOrNull(dc.State);
if (string.IsNullOrWhiteSpace(message))
{
throw new InvalidOperationException($"Missing {nameof(Message)} for {Kind}.");
}
var response = new TaskModuleResponse
{
Task = new TaskModuleMessageResponse(message),
CacheInfo = GetCacheInfo(dc),
};
var responseActivity = CreateInvokeResponseActivity(response);
ResourceResponse sendResponse = await dc.Context.SendActivityAsync(responseActivity, cancellationToken: cancellationToken).ConfigureAwait(false);
return await dc.EndDialogAsync(sendResponse, cancellationToken: cancellationToken).ConfigureAwait(false);
}
/// <summary>
/// Builds the compute Id for the dialog.
/// </summary>
/// <returns>A string representing the compute Id.</returns>
protected override string OnComputeId()
{
return $"{GetType().Name}[{Message?.ToString() ?? string.Empty}]";
}
}
}

Просмотреть файл

@ -0,0 +1,122 @@
// Licensed under the MIT License.
// Copyright (c) Microsoft Corporation. All rights reserved.
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using AdaptiveExpressions.Properties;
using Microsoft.Bot.Builder.Dialogs.Adaptive.Teams.Actions;
using Microsoft.Bot.Schema;
using Microsoft.Bot.Schema.Teams;
using Newtonsoft.Json;
namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Teams.Actions
{
/// <summary>
/// Send a url Task Module Continue response to the user.
/// </summary>
public class SendTaskModuleUrlResponse : BaseSendTaskModuleContinueResponse
{
/// <summary>
/// Class identifier.
/// </summary>
[JsonProperty("$kind")]
public const string Kind = "Teams.SendTaskModuleUrlResponse";
/// <summary>
/// Initializes a new instance of the <see cref="SendTaskModuleUrlResponse"/> class.
/// </summary>
/// <param name="callerPath">Optional, source file full path.</param>
/// <param name="callerLine">Optional, line number in source file.</param>
[JsonConstructor]
public SendTaskModuleUrlResponse([CallerFilePath] string callerPath = "", [CallerLineNumber] int callerLine = 0)
{
RegisterSourceLocation(callerPath, callerLine);
}
/// <summary>
/// Gets or sets an optional expression for the Url of the Task Module response.
/// </summary>
/// <value>
/// An string expression.
/// </value>
[JsonProperty("url")]
public StringExpression Url { get; set; }
/// <summary>
/// Gets or sets an optional expression for the Fallback Url the Task Module Task Info response.
/// </summary>
/// <value>
/// An string expression.
/// </value>
[JsonProperty("fallbackUrl")]
public StringExpression FallbackUrl { get; set; }
/// <summary>
/// Called when the dialog is started and pushed onto the dialog stack.
/// </summary>
/// <param name="dc">The <see cref="DialogContext"/> for the current turn of conversation.</param>
/// <param name="options">Optional, initial information to pass to the dialog.</param>
/// <param name="cancellationToken">A cancellation token that can be used by other objects
/// or threads to receive notice of cancellation.</param>
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
public override async Task<DialogTurnResult> BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken))
{
if (options is CancellationToken)
{
throw new ArgumentException($"{nameof(options)} cannot be a cancellation token");
}
if (Disabled != null && Disabled.GetValue(dc.State) == true)
{
return await dc.EndDialogAsync(cancellationToken: cancellationToken).ConfigureAwait(false);
}
string url = Url.GetValueOrNull(dc.State);
if (string.IsNullOrEmpty(url))
{
throw new InvalidOperationException($"Missing {nameof(Url)} for {Kind}.");
}
var title = Title.GetValueOrNull(dc.State);
var height = Height.GetValueOrNull(dc.State);
var width = Width.GetValueOrNull(dc.State);
var fallbackUrl = FallbackUrl.GetValueOrNull(dc.State);
var completionBotId = CompletionBotId.GetValueOrNull(dc.State);
var response = new TaskModuleResponse
{
Task = new TaskModuleContinueResponse
{
Value = new TaskModuleTaskInfo
{
Title = title,
Url = url,
FallbackUrl = fallbackUrl,
Height = height,
Width = width,
CompletionBotId = completionBotId,
},
},
CacheInfo = GetCacheInfo(dc),
};
var responseActivity = CreateInvokeResponseActivity(response);
ResourceResponse sendResponse = await dc.Context.SendActivityAsync(responseActivity, cancellationToken: cancellationToken).ConfigureAwait(false);
return await dc.EndDialogAsync(sendResponse, cancellationToken: cancellationToken).ConfigureAwait(false);
}
/// <summary>
/// Builds the compute Id for the dialog.
/// </summary>
/// <returns>A string representing the compute Id.</returns>
protected override string OnComputeId()
{
return $"{GetType().Name}('{Url?.ToString() ?? string.Empty},{Title?.ToString() ?? string.Empty}')";
}
}
}

Просмотреть файл

@ -36,19 +36,6 @@
<Content Include="**/*.qna" />
</ItemGroup>
<ItemGroup>
<None Remove="Schemas\Actions\Teams.GetMeetingParticipant.schema" />
<None Remove="Schemas\TriggerConditions\Microsoft.OnInvokeActivity.schema" />
<None Remove="Schemas\TriggerConditions\Teams.OnChannelRestored.schema" />
<None Remove="Schemas\TriggerConditions\Teams.OnTabFetch.schema" />
<None Remove="Schemas\TriggerConditions\Teams.OnTabSubmit.schema" />
<None Remove="Schemas\TriggerConditions\Teams.OnTeamArchived.schema" />
<None Remove="Schemas\TriggerConditions\Teams.OnTeamDeleted.schema" />
<None Remove="Schemas\TriggerConditions\Teams.OnTeamHardDeleted.schema" />
<None Remove="Schemas\TriggerConditions\Teams.OnTeamRestored.schema" />
<None Remove="Schemas\TriggerConditions\Teams.OnTeamUnarchived.schema" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Bot.Builder.Dialogs.Adaptive" Condition=" '$(ReleasePackageVersion)' == '' " Version="$(LocalPackageVersion)" />
<PackageReference Include="Microsoft.Bot.Builder.Dialogs.Adaptive" Condition=" '$(ReleasePackageVersion)' != '' " Version="$(ReleasePackageVersion)" />

Просмотреть файл

@ -15,12 +15,12 @@
"title": "Property",
"description": "Property (named location to store information).",
"examples": [
"user.participantInfo"
"dialog.participantInfo"
]
},
"meetingId": {
"$ref": "schema:#/definitions/stringExpression",
"title": "Meeting Id",
"title": "Meeting id",
"description": "Meeting Id or expression to a meetingId to use to get the participant information. Default value is the current turn.activity.channelData.meeting.id.",
"examples": [
"=turn.activity.channelData.meeting.id"
@ -28,7 +28,7 @@
},
"participantId": {
"$ref": "schema:#/definitions/stringExpression",
"title": "Participant Id",
"title": "Participant id",
"description": "Participant Id or expression to a participantId to use to get the participant information. Default value is the current turn.activity.from.aadObjectId.",
"examples": [
"=turn.activity.from.aadObjectId"
@ -36,7 +36,7 @@
},
"tenantId": {
"$ref": "schema:#/definitions/stringExpression",
"title": "Tenant Id",
"title": "Tenant id",
"description": "Tenant Id or expression to a tenantId to use to get the participant information. Default value is the current $turn.activity.channelData.tenant.id.",
"examples": [
"=turn.activity.channelData.tenant.id"

Просмотреть файл

@ -0,0 +1,38 @@
{
"$schema": "https://schemas.botframework.com/schemas/component/v1.0/component.schema",
"$role": "implements(Microsoft.IDialog)",
"title": "Get member",
"description": "This works in one-on-one, group, and teams scoped conversations.",
"type": "object",
"properties": {
"id": {
"type": "string",
"title": "Id",
"description": "Optional id for the dialog"
},
"property": {
"$ref": "schema:#/definitions/stringExpression",
"title": "Property",
"description": "Property (named location to store information).",
"examples": [
"dialog.memberInfo"
]
},
"memberId": {
"$ref": "schema:#/definitions/stringExpression",
"title": "Member Id",
"description": "Member Id or expression to a member id to use to get the member information. Default value is the current turn.activity.from.id.",
"examples": [
"=turn.activity.from.id"
]
},
"disabled": {
"$ref": "schema:#/definitions/booleanExpression",
"title": "Disabled",
"description": "Optional condition which if true will disable this action.",
"examples": [
"=user.age > 3"
]
}
}
}

Просмотреть файл

@ -0,0 +1,44 @@
{
"$schema": "https://schemas.botframework.com/schemas/component/v1.0/component.schema",
"$role": "implements(Microsoft.IDialog)",
"title": "Get paged members",
"description": "Get a paginated list of members.",
"type": "object",
"properties": {
"id": {
"type": "string",
"title": "Id",
"description": "Optional id for the dialog"
},
"property": {
"$ref": "schema:#/definitions/stringExpression",
"title": "Property",
"description": "Property (named location to store information).",
"examples": [
"dialog.pagedMembers"
]
},
"pageSize": {
"$ref": "schema:#/definitions/integerExpression",
"title": "Page Size",
"description": "Page Size or expression to use to get the page size.",
"examples": [
"100"
]
},
"continuationToken": {
"$ref": "schema:#/definitions/stringExpression",
"title": "Continuation token",
"description": "The continuation token that will be used to retrieve the members.",
"default": "=dialog.membersContinuationToken"
},
"disabled": {
"$ref": "schema:#/definitions/booleanExpression",
"title": "Disabled",
"description": "Optional condition which if true will disable this action.",
"examples": [
"=user.age > 3"
]
}
}
}

Просмотреть файл

@ -0,0 +1,13 @@
{
"$schema": "https://schemas.botframework.com/schemas/ui/v1.0/ui.schema",
"form": {
"label": "Get paged members",
"subtitle": "Gets members of a one-on-one, group, or team conversation.",
"order": [
"property",
"pageSize",
"continuationToken",
"*"
]
}
}

Просмотреть файл

@ -0,0 +1,50 @@
{
"$schema": "https://schemas.botframework.com/schemas/component/v1.0/component.schema",
"$role": "implements(Microsoft.IDialog)",
"title": "Get paged team members",
"description": "Get a paginated list of team members.",
"type": "object",
"properties": {
"id": {
"type": "string",
"title": "Id",
"description": "Optional id for the dialog"
},
"property": {
"$ref": "schema:#/definitions/stringExpression",
"title": "Property",
"description": "Property (named location to store information).",
"examples": [
"dialog.pagedTeamMembers"
]
},
"pageSize": {
"$ref": "schema:#/definitions/integerExpression",
"title": "Page size",
"description": "Page Size or expression to use to get the page size.",
"examples": [
"100"
]
},
"continuationToken": {
"$ref": "schema:#/definitions/stringExpression",
"title": "Continuation token",
"description": "The continuation token that will be used to retrieve the members.",
"default": "=dialog.membersContinuationToken"
},
"teamId": {
"$ref": "schema:#/definitions/stringExpression",
"title": "Team id",
"description": "The team id that will be used to retrieve the members.",
"default": "=turn.activity.channelData.team.id"
},
"disabled": {
"$ref": "schema:#/definitions/booleanExpression",
"title": "Disabled",
"description": "Optional condition which if true will disable this action.",
"examples": [
"=user.age > 3"
]
}
}
}

Просмотреть файл

@ -0,0 +1,14 @@
{
"$schema": "https://schemas.botframework.com/schemas/ui/v1.0/ui.schema",
"form": {
"label": "Get paged team members",
"subtitle": "Gets members for a team conversation.",
"order": [
"property",
"teamId",
"pageSize",
"continuationToken",
"*"
]
}
}

Просмотреть файл

@ -0,0 +1,36 @@
{
"$schema": "https://schemas.botframework.com/schemas/component/v1.0/component.schema",
"$role": "implements(Microsoft.IDialog)",
"title": "Get team channels",
"description": "Get channels for a team.",
"type": "object",
"properties": {
"id": {
"type": "string",
"title": "Id",
"description": "Optional id for the dialog"
},
"property": {
"$ref": "schema:#/definitions/stringExpression",
"title": "Property",
"description": "Property (named location to store information).",
"examples": [
"dialog.teamChannels"
]
},
"teamId": {
"$ref": "schema:#/definitions/stringExpression",
"title": "Team id",
"description": "Team Id or expression to a team id to use to get the team channels. Default value is the current turn.activity.channelData.team.id.",
"default": "=turn.activity.channelData.team.id"
},
"disabled": {
"$ref": "schema:#/definitions/booleanExpression",
"title": "Disabled",
"description": "Optional condition which if true will disable this action.",
"examples": [
"=user.age > 3"
]
}
}
}

Просмотреть файл

@ -0,0 +1,36 @@
{
"$schema": "https://schemas.botframework.com/schemas/component/v1.0/component.schema",
"$role": "implements(Microsoft.IDialog)",
"title": "Get team details",
"description": "Get details for a team.",
"type": "object",
"properties": {
"id": {
"type": "string",
"title": "Id",
"description": "Optional id for the dialog"
},
"property": {
"$ref": "schema:#/definitions/stringExpression",
"title": "Property",
"description": "Property (named location to store information).",
"examples": [
"dialog.teamDetails"
]
},
"teamId": {
"$ref": "schema:#/definitions/stringExpression",
"title": "Team id",
"description": "Team Id or expression to a team id to use to get the team details. Default value is the current turn.activity.channelData.team.id.",
"default": "=turn.activity.channelData.team.id"
},
"disabled": {
"$ref": "schema:#/definitions/booleanExpression",
"title": "Disabled",
"description": "Optional condition which if true will disable this action.",
"examples": [
"=user.age > 3"
]
}
}
}

Просмотреть файл

@ -0,0 +1,42 @@
{
"$schema": "https://schemas.botframework.com/schemas/component/v1.0/component.schema",
"$role": "implements(Microsoft.IDialog)",
"title": "Get team member",
"description": "Get teams member information.",
"type": "object",
"properties": {
"id": {
"type": "string",
"title": "Id",
"description": "Optional id for the dialog"
},
"property": {
"$ref": "schema:#/definitions/stringExpression",
"title": "Property",
"description": "Property (named location to store information).",
"examples": [
"dialog.teamMemberInfo"
]
},
"memberId": {
"$ref": "schema:#/definitions/stringExpression",
"title": "Member id",
"description": "Member Id or expression to a member id to use to get the member information. Default value is the current turn.activity.from.id.",
"default": "=turn.activity.from.id"
},
"teamId": {
"$ref": "schema:#/definitions/stringExpression",
"title": "Team id",
"description": "Team Id or expression to a team id to use to get the member information. Default value is the current turn.activity.channelData.team.id.",
"default": "=turn.activity.channelData.team.id"
},
"disabled": {
"$ref": "schema:#/definitions/booleanExpression",
"title": "Disabled",
"description": "Optional condition which if true will disable this action.",
"examples": [
"=user.age > 3"
]
}
}
}

Просмотреть файл

@ -0,0 +1,37 @@
{
"$schema": "https://schemas.botframework.com/schemas/component/v1.0/component.schema",
"$role": "implements(Microsoft.IDialog)",
"title": "Send query link response",
"description": "Query link requests have activity.name='composeExtension/queryLink'.",
"type": "object",
"properties": {
"id": {
"type": "string",
"title": "Id",
"description": "Optional id for the dialog"
},
"cacheType": {
"type": "string",
"title": "Cache type",
"description": "Optional type of cache: 'cache' or 'no_cache'."
},
"cacheDuration": {
"type": "string",
"title": "Cache duration",
"description": "Optional duration in seconds of the result in the cache."
},
"card": {
"$kind": "Microsoft.IActivityTemplate",
"title": "Card",
"description": "Expession for an Attachment template of Hero Card or Thumbnail Card to send. Attachment is required."
},
"disabled": {
"$ref": "schema:#/definitions/booleanExpression",
"title": "Disabled",
"description": "Optional condition which if true will disable this action.",
"examples": [
"=user.age > 3"
]
}
}
}

Просмотреть файл

@ -0,0 +1,13 @@
{
"$schema": "https://schemas.botframework.com/schemas/ui/v1.0/ui.schema",
"form": {
"label": "Send a query link response",
"subtitle": "Send a response to a query link request.",
"order": [
"card",
"cacheType",
"cacheDuration",
"*"
]
}
}

Просмотреть файл

@ -0,0 +1,49 @@
{
"$schema": "https://schemas.botframework.com/schemas/component/v1.0/component.schema",
"$role": "implements(Microsoft.IDialog)",
"title": "Send a message to a teams channel",
"description": "The resulting ConversationReference and ActivityId can be stored for later use.",
"type": "object",
"properties": {
"id": {
"type": "string",
"title": "Id",
"description": "Optional id for the dialog"
},
"conversationReferenceProperty": {
"$ref": "schema:#/definitions/stringExpression",
"title": "Conversation reference property",
"description": "Property path to put the newly created activity's Conversation Reference.",
"examples": [
"dialog.threadReference"
]
},
"activityIdProperty": {
"$ref": "schema:#/definitions/stringExpression",
"title": "Activity id property",
"description": "Property path to put the newly created activity's id.",
"examples": [
"dialog.threadId"
]
},
"teamsChannelId": {
"$ref": "schema:#/definitions/stringExpression",
"title": "Teams channel id",
"description": "Teams channel id to send a message to.",
"default": "=turn.activity.channelData.channel.id"
},
"activity": {
"$kind": "Microsoft.IActivityTemplate",
"title": "Activity",
"description": "Expession for an activity to send to the channel."
},
"disabled": {
"$ref": "schema:#/definitions/booleanExpression",
"title": "Disabled",
"description": "Optional condition which if true will disable this action.",
"examples": [
"=user.age > 3"
]
}
}
}

Просмотреть файл

@ -0,0 +1,14 @@
{
"$schema": "https://schemas.botframework.com/schemas/ui/v1.0/ui.schema",
"form": {
"label": "Send a message to a teams channel",
"subtitle": "Create a thread and send a message to a teams channel.",
"order": [
"activity",
"teamsChannelId",
"activityIdProperty",
"conversationReferenceProperty",
"*"
]
}
}

Просмотреть файл

@ -0,0 +1,66 @@
{
"$schema": "https://schemas.botframework.com/schemas/component/v1.0/component.schema",
"$role": "implements(Microsoft.IDialog)",
"title": "Messaging extension action response",
"description": "Send an task action response containing a card.",
"type": "object",
"properties": {
"id": {
"type": "string",
"title": "Id",
"description": "Optional id for the dialog"
},
"cacheType": {
"type": "string",
"title": "Cache type",
"description": "Optional type of cache: 'cache' or 'no_cache'."
},
"cacheDuration": {
"type": "string",
"title": "Cache duration",
"description": "Optional duration in seconds of the result in the cache."
},
"title": {
"$ref": "schema:#/definitions/stringExpression",
"title": "Title",
"description": "Title of the Action Response.",
"examples": [
"Action Response"
]
},
"height": {
"$ref": "schema:#/definitions/integerExpression",
"title": "Height",
"description": "Height of the Task Module Response.",
"examples": [
"450"
]
},
"width": {
"$ref": "schema:#/definitions/integerExpression",
"title": "Width",
"description": "Width of the Task Module Response.",
"examples": [
"450"
]
},
"card": {
"$kind": "Microsoft.IActivityTemplate",
"title": "Card",
"description": "Expession for an Attachment template of Hero Card or Adaptive Card to send. Attachment is required."
},
"completionBotId": {
"type": "string",
"title": "completionBotId",
"description": "an optional expression for the Completion Bot Id of the Task Module Task Info response. This is a bot App ID to send the result of the user's interaction with the task module to. If specified, the bot will receive a task/submit invoke event with a JSON object in the event payload."
},
"disabled": {
"$ref": "schema:#/definitions/booleanExpression",
"title": "Disabled",
"description": "Optional condition which if true will disable this action.",
"examples": [
"=user.age > 3"
]
}
}
}

Просмотреть файл

@ -0,0 +1,17 @@
{
"$schema": "https://schemas.botframework.com/schemas/ui/v1.0/ui.schema",
"form": {
"label": "Messaging extension action response",
"subtitle": "Send a response for a messaging extension request.",
"order": [
"card",
"title",
"height",
"width",
"cacheType",
"cacheDuration",
"completionBotId",
"*"
]
}
}

Просмотреть файл

@ -0,0 +1,57 @@
{
"$schema": "https://schemas.botframework.com/schemas/component/v1.0/component.schema",
"$role": "implements(Microsoft.IDialog)",
"title": "Messaging extensions attachments response",
"description": "Send a response containing attachments to a messaging extension request.",
"type": "object",
"properties": {
"id": {
"type": "string",
"title": "Id",
"description": "Optional id for the dialog"
},
"cacheType": {
"type": "string",
"title": "Cache type",
"description": "Optional type of cache: 'cache' or 'no_cache'."
},
"cacheDuration": {
"type": "string",
"title": "Cache duration",
"description": "Optional duration in seconds of the result in the cache."
},
"attachmentLayout": {
"$ref": "schema:#/definitions/stringExpression",
"title": "Attachment layout",
"description": "Defines the type of attachment layout. Either 'grid' or 'list'.",
"oneOf": [
{
"type": "string",
"title": "Layout type",
"description": "Layout type of 'grid' or 'list'.",
"enum": [
"list",
"grid"
],
"default": "list"
},
{
"$ref": "schema:#/definitions/equalsExpression"
}
]
},
"attachments": {
"$kind": "Microsoft.IActivityTemplate",
"title": "Attachments",
"description": "Expession for Attachments template of Cards or Adaptive Cards to send. Minimum of one Attachment is required."
},
"disabled": {
"$ref": "schema:#/definitions/booleanExpression",
"title": "Disabled",
"description": "Optional condition which if true will disable this action.",
"examples": [
"=user.age > 3"
]
}
}
}

Просмотреть файл

@ -0,0 +1,14 @@
{
"$schema": "https://schemas.botframework.com/schemas/ui/v1.0/ui.schema",
"form": {
"label": "Send messaging extensions attachment(s) response",
"subtitle": "Send an invoke response containing one or more attachments to a messaging extension request.",
"order": [
"attachments",
"attachmentLayout",
"cacheType",
"cacheDuration",
"*"
]
}
}

Просмотреть файл

@ -0,0 +1,51 @@
{
"$schema": "https://schemas.botframework.com/schemas/component/v1.0/component.schema",
"$role": "implements(Microsoft.IDialog)",
"title": "Send messaging extension auth response",
"description": "If the user is signed in, the dialog will end setting the TokenResponse in the specified property.",
"type": "object",
"properties": {
"id": {
"type": "string",
"title": "Id",
"description": "Optional id for the dialog"
},
"cacheType": {
"type": "string",
"title": "Cache type",
"description": "Optional type of cache: 'cache' or 'no_cache'."
},
"cacheDuration": {
"type": "string",
"title": "Cache duration",
"description": "Optional duration in seconds of the result in the cache."
},
"connectionName": {
"$ref": "schema:#/definitions/stringExpression",
"title": "OAuth connection name",
"description": "The OAuth Connection Name, that will be used to perform the Sign On.",
"default": "=settings.connectionName"
},
"title": {
"$ref": "schema:#/definitions/stringExpression",
"title": "Title",
"description": "Title of the response for the Suggested Actions sent back."
},
"resultProperty": {
"$ref": "schema:#/definitions/stringExpression",
"title": "Property",
"description": "Property to store the TokenResponse in once Sign In completes.",
"examples": [
"dialog.userName"
]
},
"disabled": {
"$ref": "schema:#/definitions/booleanExpression",
"title": "Disabled",
"description": "Optional condition which if true will disable this action.",
"examples": [
"=user.age > 3"
]
}
}
}

Просмотреть файл

@ -0,0 +1,13 @@
{
"$schema": "https://schemas.botframework.com/schemas/ui/v1.0/ui.schema",
"form": {
"label": "Messaging Extension auth response",
"subtitle": "Send a response to a messaging extensin requiring auth.",
"order": [
"connectionName",
"title",
"resultProperty",
"*"
]
}
}

Просмотреть файл

@ -0,0 +1,37 @@
{
"$schema": "https://schemas.botframework.com/schemas/component/v1.0/component.schema",
"$role": "implements(Microsoft.IDialog)",
"title": "Send a bot message preview response",
"description": "Send a bot message preview response to a messaging extension request.",
"type": "object",
"properties": {
"id": {
"type": "string",
"title": "Id",
"description": "Optional id for the dialog"
},
"cacheType": {
"type": "string",
"title": "Cache type",
"description": "Optional type of cache: 'cache' or 'no_cache'."
},
"cacheDuration": {
"type": "string",
"title": "Cache duration",
"description": "Optional duration in seconds of the result in the cache."
},
"card": {
"$kind": "Microsoft.IActivityTemplate",
"title": "Card",
"description": "Expession for an Attachment template of Hero Card or Adaptive Card to send. Attachment is required."
},
"disabled": {
"$ref": "schema:#/definitions/booleanExpression",
"title": "Disabled",
"description": "Optional condition which if true will disable this action.",
"examples": [
"=user.age > 3"
]
}
}
}

Просмотреть файл

@ -0,0 +1,13 @@
{
"$schema": "https://schemas.botframework.com/schemas/ui/v1.0/ui.schema",
"form": {
"label": "Send a bot message preview response",
"subtitle": "Send a bot message preview response to a messaging extension request.",
"order": [
"card",
"cacheType",
"cacheDuration",
"*"
]
}
}

Просмотреть файл

@ -0,0 +1,41 @@
{
"$schema": "https://schemas.botframework.com/schemas/component/v1.0/component.schema",
"$role": "implements(Microsoft.IDialog)",
"title": "Send query link response",
"description": "Query link requests have activity.name='composeExtension/queryLink'.",
"type": "object",
"properties": {
"id": {
"type": "string",
"title": "Id",
"description": "Optional id for the dialog"
},
"cacheType": {
"type": "string",
"title": "Cache type",
"description": "Optional type of cache: 'cache' or 'no_cache'."
},
"cacheDuration": {
"type": "string",
"title": "Cache duration",
"description": "Optional duration in seconds of the result in the cache."
},
"configUrl": {
"$ref": "schema:#/definitions/stringExpression",
"title": "Configuration url",
"description": "Url to use for the configuration page path.",
"examples": [
"https://mysite.com/config.html",
"=user.surveySiteUrl"
]
},
"disabled": {
"$ref": "schema:#/definitions/booleanExpression",
"title": "Disabled",
"description": "Optional condition which if true will disable this action.",
"examples": [
"=user.age > 3"
]
}
}
}

Просмотреть файл

@ -0,0 +1,13 @@
{
"$schema": "https://schemas.botframework.com/schemas/ui/v1.0/ui.schema",
"form": {
"label": "Send a configuration query setting response",
"subtitle": "Send a response to a query setting configuration url request.",
"order": [
"configUrl",
"cacheType",
"cacheDuration",
"*"
]
}
}

Просмотреть файл

@ -0,0 +1,40 @@
{
"$schema": "https://schemas.botframework.com/schemas/component/v1.0/component.schema",
"$role": "implements(Microsoft.IDialog)",
"title": "Send messaging extension message response",
"description": "Send a message response to a messaging extension request.",
"type": "object",
"properties": {
"id": {
"type": "string",
"title": "Id",
"description": "Optional id for the dialog"
},
"cacheType": {
"type": "string",
"title": "Cache type",
"description": "Optional type of cache: 'cache' or 'no_cache'."
},
"cacheDuration": {
"type": "string",
"title": "Cache duration",
"description": "Optional duration in seconds of the result in the cache."
},
"message": {
"$ref": "schema:#/definitions/stringExpression",
"title": "Message",
"description": "The response message to send.",
"examples": [
"Thanks, have a nice day! :)"
]
},
"disabled": {
"$ref": "schema:#/definitions/booleanExpression",
"title": "Disabled",
"description": "Optional condition which if true will disable this action.",
"examples": [
"=user.age > 3"
]
}
}
}

Просмотреть файл

@ -0,0 +1,13 @@
{
"$schema": "https://schemas.botframework.com/schemas/ui/v1.0/ui.schema",
"form": {
"label": "Send messaging extension message response",
"subtitle": "Send a message response containing text only.",
"order": [
"message",
"cacheType",
"cacheDuration",
"*"
]
}
}

Просмотреть файл

@ -0,0 +1,37 @@
{
"$schema": "https://schemas.botframework.com/schemas/component/v1.0/component.schema",
"$role": "implements(Microsoft.IDialog)",
"title": "Send a messaging extension response when an item is selected",
"description": "Query link requests have activity.name='composeExtension/queryLink'.",
"type": "object",
"properties": {
"id": {
"type": "string",
"title": "Id",
"description": "Optional id for the dialog"
},
"cacheType": {
"type": "string",
"title": "Cache type",
"description": "Optional type of cache: 'cache' or 'no_cache'."
},
"cacheDuration": {
"type": "string",
"title": "Cache duration",
"description": "Optional duration in seconds of the result in the cache."
},
"card": {
"$kind": "Microsoft.IActivityTemplate",
"title": "Card",
"description": "Expression for an Attachment template of Hero Card or Adaptive Card to send. Attachment is required."
},
"disabled": {
"$ref": "schema:#/definitions/booleanExpression",
"title": "Disabled",
"description": "Optional condition which if true will disable this action.",
"examples": [
"=user.age > 3"
]
}
}
}

Просмотреть файл

@ -0,0 +1,13 @@
{
"$schema": "https://schemas.botframework.com/schemas/ui/v1.0/ui.schema",
"form": {
"label": "Send a card response on item selection",
"subtitle": "Send a messaging extension response when an item is selected",
"order": [
"card",
"cacheType",
"cacheDuration",
"*"
]
}
}

Просмотреть файл

@ -0,0 +1,66 @@
{
"$schema": "https://schemas.botframework.com/schemas/component/v1.0/component.schema",
"$role": "implements(Microsoft.IDialog)",
"title": "Send task module card response",
"description": "Send a card response to a Task Module request.",
"type": "object",
"properties": {
"id": {
"type": "string",
"title": "Id",
"description": "Optional id for the dialog"
},
"cacheType": {
"type": "string",
"title": "Cache type",
"description": "Optional type of cache: 'cache' or 'no_cache'."
},
"cacheDuration": {
"type": "string",
"title": "Cache duration",
"description": "Optional duration in seconds of the result in the cache."
},
"title": {
"$ref": "schema:#/definitions/stringExpression",
"title": "Title",
"description": "Title of the Task Module Response.",
"examples": [
"Bot Task Module"
]
},
"height": {
"$ref": "schema:#/definitions/integerExpression",
"title": "Height",
"description": "Height of the Task Module Response.",
"examples": [
"450"
]
},
"width": {
"$ref": "schema:#/definitions/integerExpression",
"title": "Width",
"description": "Width of the Task Module Response.",
"examples": [
"450"
]
},
"card": {
"$kind": "Microsoft.IActivityTemplate",
"title": "Card",
"description": "Expession for an Attachment template of Hero Card or Adaptive Card to send. Attachment is required."
},
"completionBotId": {
"type": "string",
"title": "completionBotId",
"description": "an optional expression for the Completion Bot Id of the Task Module Task Info response. This is a bot App ID to send the result of the user's interaction with the task module to. If specified, the bot will receive a task/submit invoke event with a JSON object in the event payload."
},
"disabled": {
"$ref": "schema:#/definitions/booleanExpression",
"title": "Disabled",
"description": "Optional condition which if true will disable this action.",
"examples": [
"=user.age > 3"
]
}
}
}

Просмотреть файл

@ -0,0 +1,17 @@
{
"$schema": "https://schemas.botframework.com/schemas/ui/v1.0/ui.schema",
"form": {
"label": "Send task module card response",
"subtitle": "Send a continue response containing a card.",
"order": [
"card",
"title",
"height",
"width",
"cacheType",
"cacheDuration",
"completionBotId",
"*"
]
}
}

Просмотреть файл

@ -0,0 +1,40 @@
{
"$schema": "https://schemas.botframework.com/schemas/component/v1.0/component.schema",
"$role": "implements(Microsoft.IDialog)",
"title": "Send task module message response",
"description": "Send a message response to a Task Module request.",
"type": "object",
"properties": {
"id": {
"type": "string",
"title": "Id",
"description": "Optional id for the dialog"
},
"cacheType": {
"type": "string",
"title": "Cache type",
"description": "Optional type of cache: 'cache' or 'no_cache'."
},
"cacheDuration": {
"type": "string",
"title": "Cache duration",
"description": "Optional duration in seconds of the result in the cache."
},
"message": {
"$ref": "schema:#/definitions/stringExpression",
"title": "Message",
"description": "The response message to send.",
"examples": [
"Thanks, have a nice day! :)"
]
},
"disabled": {
"$ref": "schema:#/definitions/booleanExpression",
"title": "Disabled",
"description": "Optional condition which if true will disable this action.",
"examples": [
"=user.age > 3"
]
}
}
}

Просмотреть файл

@ -0,0 +1,13 @@
{
"$schema": "https://schemas.botframework.com/schemas/ui/v1.0/ui.schema",
"form": {
"label": "Send task module message response",
"subtitle": "Send a message response containing text only.",
"order": [
"message",
"cacheType",
"cacheDuration",
"*"
]
}
}

Просмотреть файл

@ -0,0 +1,79 @@
{
"$schema": "https://schemas.botframework.com/schemas/component/v1.0/component.schema",
"$role": "implements(Microsoft.IDialog)",
"title": "Send task module url response",
"description": "Send a url type continue response to a Task Module request.",
"type": "object",
"properties": {
"id": {
"type": "string",
"title": "Id",
"description": "Optional id for the dialog"
},
"cacheType": {
"type": "string",
"title": "Cache type",
"description": "Optional type of cache: 'cache' or 'no_cache'."
},
"cacheDuration": {
"type": "string",
"title": "Cache duration",
"description": "Optional duration in seconds of the result in the cache."
},
"title": {
"$ref": "schema:#/definitions/stringExpression",
"title": "Title",
"description": "Title of the Task Module Response.",
"examples": [
"Bot Task Module"
]
},
"height": {
"$ref": "schema:#/definitions/integerExpression",
"title": "Height",
"description": "Height of the Task Module Response.",
"examples": [
"450"
]
},
"width": {
"$ref": "schema:#/definitions/integerExpression",
"title": "Width",
"description": "Width of the Task Module Response.",
"examples": [
"450"
]
},
"url": {
"$ref": "schema:#/definitions/stringExpression",
"title": "Url",
"description": "Url to use for the Task Module Response.",
"examples": [
"https://mysite.com",
"=user.surveySiteUrl"
]
},
"fallbackUrl": {
"$ref": "schema:#/definitions/stringExpression",
"title": "Fallback Url",
"description": "Fallback Url to use for the Task Module Response.",
"examples": [
"https://fallbacksite.com",
"=user.surveySiteFallbackUrl"
]
},
"completionBotId": {
"type": "string",
"title": "completionBotId",
"description": "an optional expression for the Completion Bot Id of the Task Module Task Info response. This is a bot App ID to send the result of the user's interaction with the task module to. If specified, the bot will receive a task/submit invoke event with a JSON object in the event payload."
},
"disabled": {
"$ref": "schema:#/definitions/booleanExpression",
"title": "Disabled",
"description": "Optional condition which if true will disable this action.",
"examples": [
"=user.age > 3"
]
}
}
}

Просмотреть файл

@ -0,0 +1,18 @@
{
"$schema": "https://schemas.botframework.com/schemas/ui/v1.0/ui.schema",
"form": {
"label": "Send task module url response",
"subtitle": "Send a continue response containing a url.",
"order": [
"title",
"url",
"fallbackUrl",
"height",
"width",
"cacheType",
"cacheDuration",
"completionBotId",
"*"
]
}
}

Просмотреть файл

@ -1,9 +1,12 @@
{
"$schema": "https://schemas.botframework.com/schemas/component/v1.0/component.schema",
"$role": [ "implements(Microsoft.ITrigger)", "extends(Microsoft.OnCondition)" ],
"title": "OnTeamsAppBasedLinkQuery",
"title": "On app based link query",
"description": "Actions triggered when a Teams activity is received with activity.name == 'composeExtension/queryLink'.",
"type": "object",
"hidden": [
"actions"
],
"required": [
]
}

Просмотреть файл

@ -0,0 +1,14 @@
{
"$schema": "https://schemas.botframework.com/schemas/ui/v1.0/ui.schema",
"form": {
"order": [
"condition",
"*"
],
"hidden": [
"actions"
],
"label": "Teams app based link query",
"subtitle": "Invoke activity.name='composeExtension/queryLink'"
}
}

Просмотреть файл

@ -1,7 +1,7 @@
{
"$schema": "https://schemas.botframework.com/schemas/component/v1.0/component.schema",
"$role": [ "implements(Microsoft.ITrigger)", "extends(Microsoft.OnCondition)" ],
"title": "OnTeamsCardAction",
"title": "On Teams card action",
"description": "Actions triggered when a Teams InvokeActivity is received with no activity.name.",
"type": "object",
"required": [

Просмотреть файл

@ -0,0 +1,14 @@
{
"$schema": "https://schemas.botframework.com/schemas/ui/v1.0/ui.schema",
"form": {
"order": [
"condition",
"*"
],
"hidden": [
"actions"
],
"label": "Teams card action invoke",
"subtitle": "Invoke activity with no activity.name"
}
}

Просмотреть файл

@ -1,7 +1,7 @@
{
"$schema": "https://schemas.botframework.com/schemas/component/v1.0/component.schema",
"$role": [ "implements(Microsoft.ITrigger)", "extends(Microsoft.OnCondition)" ],
"title": "OnTeamsChannelCreated",
"title": "On Teams channel created",
"description": "Actions triggered when a Teams ConversationUpdateActivity with channelData.eventType == 'channelCreated'.",
"type": "object",
"required": [

Просмотреть файл

@ -1,7 +1,7 @@
{
"$schema": "https://schemas.botframework.com/schemas/component/v1.0/component.schema",
"$role": [ "implements(Microsoft.ITrigger)", "extends(Microsoft.OnCondition)" ],
"title": "OnTeamsChannelDeleted",
"title": "On Teams channel deleted",
"description": "Actions triggered when a Teams ConversationUpdateActivity with channelData.eventType == 'channelDeleted'.",
"type": "object",
"required": [

Просмотреть файл

@ -1,7 +1,7 @@
{
"$schema": "https://schemas.botframework.com/schemas/component/v1.0/component.schema",
"$role": [ "implements(Microsoft.ITrigger)", "extends(Microsoft.OnCondition)" ],
"title": "OnTeamsChannelRenamed",
"title": "On Teams channel renamed",
"description": "Actions triggered when a Teams ConversationUpdateActivity with channelData.eventType == 'channelRenamed'.",
"type": "object",
"required": [

Просмотреть файл

@ -1,7 +1,7 @@
{
"$schema": "https://schemas.botframework.com/schemas/component/v1.0/component.schema",
"$role": [ "implements(Microsoft.ITrigger)", "extends(Microsoft.OnCondition)" ],
"title": "OnTeamsChannelRestored",
"title": "On Teams channel restored",
"description": "Actions triggered when a Teams ConversationUpdateActivity with channelData.eventType == 'channelRestored'.",
"type": "object",
"required": [

Просмотреть файл

@ -1,7 +1,7 @@
{
"$schema": "https://schemas.botframework.com/schemas/component/v1.0/component.schema",
"$role": [ "implements(Microsoft.ITrigger)", "extends(Microsoft.OnCondition)" ],
"title": "OnTeamsFileConsent",
"title": "On Teams file consent",
"description": "Actions triggered when a Teams InvokeActivity is received with activity.name == 'fileConsent/invoke'.",
"type": "object",
"required": [

Просмотреть файл

@ -0,0 +1,9 @@
{
"$schema": "https://schemas.botframework.com/schemas/component/v1.0/component.schema",
"$role": [ "implements(Microsoft.ITrigger)", "extends(Microsoft.OnCondition)" ],
"title": "On teams messaging extension preview edit submit action",
"description": "Actions triggered when a Teams InvokeActivity is received with activity.name='composeExtension/submitAction' and activity.value.botMessagePreviewAction == 'edit'.",
"type": "object",
"required": [
]
}

Просмотреть файл

@ -0,0 +1,14 @@
{
"$schema": "https://schemas.botframework.com/schemas/ui/v1.0/ui.schema",
"form": {
"order": [
"condition",
"*"
],
"hidden": [
"actions"
],
"label": "Teams messaging extension preview edit submit action",
"subtitle": "Invoke with activity.value.botMessagePreviewAction == 'edit'"
}
}

Просмотреть файл

@ -0,0 +1,9 @@
{
"$schema": "https://schemas.botframework.com/schemas/component/v1.0/component.schema",
"$role": [ "implements(Microsoft.ITrigger)", "extends(Microsoft.OnCondition)" ],
"title": "On teams messaging extension preview send submit action",
"description": "Actions triggered when a Teams InvokeActivity is received with activity.name='composeExtension/submitAction' and activity.value.botMessagePreviewAction == 'send'.",
"type": "object",
"required": [
]
}

Просмотреть файл

@ -0,0 +1,14 @@
{
"$schema": "https://schemas.botframework.com/schemas/ui/v1.0/ui.schema",
"form": {
"order": [
"condition",
"*"
],
"hidden": [
"actions"
],
"label": "Teams messaging extension preview send submit action",
"subtitle": "Invoke with activity.value.botMessagePreviewAction == 'send'"
}
}

Просмотреть файл

@ -1,7 +1,7 @@
{
"$schema": "https://schemas.botframework.com/schemas/component/v1.0/component.schema",
"$role": [ "implements(Microsoft.ITrigger)", "extends(Microsoft.OnCondition)" ],
"title": "OnTeamsMessagingExtensionCardButtonClicked",
"title": "On Teams messaging extension card button clicked",
"description": "Actions triggered when a Teams InvokeActivity is received with activity.name='composeExtension/onCardButtonClicked'.",
"type": "object",
"required": [

Просмотреть файл

@ -0,0 +1,14 @@
{
"$schema": "https://schemas.botframework.com/schemas/ui/v1.0/ui.schema",
"form": {
"order": [
"condition",
"*"
],
"hidden": [
"actions"
],
"label": "Teams messaging extension card button clicked",
"subtitle": "Invoke activity.name='composeExtension/onCardButtonClicked'"
}
}

Просмотреть файл

@ -1,7 +1,7 @@
{
"$schema": "https://schemas.botframework.com/schemas/component/v1.0/component.schema",
"$role": [ "implements(Microsoft.ITrigger)", "extends(Microsoft.OnCondition)" ],
"title": "OnTeamsMessagingExtensionConfigurationQuerySettingUrl",
"title": "On Teams messaging extension configuration query setting url",
"description": "Actions triggered when a Teams InvokeActivity is received with name='composeExtension/querySettingUrl'.",
"type": "object",
"required": [

Просмотреть файл

@ -0,0 +1,14 @@
{
"$schema": "https://schemas.botframework.com/schemas/ui/v1.0/ui.schema",
"form": {
"order": [
"condition",
"*"
],
"hidden": [
"actions"
],
"label": "Teams messaging extension configuration query setting url",
"subtitle": "Invoke activity.name='composeExtension/querySettingUrl'"
}
}

Просмотреть файл

@ -1,7 +1,7 @@
{
"$schema": "https://schemas.botframework.com/schemas/component/v1.0/component.schema",
"$role": [ "implements(Microsoft.ITrigger)", "extends(Microsoft.OnCondition)" ],
"title": "OnTeamsMessagingExtensionConfigurationSetting",
"title": "On Teams messaging extension configuration setting",
"description": "Actions triggered when a Teams InvokeActivity is received with activity.name='composeExtension/setting'.",
"type": "object",
"required": [

Просмотреть файл

@ -0,0 +1,14 @@
{
"$schema": "https://schemas.botframework.com/schemas/ui/v1.0/ui.schema",
"form": {
"order": [
"condition",
"*"
],
"hidden": [
"actions"
],
"label": "Teams messaging extension configuration setting",
"subtitle": "Invoke activity.name='composeExtension/setting'"
}
}

Просмотреть файл

@ -1,7 +1,7 @@
{
"$schema": "https://schemas.botframework.com/schemas/component/v1.0/component.schema",
"$role": [ "implements(Microsoft.ITrigger)", "extends(Microsoft.OnCondition)" ],
"title": "OnTeamsMessagingExtensionFetchTask",
"title": "On Teams messaging extension fetch task",
"description": "Actions triggered when a Teams InvokeActivity is received when activity.name='composeExtension/fetchTask'.",
"type": "object",
"required": [

Просмотреть файл

@ -0,0 +1,14 @@
{
"$schema": "https://schemas.botframework.com/schemas/ui/v1.0/ui.schema",
"form": {
"order": [
"condition",
"*"
],
"hidden": [
"actions"
],
"label": "Teams messaging extension fetch task",
"subtitle": "Invoke activity.name='composeExtension/fetchTask'"
}
}

Просмотреть файл

@ -1,7 +1,7 @@
{
"$schema": "https://schemas.botframework.com/schemas/component/v1.0/component.schema",
"$role": [ "implements(Microsoft.ITrigger)", "extends(Microsoft.OnCondition)" ],
"title": "OnTeamsMessagingExtensionQuery",
"title": "On Teams messaging extension query",
"description": "Actions triggered when a Teams InvokeActivity is received with activity.name='composeExtension/query'.",
"type": "object",
"required": [

Просмотреть файл

@ -0,0 +1,14 @@
{
"$schema": "https://schemas.botframework.com/schemas/ui/v1.0/ui.schema",
"form": {
"order": [
"condition",
"*"
],
"hidden": [
"actions"
],
"label": "Teams messaging extension query",
"subtitle": "Invoke activity.name='composeExtension/query'"
}
}

Просмотреть файл

@ -1,7 +1,7 @@
{
"$schema": "https://schemas.botframework.com/schemas/component/v1.0/component.schema",
"$role": [ "implements(Microsoft.ITrigger)", "extends(Microsoft.OnCondition)" ],
"title": "OnTeamsMessagingExtensionSelectItem",
"title": "On Teams messaging extension select item",
"description": "Actions triggered when a Teams InvokeActivity is received with activity.name='composeExtension/selectItem'.",
"type": "object",
"required": [

Просмотреть файл

@ -0,0 +1,14 @@
{
"$schema": "https://schemas.botframework.com/schemas/ui/v1.0/ui.schema",
"form": {
"order": [
"condition",
"*"
],
"hidden": [
"actions"
],
"label": "Teams messaging extension select item",
"subtitle": "Invoke activity.name='composeExtension/selectItem'"
}
}

Просмотреть файл

@ -1,7 +1,7 @@
{
"$schema": "https://schemas.botframework.com/schemas/component/v1.0/component.schema",
"$role": [ "implements(Microsoft.ITrigger)", "extends(Microsoft.OnCondition)" ],
"title": "OnTeamsMessagingExtensionSubmitAction",
"title": "On teams messaging extension submit action",
"description": "Actions triggered when a Teams InvokeActivity is received with activity.name='composeExtension/submitAction'.",
"type": "object",
"required": [

Просмотреть файл

@ -0,0 +1,14 @@
{
"$schema": "https://schemas.botframework.com/schemas/ui/v1.0/ui.schema",
"form": {
"order": [
"condition",
"*"
],
"hidden": [
"actions"
],
"label": "Teams messaging extension submit action",
"subtitle": "Invoke activity.name='composeExtension/submitAction'"
}
}

Просмотреть файл

@ -1,7 +1,7 @@
{
"$schema": "https://schemas.botframework.com/schemas/component/v1.0/component.schema",
"$role": [ "implements(Microsoft.ITrigger)", "extends(Microsoft.OnCondition)" ],
"title": "OnTeamsO365ConnectorCardAction",
"title": "On Teams O365 connector card action",
"description": "Actions triggered when a Teams InvokeActivity is received for 'actionableMessage/executeAction'.",
"type": "object",
"required": [

Просмотреть файл

@ -0,0 +1,14 @@
{
"$schema": "https://schemas.botframework.com/schemas/ui/v1.0/ui.schema",
"form": {
"order": [
"condition",
"*"
],
"hidden": [
"actions"
],
"label": "Teams O365 connector card action",
"subtitle": "Invoke activity.name='actionableMessage/executeAction'"
}
}

Просмотреть файл

@ -1,9 +1,9 @@
{
"$schema": "https://schemas.botframework.com/schemas/component/v1.0/component.schema",
"$role": [ "implements(Microsoft.ITrigger)", "extends(Microsoft.OnCondition)" ],
"title": "OnTeamsTaskModuleFetch",
"description": "Actions triggered when a Teams InvokeActivity is received with activity.name='task/fetch'.",
"title": "On Teams task module fetch",
"description": "Actions triggered when a Teams Invoke Activity is received with activity.name='task/fetch'.",
"type": "object",
"required": [
]
}
}

Просмотреть файл

@ -0,0 +1,14 @@
{
"$schema": "https://schemas.botframework.com/schemas/ui/v1.0/ui.schema",
"form": {
"order": [
"condition",
"*"
],
"hidden": [
"actions"
],
"label": "Teams task module fetch",
"subtitle": "Invoke activity.name='task/fetch'"
}
}

Просмотреть файл

@ -1,7 +1,7 @@
{
"$schema": "https://schemas.botframework.com/schemas/component/v1.0/component.schema",
"$role": [ "implements(Microsoft.ITrigger)", "extends(Microsoft.OnCondition)" ],
"title": "OnTeamsTaskModuleSubmit",
"title": "On Teams task module submit",
"description": "Actions triggered when a Teams InvokeActivity is received with activity.name='task/submit'.",
"type": "object",
"required": [

Просмотреть файл

@ -0,0 +1,14 @@
{
"$schema": "https://schemas.botframework.com/schemas/ui/v1.0/ui.schema",
"form": {
"order": [
"condition",
"*"
],
"hidden": [
"actions"
],
"label": "Teams task module submit",
"subtitle": "Invoke activity.name='task/submit'"
}
}

Просмотреть файл

@ -1,7 +1,7 @@
{
"$schema": "https://schemas.botframework.com/schemas/component/v1.0/component.schema",
"$role": [ "implements(Microsoft.ITrigger)", "extends(Microsoft.OnCondition)" ],
"title": "OnTeamsTeamArchived",
"title": "On Teams team archived",
"description": "Actions triggered when a Teams ConversationUpdate with channelData.eventType == 'teamArchived'.",
"type": "object",
"required": [

Просмотреть файл

@ -1,7 +1,7 @@
{
"$schema": "https://schemas.botframework.com/schemas/component/v1.0/component.schema",
"$role": [ "implements(Microsoft.ITrigger)", "extends(Microsoft.OnCondition)" ],
"title": "OnTeamsTeamDeleted",
"title": "On Teams team deleted",
"description": "Actions triggered when a Teams ConversationUpdate with channelData.eventType == 'teamDeleted'.",
"type": "object",
"required": [

Просмотреть файл

@ -1,7 +1,7 @@
{
"$schema": "https://schemas.botframework.com/schemas/component/v1.0/component.schema",
"$role": [ "implements(Microsoft.ITrigger)", "extends(Microsoft.OnCondition)" ],
"title": "OnTeamsTeamHardDeleted",
"title": "On Teams team hard deleted",
"description": "Actions triggered when a Teams ConversationUpdate with channelData.eventType == 'teamHardDeleted'.",
"type": "object",
"required": [

Просмотреть файл

@ -1,7 +1,7 @@
{
"$schema": "https://schemas.botframework.com/schemas/component/v1.0/component.schema",
"$role": [ "implements(Microsoft.ITrigger)", "extends(Microsoft.OnCondition)" ],
"title": "OnTeamsTeamRenamed",
"title": "On Teams team renamed",
"description": "Actions triggered when a Teams ConversationUpdate with channelData.eventType == 'teamRenamed'.",
"type": "object",
"required": [

Просмотреть файл

@ -1,7 +1,7 @@
{
"$schema": "https://schemas.botframework.com/schemas/component/v1.0/component.schema",
"$role": [ "implements(Microsoft.ITrigger)", "extends(Microsoft.OnCondition)" ],
"title": "OnTeamsTeamRestored",
"title": "On Teams team restored",
"description": "Actions triggered when a Teams ConversationUpdate with channelData.eventType == 'teamRestored'.",
"type": "object",
"required": [

Просмотреть файл

@ -1,7 +1,7 @@
{
"$schema": "https://schemas.botframework.com/schemas/component/v1.0/component.schema",
"$role": [ "implements(Microsoft.ITrigger)", "extends(Microsoft.OnCondition)" ],
"title": "OnTeamsTeamUnarchived",
"title": "On Teams team unarchived",
"description": "Actions triggered when a Teams ConversationUpdate with channelData.eventType == 'teamUnarchived'.",
"type": "object",
"required": [

Просмотреть файл

@ -2,7 +2,8 @@
// Licensed under the MIT License.
using System.Collections.Generic;
using Microsoft.Bot.Builder.Dialogs.Adaptive.Actions;
using Microsoft.Bot.Builder.Dialogs.Adaptive.Teams.Actions;
using Microsoft.Bot.Builder.Dialogs.Adaptive.Teams.Conditions;
using Microsoft.Bot.Builder.Dialogs.Debugging;
using Microsoft.Bot.Builder.Dialogs.Declarative;
using Microsoft.Bot.Builder.Dialogs.Declarative.Resources;
@ -38,11 +39,31 @@ namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Teams
yield return new DeclarativeType<OnTeamsTeamRenamed>(OnTeamsTeamRenamed.Kind);
yield return new DeclarativeType<OnTeamsTeamRestored>(OnTeamsTeamRestored.Kind);
yield return new DeclarativeType<OnTeamsTeamUnarchived>(OnTeamsTeamUnarchived.Kind);
yield return new DeclarativeType<OnTeamsMessagingExtensionBotMessagePreviewEdit>(OnTeamsMessagingExtensionBotMessagePreviewEdit.Kind);
yield return new DeclarativeType<OnTeamsMessagingExtensionBotMessagePreviewSend>(OnTeamsMessagingExtensionBotMessagePreviewSend.Kind);
yield return new DeclarativeType<OnTeamsTabFetch>(OnTeamsTabFetch.Kind);
yield return new DeclarativeType<OnTeamsTabSubmit>(OnTeamsTabSubmit.Kind);
// Actions
yield return new DeclarativeType<GetMeetingParticipant>(GetMeetingParticipant.Kind);
yield return new DeclarativeType<GetMember>(GetMember.Kind);
yield return new DeclarativeType<GetPagedMembers>(GetPagedMembers.Kind);
yield return new DeclarativeType<GetPagedTeamMembers>(GetPagedTeamMembers.Kind);
yield return new DeclarativeType<GetTeamChannels>(GetTeamChannels.Kind);
yield return new DeclarativeType<GetTeamDetails>(GetTeamDetails.Kind);
yield return new DeclarativeType<GetTeamMember>(GetTeamMember.Kind);
yield return new DeclarativeType<SendAppBasedLinkQueryResponse>(SendAppBasedLinkQueryResponse.Kind);
yield return new DeclarativeType<SendMessageToTeamsChannel>(SendMessageToTeamsChannel.Kind);
yield return new DeclarativeType<SendMessagingExtensionActionResponse>(SendMessagingExtensionActionResponse.Kind);
yield return new DeclarativeType<SendMessagingExtensionAttachmentsResponse>(SendMessagingExtensionAttachmentsResponse.Kind);
yield return new DeclarativeType<SendMessagingExtensionAuthResponse>(SendMessagingExtensionAuthResponse.Kind);
yield return new DeclarativeType<SendMessagingExtensionBotMessagePreviewResponse>(SendMessagingExtensionBotMessagePreviewResponse.Kind);
yield return new DeclarativeType<SendMessagingExtensionConfigQuerySettingUrlResponse>(SendMessagingExtensionConfigQuerySettingUrlResponse.Kind);
yield return new DeclarativeType<SendMessagingExtensionMessageResponse>(SendMessagingExtensionMessageResponse.Kind);
yield return new DeclarativeType<SendMessagingExtensionSelectItemResponse>(SendMessagingExtensionSelectItemResponse.Kind);
yield return new DeclarativeType<SendTaskModuleCardResponse>(SendTaskModuleCardResponse.Kind);
yield return new DeclarativeType<SendTaskModuleMessageResponse>(SendTaskModuleMessageResponse.Kind);
yield return new DeclarativeType<SendTaskModuleUrlResponse>(SendTaskModuleUrlResponse.Kind);
}
public virtual IEnumerable<JsonConverter> GetConverters(ResourceExplorer resourceExplorer, SourceContext sourceContext)

Просмотреть файл

@ -7,7 +7,7 @@ using AdaptiveExpressions;
using Microsoft.Bot.Builder.Dialogs.Adaptive.Conditions;
using Newtonsoft.Json;
namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Teams
namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Teams.Conditions
{
/// <summary>
/// Actions triggered when a Teams InvokeActivity is received with activity.name == 'composeExtension/queryLink'.

Просмотреть файл

@ -8,7 +8,7 @@ using Microsoft.Bot.Builder.Dialogs.Adaptive.Conditions;
using Microsoft.Bot.Connector;
using Newtonsoft.Json;
namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Teams
namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Teams.Conditions
{
/// <summary>
/// Actions triggered when a Teams InvokeActivity is received with no activity.name.

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше