Skip to content

Commit

Permalink
Filter continueConversation events when logging
Browse files Browse the repository at this point in the history
Fixes #2805
  • Loading branch information
Josh Gummersall committed Oct 15, 2020
1 parent e56fdb7 commit d7d764c
Show file tree
Hide file tree
Showing 5 changed files with 245 additions and 246 deletions.
1 change: 1 addition & 0 deletions libraries/botbuilder-core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"@types/node": "^10.17.27",
"mocha": "^6.2.3",
"nyc": "^15.1.0",
"sinon": "^7.5.0",
"source-map-support": "^0.5.3",
"ts-node": "^4.1.0",
"typescript": "3.5.3",
Expand Down
44 changes: 26 additions & 18 deletions libraries/botbuilder-core/src/transcriptLogger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,13 @@
* Licensed under the MIT License.
*/

import { Activity, ActivityTypes, ConversationReference, ResourceResponse } from 'botframework-schema';
import {
Activity,
ActivityEventNames,
ActivityTypes,
ConversationReference,
ResourceResponse,
} from 'botframework-schema';
import { Middleware } from './middlewareSet';
import { TurnContext } from './turnContext';

Expand Down Expand Up @@ -47,12 +53,12 @@ export class TranscriptLoggerMiddleware implements Middleware {

// hook up onSend pipeline
context.onSendActivities(
async (ctx: TurnContext, activities: Partial<Activity>[], next2: () => Promise<ResourceResponse[]>) => {
async (ctx: TurnContext, activities: Partial<Activity>[], next: () => Promise<ResourceResponse[]>) => {
// Run full pipeline.
const responses: ResourceResponse[] = await next2();
const responses = await next();

activities.map((a: Partial<Activity>, index: number) => {
const clonedActivity = this.cloneActivity(a);
activities.forEach((activity, index) => {
const clonedActivity = this.cloneActivity(activity);
clonedActivity.id = responses && responses[index] ? responses[index].id : clonedActivity.id;

// For certain channels, a ResourceResponse with an id is not always sent to the bot.
Expand All @@ -76,12 +82,12 @@ export class TranscriptLoggerMiddleware implements Middleware {
);

// hook up update activity pipeline
context.onUpdateActivity(async (ctx: TurnContext, activity: Partial<Activity>, next3: () => Promise<void>) => {
context.onUpdateActivity(async (ctx: TurnContext, activity: Partial<Activity>, next: () => Promise<void>) => {
// run full pipeline
const response: void = await next3();
const response: void = await next();

// add Message Update activity
const updateActivity: Activity = this.cloneActivity(activity);
const updateActivity = this.cloneActivity(activity);
updateActivity.type = ActivityTypes.MessageUpdate;
this.logActivity(transcript, updateActivity);

Expand All @@ -90,13 +96,13 @@ export class TranscriptLoggerMiddleware implements Middleware {

// hook up delete activity pipeline
context.onDeleteActivity(
async (ctx: TurnContext, reference: Partial<ConversationReference>, next4: () => Promise<void>) => {
async (ctx: TurnContext, reference: Partial<ConversationReference>, next: () => Promise<void>) => {
// run full pipeline
await next4();
await next();

// add MessageDelete activity
// log as MessageDelete activity
const deleteActivity: Partial<Activity> = TurnContext.applyConversationReference(
const deleteActivity = TurnContext.applyConversationReference(
{
type: ActivityTypes.MessageDelete,
id: reference.activityId,
Expand All @@ -105,29 +111,28 @@ export class TranscriptLoggerMiddleware implements Middleware {
false
);

this.logActivity(transcript, <Activity>deleteActivity);
this.logActivity(transcript, this.cloneActivity(deleteActivity));
}
);

// process bot logic
await next();

// flush transcript at end of turn
while (transcript.length > 0) {
while (transcript.length) {
try {
const activity: Activity = transcript.shift();
// If the implementation of this.logger.logActivity() is asynchronous, we don't
// await it as to not block processing of activities.
// Because TranscriptLogger.logActivity() returns void or Promise<void>, we capture
// the result and see if it is a Promise.
const logActivityResult = this.logger.logActivity(activity);
const maybePromise = this.logger.logActivity(transcript.shift());

// If this.logger.logActivity() returns a Promise, a catch is added in case there
// is no innate error handling in the method. This catch prevents
// UnhandledPromiseRejectionWarnings from being thrown and prints the error to the
// console.
if (logActivityResult instanceof Promise) {
logActivityResult.catch((err) => {
if (maybePromise instanceof Promise) {
maybePromise.catch((err) => {
this.transcriptLoggerErrorHandler(err);
});
}
Expand All @@ -146,7 +151,10 @@ export class TranscriptLoggerMiddleware implements Middleware {
activity.timestamp = new Date();
}

transcript.push(activity);
// We should not log ContinueConversation events used by skills to initialize the middleware.
if (!(activity.type === ActivityTypes.Event && activity.name === ActivityEventNames.ContinueConversation)) {
transcript.push(activity);
}
}

/**
Expand Down
Loading

0 comments on commit d7d764c

Please sign in to comment.