Search code examples
botframework

Log additional information with TranscriptLoggerMiddleware


I'm using TranscriptLoggerMiddleware to log transcript to Azure blobs. Now, I want to add additional information to the activity, for example, account ID.

Ideally I want the account ID to be the top level folder when creating the blobs so one can easily locate all conversations for a given account.

The logger is only passed the activity without any context. So I'm looking at the Entities activity property which I can potentially use for storing my account ID.

Is this a valid approach? Any other ideas on how to implement this?


Solution

  • Answering my own question. This worked for me:

    public class SetEntityMiddleware : IMiddleware
    {
        private readonly BotState _userState;
        private readonly IStatePropertyAccessor<UserProfileState> _userProfileState;
    
        public SetEntityMiddleware(UserState userState)
        {
            _userState = userState;
            _userProfileState = userState.CreateProperty<UserProfileState>(nameof(UserProfileState));
        }
    
        public async Task OnTurnAsync(ITurnContext turnContext, NextDelegate next, CancellationToken cancellationToken = default)
        {
            var userProfile = await _userProfileState.GetAsync(turnContext, () => new UserProfileState(), cancellationToken);
            this.SetEntity(turnContext.Activity, userProfile);
    
            turnContext.OnSendActivities(async (ctx, activities, nextSend) =>
            {
                var userProfile = await _userProfileState.GetAsync(ctx, () => new UserProfileState(), cancellationToken);
    
                foreach (var activity in activities)
                {
                    this.SetEntity(activity, userProfile);
                }
    
                return await nextSend().ConfigureAwait(false);
            });
    
            await next(cancellationToken).ConfigureAwait(false);
        }
    
        private void SetEntity(Activity activity, UserProfileState userProfile)
        {
            if (activity.Type == ActivityTypes.Message &&
                !string.IsNullOrEmpty(userProfile.AccountNumber))
            {
                var entity = new Entity();
                entity.Type = "userProfile";
                entity.Properties["accountNumber"] = userProfile.AccountNumber;
    
                if (activity.Entities == null)
                {
                    activity.Entities = new List<Entity>();
                }
    
                activity.Entities.Add(entity);
            }
        }
    }