// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
using System.Text.Json;
using Microsoft.Teams.Apps.Routing;
using Microsoft.Teams.Apps.Schema;
namespace Microsoft.Teams.Apps.Handlers.MessageExtension;
///
/// Delegate for handling message extension query invoke activities.
///
public delegate Task> MessageExtensionQueryHandler(Context> context, CancellationToken cancellationToken = default);
///
/// Delegate for handling message extension submit action invoke activities.
/// Can return either a TaskModuleResponse or MessageExtensionResponse.
///
public delegate Task> MessageExtensionSubmitActionHandler(Context> context, CancellationToken cancellationToken = default);
///
/// Delegate for handling message extension fetch task invoke activities.
/// Can return either a TaskModuleResponse or MessageExtensionResponse.
///
public delegate Task> MessageExtensionFetchTaskHandler(Context> context, CancellationToken cancellationToken = default);
///
/// Delegate for handling message extension query link invoke activities.
///
public delegate Task> MessageExtensionQueryLinkHandler(Context> context, CancellationToken cancellationToken = default);
///
/// Delegate for handling message extension anonymous query link invoke activities.
///
public delegate Task> MessageExtensionAnonQueryLinkHandler(Context> context, CancellationToken cancellationToken = default);
///
/// Delegate for handling message extension select item invoke activities.
///
public delegate Task> MessageExtensionSelectItemHandler(Context> context, CancellationToken cancellationToken = default);
///
/// Delegate for handling message extension query setting URL invoke activities.
///
public delegate Task> MessageExtensionQuerySettingUrlHandler(Context> context, CancellationToken cancellationToken = default);
/*
///
/// Delegate for handling message extension card button clicked invoke activities.
///
public delegate Task MessageExtensionCardButtonClickedHandler(Context> context, CancellationToken cancellationToken = default);
///
/// Delegate for handling message extension setting invoke activities.
///
public delegate Task MessageExtensionSettingHandler(Context> context, CancellationToken cancellationToken = default);
*/
///
/// Extension methods for registering message extension invoke handlers.
///
public static class MessageExtensionExtensions
{
//TODO : add msg ext prefix to handlers ? very confusing right now as we have both onFetchTask and onTaskFetch.
//onSubmitAction is confusing as it is similar to adaptive cards
///
/// Registers a handler for message extension query invoke activities.
/// Cannot be combined with .
///
///
/// Breaking change: previously a catch-all invoke handler could be registered alongside specific invoke handlers. This combination now throws at registration time.
///
/// The Teams bot application.
/// The handler to register.
/// The updated Teams bot application.
public static TeamsBotApplication OnQuery(this TeamsBotApplication app, MessageExtensionQueryHandler handler)
{
ArgumentNullException.ThrowIfNull(app, nameof(app));
app.Router.Register(new Route
{
Name = string.Join("/", TeamsActivityTypes.Invoke, InvokeNames.MessageExtensionQuery),
Selector = activity => activity.Name == InvokeNames.MessageExtensionQuery,
HandlerWithReturn = async (ctx, cancellationToken) =>
{
InvokeActivity typedActivity = new(ctx.Activity);
var typedContext = ctx.CreateDerivedContext(typedActivity);
return await handler(typedContext, cancellationToken).ConfigureAwait(false);
}
});
return app;
}
///
/// Registers a handler for message extension submit action invoke activities.
/// Cannot be combined with .
///
///
/// Breaking change: previously a catch-all invoke handler could be registered alongside specific invoke handlers. This combination now throws at registration time.
///
/// The Teams bot application.
/// The handler to register.
/// The updated Teams bot application.
public static TeamsBotApplication OnSubmitAction(this TeamsBotApplication app, MessageExtensionSubmitActionHandler handler)
{
ArgumentNullException.ThrowIfNull(app, nameof(app));
app.Router.Register(new Route
{
Name = string.Join("/", TeamsActivityTypes.Invoke, InvokeNames.MessageExtensionSubmitAction),
Selector = activity => activity.Name == InvokeNames.MessageExtensionSubmitAction,
HandlerWithReturn = async (ctx, cancellationToken) =>
{
InvokeActivity typedActivity = new(ctx.Activity);
var typedContext = ctx.CreateDerivedContext(typedActivity);
return await handler(typedContext, cancellationToken).ConfigureAwait(false);
}
});
return app;
}
///
/// Registers a handler for message extension query link invoke activities.
/// Cannot be combined with .
///
///
/// Breaking change: previously a catch-all invoke handler could be registered alongside specific invoke handlers. This combination now throws at registration time.
///
/// The Teams bot application.
/// The handler to register.
/// The updated Teams bot application.
public static TeamsBotApplication OnQueryLink(this TeamsBotApplication app, MessageExtensionQueryLinkHandler handler)
{
ArgumentNullException.ThrowIfNull(app, nameof(app));
app.Router.Register(new Route
{
Name = string.Join("/", TeamsActivityTypes.Invoke, InvokeNames.MessageExtensionQueryLink),
Selector = activity => activity.Name == InvokeNames.MessageExtensionQueryLink,
HandlerWithReturn = async (ctx, cancellationToken) =>
{
InvokeActivity typedActivity = new(ctx.Activity);
var typedContext = ctx.CreateDerivedContext(typedActivity);
return await handler(typedContext, cancellationToken).ConfigureAwait(false);
}
});
return app;
}
///
/// Registers a handler for message extension anonymous query link invoke activities.
/// Cannot be combined with .
///
///
/// Breaking change: previously a catch-all invoke handler could be registered alongside specific invoke handlers. This combination now throws at registration time.
///
/// The Teams bot application.
/// The handler to register.
/// The updated Teams bot application.
public static TeamsBotApplication OnAnonQueryLink(this TeamsBotApplication app, MessageExtensionAnonQueryLinkHandler handler)
{
ArgumentNullException.ThrowIfNull(app, nameof(app));
app.Router.Register(new Route
{
Name = string.Join("/", TeamsActivityTypes.Invoke, InvokeNames.MessageExtensionAnonQueryLink),
Selector = activity => activity.Name == InvokeNames.MessageExtensionAnonQueryLink,
HandlerWithReturn = async (ctx, cancellationToken) =>
{
InvokeActivity typedActivity = new(ctx.Activity);
var typedContext = ctx.CreateDerivedContext(typedActivity);
return await handler(typedContext, cancellationToken).ConfigureAwait(false);
}
});
return app;
}
///
/// Registers a handler for message extension fetch task invoke activities.
/// Cannot be combined with .
///
///
/// Breaking change: previously a catch-all invoke handler could be registered alongside specific invoke handlers. This combination now throws at registration time.
///
/// The Teams bot application.
/// The handler to register.
/// The updated Teams bot application.
public static TeamsBotApplication OnFetchTask(this TeamsBotApplication app, MessageExtensionFetchTaskHandler handler)
{
ArgumentNullException.ThrowIfNull(app, nameof(app));
app.Router.Register(new Route
{
Name = string.Join("/", TeamsActivityTypes.Invoke, InvokeNames.MessageExtensionFetchTask),
Selector = activity => activity.Name == InvokeNames.MessageExtensionFetchTask,
HandlerWithReturn = async (ctx, cancellationToken) =>
{
InvokeActivity typedActivity = new(ctx.Activity);
var typedContext = ctx.CreateDerivedContext(typedActivity);
return await handler(typedContext, cancellationToken).ConfigureAwait(false);
}
});
return app;
}
///
/// Registers a handler for message extension select item invoke activities.
/// Cannot be combined with .
///
///
/// Breaking change: previously a catch-all invoke handler could be registered alongside specific invoke handlers. This combination now throws at registration time.
///
/// The Teams bot application.
/// The handler to register.
/// The updated Teams bot application.
public static TeamsBotApplication OnSelectItem(this TeamsBotApplication app, MessageExtensionSelectItemHandler handler)
{
ArgumentNullException.ThrowIfNull(app, nameof(app));
app.Router.Register(new Route
{
Name = string.Join("/", TeamsActivityTypes.Invoke, InvokeNames.MessageExtensionSelectItem),
Selector = activity => activity.Name == InvokeNames.MessageExtensionSelectItem,
HandlerWithReturn = async (ctx, cancellationToken) =>
{
InvokeActivity typedActivity = new(ctx.Activity);
var typedContext = ctx.CreateDerivedContext(typedActivity);
return await handler(typedContext, cancellationToken).ConfigureAwait(false);
}
});
return app;
}
///
/// Registers a handler for message extension query setting URL invoke activities.
/// Cannot be combined with .
///
///
/// Breaking change: previously a catch-all invoke handler could be registered alongside specific invoke handlers. This combination now throws at registration time.
///
/// The Teams bot application.
/// The handler to register.
/// The updated Teams bot application.
public static TeamsBotApplication OnQuerySettingUrl(this TeamsBotApplication app, MessageExtensionQuerySettingUrlHandler handler)
{
ArgumentNullException.ThrowIfNull(app, nameof(app));
app.Router.Register(new Route
{
Name = string.Join("/", TeamsActivityTypes.Invoke, InvokeNames.MessageExtensionQuerySettingUrl),
Selector = activity => activity.Name == InvokeNames.MessageExtensionQuerySettingUrl,
HandlerWithReturn = async (ctx, cancellationToken) =>
{
InvokeActivity typedActivity = new(ctx.Activity);
var typedContext = ctx.CreateDerivedContext(typedActivity);
return await handler(typedContext, cancellationToken).ConfigureAwait(false);
}
});
return app;
}
}