From dcf434d39f562ad697bc4d6a07f16ef9e6db4da4 Mon Sep 17 00:00:00 2001 From: alexrecuenco Date: Mon, 25 Apr 2022 16:42:27 +0700 Subject: [PATCH] =?UTF-8?q?[botbuilder]=20TeamsActivityHandler=20=E2=80=94?= =?UTF-8?q?=20Prevent=20calling=20event=20handlers=20twice?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #4202 Description This change prevents calling TeamsActivityHandler event handlers twice for every event received. Specific Changes Why were the event handlers getting called twice? - teamsActivityHandler overwrites `dispatchEventActivity` - `dispatchEventActivity` is only called from within `onEventActivity` - `onEventActivity` already dispatches *after* calling all handlers - on teamsActivityHandler, when overwriting, it is also calling all handlers How to fix it? - Prevent the handler call inside the dispatchEventHandler - This should have no effect on any consumer, since they should already be consuming only from within a onEventActivity call. Testing A test is added to prevent the behavior from reappearing Note that to test the issue described, it is enough to run the changed test in main. The test will fail when run in main currently, since since it is called twice. --- .../botbuilder/src/teamsActivityHandler.ts | 18 +++++++-------- .../tests/teamsActivityHandler.test.js | 23 +++++++++++++++++++ 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/libraries/botbuilder/src/teamsActivityHandler.ts b/libraries/botbuilder/src/teamsActivityHandler.ts index 6b5b3e00ce..06fb4cc966 100644 --- a/libraries/botbuilder/src/teamsActivityHandler.ts +++ b/libraries/botbuilder/src/teamsActivityHandler.ts @@ -1012,18 +1012,16 @@ export class TeamsActivityHandler extends ActivityHandler { * custom event sub-type events. */ protected async dispatchEventActivity(context: TurnContext): Promise { - await this.handle(context, 'Event', async () => { - if (context.activity.channelId === Channels.Msteams) { - switch (context.activity.name) { - case 'application/vnd.microsoft.meetingStart': - return this.onTeamsMeetingStart(context); - case 'application/vnd.microsoft.meetingEnd': - return this.onTeamsMeetingEnd(context); - } + if (context.activity.channelId === Channels.Msteams) { + switch (context.activity.name) { + case 'application/vnd.microsoft.meetingStart': + return this.onTeamsMeetingStart(context); + case 'application/vnd.microsoft.meetingEnd': + return this.onTeamsMeetingEnd(context); } + } - return super.dispatchEventActivity(context); - }); + return super.dispatchEventActivity(context); } /** diff --git a/libraries/botbuilder/tests/teamsActivityHandler.test.js b/libraries/botbuilder/tests/teamsActivityHandler.test.js index 6db8e2260f..5ef05a0fff 100644 --- a/libraries/botbuilder/tests/teamsActivityHandler.test.js +++ b/libraries/botbuilder/tests/teamsActivityHandler.test.js @@ -2307,5 +2307,28 @@ describe('TeamsActivityHandler', function () { }) .startTest(); }); + + it('should not call middleware handler twice', async function () { + const bot = new TeamsActivityHandler(); + + const activity = createMeetingEventActivity(false); + let ncalls = 0; + + bot.onEvent(async (context, next) => { + ncalls++; + await next(); + }); + + const adapter = new TestAdapter(async (context) => { + await bot.run(context); + }); + + await adapter + .send(activity) + .then(() => { + assert(ncalls === 1, 'On Event should only be called once, times called: ' + ncalls.toString()); + }) + .startTest(); + }); }); });