Skip to content
This repository has been archived by the owner on Apr 22, 2024. It is now read-only.

Commit

Permalink
[botbuilder] TeamsActivityHandler — Prevent calling event handlers twice
Browse files Browse the repository at this point in the history
Fixes microsoft#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.
  • Loading branch information
alexrecuenco committed Apr 25, 2022
1 parent 08b73c4 commit dcf434d
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 10 deletions.
18 changes: 8 additions & 10 deletions libraries/botbuilder/src/teamsActivityHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1012,18 +1012,16 @@ export class TeamsActivityHandler extends ActivityHandler {
* custom event sub-type events.
*/
protected async dispatchEventActivity(context: TurnContext): Promise<void> {
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);
}

/**
Expand Down
23 changes: 23 additions & 0 deletions libraries/botbuilder/tests/teamsActivityHandler.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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();
});
});
});

0 comments on commit dcf434d

Please sign in to comment.