// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
using Microsoft.Teams.Apps.Routing;
using Microsoft.Teams.Apps.Schema;
namespace Microsoft.Teams.Apps.Handlers;
///
/// Delegate for handling conversation update activities.
///
/// The context for the conversation update activity.
/// A cancellation token that can be used to cancel the operation.
/// A task representing the asynchronous operation.
public delegate Task ConversationUpdateHandler(Context context, CancellationToken cancellationToken = default);
///
/// Extension methods for registering conversation update activity handlers.
///
public static class ConversationUpdateExtensions
{
///
/// Registers a handler for conversation update activities.
///
///
/// Breaking change: previously only the first matching handler was invoked. All matching handlers are now invoked sequentially.
///
/// The Teams bot application.
/// The handler to register.
/// The updated Teams bot application.
public static TeamsBotApplication OnConversationUpdate(this TeamsBotApplication app, ConversationUpdateHandler handler)
{
ArgumentNullException.ThrowIfNull(app, nameof(app));
app.Router.Register(new Route
{
Name = TeamsActivityTypes.ConversationUpdate,
Selector = _ => true,
Handler = async (ctx, cancellationToken) =>
{
await handler(ctx, cancellationToken).ConfigureAwait(false);
}
});
return app;
}
///
/// Registers a handler for conversation update activities where members were added.
///
///
/// Breaking change: previously only the first matching handler was invoked. All matching handlers are now invoked sequentially.
///
/// The Teams bot application.
/// The handler to register.
/// The updated Teams bot application.
public static TeamsBotApplication OnMembersAdded(this TeamsBotApplication app, ConversationUpdateHandler handler)
{
ArgumentNullException.ThrowIfNull(app, nameof(app));
app.Router.Register(new Route
{
Name = string.Join("/", [TeamsActivityTypes.ConversationUpdate, "membersAdded"]),
Selector = activity => activity.MembersAdded?.Count > 0,
Handler = async (ctx, cancellationToken) =>
{
await handler(ctx, cancellationToken).ConfigureAwait(false);
}
});
return app;
}
///
/// Registers a handler for conversation update activities where members were removed.
///
///
/// Breaking change: previously only the first matching handler was invoked. All matching handlers are now invoked sequentially.
///
/// The Teams bot application.
/// The handler to register.
/// The updated Teams bot application.
public static TeamsBotApplication OnMembersRemoved(this TeamsBotApplication app, ConversationUpdateHandler handler)
{
ArgumentNullException.ThrowIfNull(app, nameof(app));
app.Router.Register(new Route
{
Name = string.Join("/", [TeamsActivityTypes.ConversationUpdate, "membersRemoved"]),
Selector = activity => activity.MembersRemoved?.Count > 0,
Handler = async (ctx, cancellationToken) =>
{
await handler(ctx, cancellationToken).ConfigureAwait(false);
}
});
return app;
}
// Channel Event Handlers
///
/// Registers a handler for channel created events.
///
///
/// Breaking change: previously only the first matching handler was invoked. All matching handlers are now invoked sequentially.
///
/// The Teams bot application.
/// The handler to register.
/// The updated Teams bot application.
public static TeamsBotApplication OnChannelCreated(this TeamsBotApplication app, ConversationUpdateHandler handler)
{
ArgumentNullException.ThrowIfNull(app, nameof(app));
app.Router.Register(new Route
{
Name = string.Join("/", [TeamsActivityTypes.ConversationUpdate, ConversationEventTypes.ChannelCreated]),
Selector = activity => activity.ChannelData?.EventType == ConversationEventTypes.ChannelCreated,
Handler = async (ctx, cancellationToken) =>
{
await handler(ctx, cancellationToken).ConfigureAwait(false);
}
});
return app;
}
///
/// Registers a handler for channel deleted events.
///
///
/// Breaking change: previously only the first matching handler was invoked. All matching handlers are now invoked sequentially.
///
/// The Teams bot application.
/// The handler to register.
/// The updated Teams bot application.
public static TeamsBotApplication OnChannelDeleted(this TeamsBotApplication app, ConversationUpdateHandler handler)
{
ArgumentNullException.ThrowIfNull(app, nameof(app));
app.Router.Register(new Route
{
Name = string.Join("/", [TeamsActivityTypes.ConversationUpdate, ConversationEventTypes.ChannelDeleted]),
Selector = activity => activity.ChannelData?.EventType == ConversationEventTypes.ChannelDeleted,
Handler = async (ctx, cancellationToken) =>
{
await handler(ctx, cancellationToken).ConfigureAwait(false);
}
});
return app;
}
///
/// Registers a handler for channel renamed events.
///
///
/// Breaking change: previously only the first matching handler was invoked. All matching handlers are now invoked sequentially.
///
/// The Teams bot application.
/// The handler to register.
/// The updated Teams bot application.
public static TeamsBotApplication OnChannelRenamed(this TeamsBotApplication app, ConversationUpdateHandler handler)
{
ArgumentNullException.ThrowIfNull(app, nameof(app));
app.Router.Register(new Route
{
Name = string.Join("/", [TeamsActivityTypes.ConversationUpdate, ConversationEventTypes.ChannelRenamed]),
Selector = activity => activity.ChannelData?.EventType == ConversationEventTypes.ChannelRenamed,
Handler = async (ctx, cancellationToken) =>
{
await handler(ctx, cancellationToken).ConfigureAwait(false);
}
});
return app;
}
///
/// Registers a handler for channel shared events.
///
/// The Teams bot application.
/// The handler to register.
/// The updated Teams bot application.
public static TeamsBotApplication OnChannelShared(this TeamsBotApplication app, ConversationUpdateHandler handler)
{
ArgumentNullException.ThrowIfNull(app, nameof(app));
app.Router.Register(new Route
{
Name = string.Join("/", [TeamsActivityTypes.ConversationUpdate, ConversationEventTypes.ChannelShared]),
Selector = activity => activity.ChannelData?.EventType == ConversationEventTypes.ChannelShared,
Handler = async (ctx, cancellationToken) =>
{
await handler(ctx, cancellationToken).ConfigureAwait(false);
}
});
return app;
}
///
/// Registers a handler for channel unshared events.
///
/// The Teams bot application.
/// The handler to register.
/// The updated Teams bot application.
public static TeamsBotApplication OnChannelUnshared(this TeamsBotApplication app, ConversationUpdateHandler handler)
{
ArgumentNullException.ThrowIfNull(app, nameof(app));
app.Router.Register(new Route
{
Name = string.Join("/", [TeamsActivityTypes.ConversationUpdate, ConversationEventTypes.ChannelUnShared]),
Selector = activity => activity.ChannelData?.EventType == ConversationEventTypes.ChannelUnShared,
Handler = async (ctx, cancellationToken) =>
{
await handler(ctx, cancellationToken).ConfigureAwait(false);
}
});
return app;
}
///
/// Registers a handler for channel member added events.
///
/// The Teams bot application.
/// The handler to register.
/// The updated Teams bot application.
public static TeamsBotApplication OnChannelMemberAdded(this TeamsBotApplication app, ConversationUpdateHandler handler)
{
ArgumentNullException.ThrowIfNull(app, nameof(app));
app.Router.Register(new Route
{
Name = string.Join("/", [TeamsActivityTypes.ConversationUpdate, ConversationEventTypes.ChannelMemberAdded]),
Selector = activity => activity.ChannelData?.EventType == ConversationEventTypes.ChannelMemberAdded,
Handler = async (ctx, cancellationToken) =>
{
await handler(ctx, cancellationToken).ConfigureAwait(false);
}
});
return app;
}
///
/// Registers a handler for channel member removed events.
///
/// The Teams bot application.
/// The handler to register.
/// The updated Teams bot application.
public static TeamsBotApplication OnChannelMemberRemoved(this TeamsBotApplication app, ConversationUpdateHandler handler)
{
ArgumentNullException.ThrowIfNull(app, nameof(app));
app.Router.Register(new Route
{
Name = string.Join("/", [TeamsActivityTypes.ConversationUpdate, ConversationEventTypes.ChannelMemberRemoved]),
Selector = activity => activity.ChannelData?.EventType == ConversationEventTypes.ChannelMemberRemoved,
Handler = async (ctx, cancellationToken) =>
{
await handler(ctx, cancellationToken).ConfigureAwait(false);
}
});
return app;
}
/*
///
/// Registers a handler for channel restored events.
///
/// The Teams bot application.
/// The handler to register.
/// The updated Teams bot application.
public static TeamsBotApplication OnChannelRestored(this TeamsBotApplication app, ConversationUpdateHandler handler)
{
ArgumentNullException.ThrowIfNull(app, nameof(app));
app.Router.Register(new Route
{
Name = string.Join("/", [TeamsActivityTypes.ConversationUpdate, ConversationEventTypes.ChannelRestored]),
Selector = activity => activity.ChannelData?.EventType == ConversationEventTypes.ChannelRestored,
Handler = async (ctx, cancellationToken) =>
{
await handler(ctx, cancellationToken).ConfigureAwait(false);
}
});
return app;
}
*/
// Team Event Handlers
///
/// Registers a handler for team member added events.
///
///
/// Breaking change: previously only the first matching handler was invoked. All matching handlers are now invoked sequentially.
///
/// The Teams bot application.
/// The handler to register.
/// The updated Teams bot application.
public static TeamsBotApplication OnTeamMemberAdded(this TeamsBotApplication app, ConversationUpdateHandler handler)
{
ArgumentNullException.ThrowIfNull(app, nameof(app));
app.Router.Register(new Route
{
Name = string.Join("/", [TeamsActivityTypes.ConversationUpdate, ConversationEventTypes.TeamMemberAdded]),
Selector = activity => activity.ChannelData?.EventType == ConversationEventTypes.TeamMemberAdded,
Handler = async (ctx, cancellationToken) =>
{
await handler(ctx, cancellationToken).ConfigureAwait(false);
}
});
return app;
}
///
/// Registers a handler for team member removed events.
///
///
/// Breaking change: previously only the first matching handler was invoked. All matching handlers are now invoked sequentially.
///
/// The Teams bot application.
/// The handler to register.
/// The updated Teams bot application.
public static TeamsBotApplication OnTeamMemberRemoved(this TeamsBotApplication app, ConversationUpdateHandler handler)
{
ArgumentNullException.ThrowIfNull(app, nameof(app));
app.Router.Register(new Route
{
Name = string.Join("/", [TeamsActivityTypes.ConversationUpdate, ConversationEventTypes.TeamMemberRemoved]),
Selector = activity => activity.ChannelData?.EventType == ConversationEventTypes.TeamMemberRemoved,
Handler = async (ctx, cancellationToken) =>
{
await handler(ctx, cancellationToken).ConfigureAwait(false);
}
});
return app;
}
///
/// Registers a handler for team archived events.
///
///
/// Breaking change: previously only the first matching handler was invoked. All matching handlers are now invoked sequentially.
///
/// The Teams bot application.
/// The handler to register.
/// The updated Teams bot application.
public static TeamsBotApplication OnTeamArchived(this TeamsBotApplication app, ConversationUpdateHandler handler)
{
ArgumentNullException.ThrowIfNull(app, nameof(app));
app.Router.Register(new Route
{
Name = string.Join("/", [TeamsActivityTypes.ConversationUpdate, ConversationEventTypes.TeamArchived]),
Selector = activity => activity.ChannelData?.EventType == ConversationEventTypes.TeamArchived,
Handler = async (ctx, cancellationToken) =>
{
await handler(ctx, cancellationToken).ConfigureAwait(false);
}
});
return app;
}
///
/// Registers a handler for team deleted events.
///
///
/// Breaking change: previously only the first matching handler was invoked. All matching handlers are now invoked sequentially.
///
/// The Teams bot application.
/// The handler to register.
/// The updated Teams bot application.
public static TeamsBotApplication OnTeamDeleted(this TeamsBotApplication app, ConversationUpdateHandler handler)
{
ArgumentNullException.ThrowIfNull(app, nameof(app));
app.Router.Register(new Route
{
Name = string.Join("/", [TeamsActivityTypes.ConversationUpdate, ConversationEventTypes.TeamDeleted]),
Selector = activity => activity.ChannelData?.EventType == ConversationEventTypes.TeamDeleted,
Handler = async (ctx, cancellationToken) =>
{
await handler(ctx, cancellationToken).ConfigureAwait(false);
}
});
return app;
}
///
/// Registers a handler for team renamed events.
///
///
/// Breaking change: previously only the first matching handler was invoked. All matching handlers are now invoked sequentially.
///
/// The Teams bot application.
/// The handler to register.
/// The updated Teams bot application.
public static TeamsBotApplication OnTeamRenamed(this TeamsBotApplication app, ConversationUpdateHandler handler)
{
ArgumentNullException.ThrowIfNull(app, nameof(app));
app.Router.Register(new Route
{
Name = string.Join("/", [TeamsActivityTypes.ConversationUpdate, ConversationEventTypes.TeamRenamed]),
Selector = activity => activity.ChannelData?.EventType == ConversationEventTypes.TeamRenamed,
Handler = async (ctx, cancellationToken) =>
{
await handler(ctx, cancellationToken).ConfigureAwait(false);
}
});
return app;
}
///
/// Registers a handler for team unarchived events.
///
///
/// Breaking change: previously only the first matching handler was invoked. All matching handlers are now invoked sequentially.
///
/// The Teams bot application.
/// The handler to register.
/// The updated Teams bot application.
public static TeamsBotApplication OnTeamUnarchived(this TeamsBotApplication app, ConversationUpdateHandler handler)
{
ArgumentNullException.ThrowIfNull(app, nameof(app));
app.Router.Register(new Route
{
Name = string.Join("/", [TeamsActivityTypes.ConversationUpdate, ConversationEventTypes.TeamUnarchived]),
Selector = activity => activity.ChannelData?.EventType == ConversationEventTypes.TeamUnarchived,
Handler = async (ctx, cancellationToken) =>
{
await handler(ctx, cancellationToken).ConfigureAwait(false);
}
});
return app;
}
/*
/// Registers a handler for team restored events.
///
/// The Teams bot application.
/// The handler to register.
/// The updated Teams bot application.
public static TeamsBotApplication OnTeamRestored(this TeamsBotApplication app, ConversationUpdateHandler handler)
{
ArgumentNullException.ThrowIfNull(app, nameof(app));
app.Router.Register(new Route
{
Name = string.Join("/", [TeamsActivityTypes.ConversationUpdate, ConversationEventTypes.TeamRestored]),
Selector = activity => activity.ChannelData?.EventType == ConversationEventTypes.TeamRestored,
Handler = async (ctx, cancellationToken) =>
{
await handler(ctx, cancellationToken).ConfigureAwait(false);
}
});
return app;
}
///
/// Registers a handler for team hard deleted events.
///
/// The Teams bot application.
/// The handler to register.
/// The updated Teams bot application.
public static TeamsBotApplication OnTeamHardDeleted(this TeamsBotApplication app, ConversationUpdateHandler handler)
{
ArgumentNullException.ThrowIfNull(app, nameof(app));
app.Router.Register(new Route
{
Name = string.Join("/", [TeamsActivityTypes.ConversationUpdate, ConversationEventTypes.TeamHardDeleted]),
Selector = activity => activity.ChannelData?.EventType == ConversationEventTypes.TeamHardDeleted,
Handler = async (ctx, cancellationToken) =>
{
await handler(ctx, cancellationToken).ConfigureAwait(false);
}
});
return app;
}
*/
}