From ea1495f4ff7906ddb5058479eb13582225ee27b2 Mon Sep 17 00:00:00 2001 From: Eric Dahlvang Date: Wed, 22 Jul 2020 15:51:42 -0700 Subject: [PATCH] Add installation update activity handler --- .../etc/botbuilder-core.api.md | 3 ++ .../botbuilder-core/src/activityHandler.ts | 31 +++++++++++++++++++ .../src/activityHandlerBase.ts | 16 ++++++++++ .../tests/ActivityHandler.test.js | 13 ++++++++ .../tests/activityHandlerBase.test.js | 9 ++++++ 5 files changed, 72 insertions(+) diff --git a/libraries/botbuilder-core/etc/botbuilder-core.api.md b/libraries/botbuilder-core/etc/botbuilder-core.api.md index 68f990428b..bd6c24f96c 100644 --- a/libraries/botbuilder-core/etc/botbuilder-core.api.md +++ b/libraries/botbuilder-core/etc/botbuilder-core.api.md @@ -76,6 +76,8 @@ export class ActivityHandler extends ActivityHandlerBase { protected onTurnActivity(context: TurnContext): Promise; onTyping(handler: BotHandler): this; protected onTypingActivity(context: TurnContext): Promise; + onInstallationUpdate(handler: BotHandler): this; + protected onInstallationUpdateActivity(context: TurnContext): Promise; protected onUnrecognizedActivity(context: TurnContext): Promise; onUnrecognizedActivityType(handler: BotHandler): this; run(context: TurnContext): Promise; @@ -95,6 +97,7 @@ export class ActivityHandlerBase { protected onReactionsRemovedActivity(reactionsRemoved: MessageReaction[], context: TurnContext): Promise; protected onTurnActivity(context: TurnContext): Promise; protected onTypingActivity(context: TurnContext): Promise; + protected onInstallationUpdateActivity(context: TurnContext): Promise; protected onUnrecognizedActivity(context: TurnContext): Promise; run(context: TurnContext): Promise; } diff --git a/libraries/botbuilder-core/src/activityHandler.ts b/libraries/botbuilder-core/src/activityHandler.ts index a88a93b262..3dd9c6efdd 100644 --- a/libraries/botbuilder-core/src/activityHandler.ts +++ b/libraries/botbuilder-core/src/activityHandler.ts @@ -287,6 +287,21 @@ export class ActivityHandler extends ActivityHandlerBase { return this.on('Typing', handler); } + /** + * Registers an activity event handler for the _installationupdate_ activity. + * + * @param handler The event handler. + * + * @remarks + * Returns a reference to the [ActivityHandler](xref:botbuilder-core.ActivityHandler) object. + * + * To handle a InstallationUpdate event, use the + * [onInstallationUpdate](xref:botbuilder-core.ActivityHandler.onInstallationUpdate) type-specific event handler. + */ + public onInstallationUpdate(handler: BotHandler): this { + return this.on('InstallationUpdate', handler); + } + /** * Registers an activity event handler for the _tokens-response_ event, emitted for any incoming * `tokens/response` event activity. These are generated as part of the OAuth authentication flow. @@ -498,6 +513,22 @@ export class ActivityHandler extends ActivityHandlerBase { await this.handle(context, 'Typing', this.defaultNextEvent(context)); } + /** + * Runs all registered _instllationupdate_ handlers and then continues the event emission process. + * + * @param context The context object for the current turn. + * + * @remarks + * Overwrite this method to support channel-specific behavior across multiple channels. + * + * The default logic is to call any handlers registered via + * [onInstallationUpdateActivity](xref:botbuilder-core.ActivityHandler.onInstallationUpdateActivity), + * and then continue by calling [defaultNextEvent](xref:botbuilder-core.ActivityHandler.defaultNextEvent). + */ + protected async onInstallationUpdateActivity(context: TurnContext): Promise { + await this.handle(context, 'InstallationUpdate', this.defaultNextEvent(context)); + } + /** * Runs all registered _unrecognized activity type_ handlers and then continues the event emission process. * diff --git a/libraries/botbuilder-core/src/activityHandlerBase.ts b/libraries/botbuilder-core/src/activityHandlerBase.ts index 10f4a19c5d..fddc4b53a1 100644 --- a/libraries/botbuilder-core/src/activityHandlerBase.ts +++ b/libraries/botbuilder-core/src/activityHandlerBase.ts @@ -79,6 +79,9 @@ export class ActivityHandlerBase { case ActivityTypes.Typing: await this.onTypingActivity(context); break; + case ActivityTypes.InstallationUpdate: + await this.onInstallationUpdateActivity(context); + break; default: // handler for unknown or unhandled types await this.onUnrecognizedActivity(context); @@ -200,6 +203,19 @@ export class ActivityHandlerBase { return; } + /** + * Provides a hook for emitting the _installationupdate_ event. + * + * @param context The context object for the current turn. + * + * @remarks + * Overwrite this method to run registered _installationupdate_ handlers and then continue the event + * emission process. + */ + protected async onInstallationUpdateActivity(context: TurnContext): Promise { + return; + } + /** * Provides a hook for emitting the _unrecognized_ event. * diff --git a/libraries/botbuilder-core/tests/ActivityHandler.test.js b/libraries/botbuilder-core/tests/ActivityHandler.test.js index f94078a0c9..2a5b6dc89e 100644 --- a/libraries/botbuilder-core/tests/ActivityHandler.test.js +++ b/libraries/botbuilder-core/tests/ActivityHandler.test.js @@ -223,6 +223,19 @@ describe('ActivityHandler', function() { processActivity({type: ActivityTypes.Typing}, bot, done); }); + it(`should fire onInstallationUpdate`, async function(done) { + + const bot = new ActivityHandler(); + + bot.onInstallationUpdate(async (context, next) => { + assert(true, 'onInstallationUpdate not called'); + done(); + await next(); + }); + + processActivity({type: ActivityTypes.InstallationUpdate}, bot, done); + }); + it(`should fire onUnrecognizedActivityType`, async function(done) { const bot = new ActivityHandler(); diff --git a/libraries/botbuilder-core/tests/activityHandlerBase.test.js b/libraries/botbuilder-core/tests/activityHandlerBase.test.js index 4f073e8f6a..d3515c735f 100644 --- a/libraries/botbuilder-core/tests/activityHandlerBase.test.js +++ b/libraries/botbuilder-core/tests/activityHandlerBase.test.js @@ -29,6 +29,7 @@ describe('ActivityHandlerBase', function() { let onEventCalled = false; let onEndOfConversationCalled = false; let onTypingCalled = false; + let onInstallationUpdateCalled = false; let onUnrecognizedActivity = false; afterEach(function() { @@ -39,6 +40,7 @@ describe('ActivityHandlerBase', function() { onEventCalled = false; onEndOfConversationCalled = false; onTypingCalled = false; + onInstallationUpdateCalled = false; onUnrecognizedActivity = false; }); @@ -127,6 +129,11 @@ describe('ActivityHandlerBase', function() { onTypingCalled = true; } + async onInstallationUpdateActivity(context) { + assert(context, 'context not found'); + onInstallationUpdateCalled = true; + } + async onUnrecognizedActivity(context) { assert(context, 'context not found'); onUnrecognizedActivity = true; @@ -142,6 +149,7 @@ describe('ActivityHandlerBase', function() { processActivity({type: ActivityTypes.Event}, bot, done); processActivity({type: ActivityTypes.EndOfConversation}, bot, done); processActivity({type: ActivityTypes.Typing}, bot, done); + processActivity({type: ActivityTypes.InstallationUpdate}, bot, done); processActivity({ type: 'unrecognized' }, bot, done); assert(onTurnActivityCalled, 'onTurnActivity was not called'); @@ -151,6 +159,7 @@ describe('ActivityHandlerBase', function() { assert(onEventCalled, 'onEventActivity was not called'); assert(onEndOfConversationCalled, 'onEndOfConversationCalled was not called'); assert(onTypingCalled, 'onTypingCalled was not called'); + assert(onInstallationUpdateCalled, 'onInstallationUpdateCalled was not called'); assert(onUnrecognizedActivity, 'onUnrecognizedActivity was not called'); done(); });