Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Filter continueConversation events when logging #2903

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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[]>) => {
joshgummersall marked this conversation as resolved.
Show resolved Hide resolved
// 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