public async Task <ProcessedChat> ProcessChatMessagesAsync(TeamsDataContext ctx, Chat chat, IEnumerable <Message> messages) { var result = new ProcessedChat(chat); // like 00000000-0000-beef-0000-000000000000 var userId = ctx.Tenant.UserId; // from oldest to newest var orderedMessages = messages.OrderBy(m => m.originalarrivaltime); // TODO: combine this with the conversion logic of processedMessageFactory.CreateProcessedMessage().InitFromMessageAsync -> extract users first to have names ready, then generate processed messages HashSet <TeamsUserWithSource> usersFromChat; usersFromChat = CollectUsersFromChatAndMessages(chat, orderedMessages.ToList()); result.UserIds.AddRange(usersFromChat.Select(value => value.User).Distinct()); // TODO: check if this is still necessary of if we use TeamsUserStore instead await UpdateUserObjectsAsync(ctx, result.UserIds); // note: it is important to process them from oldest to newest to catch all user names floating around in messages (e.g. chat messages contain user display names needed to put names in call end messages) // note2: this does not always work which is why there is the job to resolve unknown user ids result.OrderedMessages = (await Task.WhenAll(orderedMessages.Select(async m => await processedMessageFactory.CreateProcessedMessage().InitFromMessageAsync(ctx, chat.id, m)))).OrderBy(m => m.OriginalArrivalTime); // case 1: there is a custom title var title = chat.title?.Trim() ?? ""; // this handles a title containing user mris (instead of custom title set by the user) var matches = Regex.Matches(title, TeamsParticipant.MriPatternOpen); // case 2: Teams provides a title consisting of user ids - collect them if (matches.Count > 0) { usersFromChat.AddRange(matches.Select(g => new TeamsUserWithSource((TeamsParticipant)g.Value, TeamsUserSource.FoundInChatTitle))); } // remove self and remove any "chat" that participated usersFromChat.RemoveWhere(value => value.User.Equals(ctx.Tenant.UserId) || value.User.Kind == ParticipantKind.TeamsChat); if (usersFromChat.Count == 0) { // no users left? add self... usersFromChat.Add(new TeamsUserWithSource(ctx.Tenant.UserId, TeamsUserSource.Self)); } if (string.IsNullOrWhiteSpace(title)) { title = string.Join(", ", usersFromChat .Where(value => value.UserSource == TeamsUserSource.ChatCreator || value.UserSource == TeamsUserSource.FoundInChatTitle || value.UserSource == TeamsUserSource.OfficialChatMember || value.UserSource == TeamsUserSource.SenderOfMessageInChat || value.UserSource == TeamsUserSource.Self) .Select(value => value.User) .Distinct()); } title = await teamsUserRegistry.ReplaceUserIdsWithDisplayNamesAsync(ctx, title?.Trim()); if (string.IsNullOrEmpty(title)) { title = chat.id; } result.ChatTitle = title; return(result); }
public async Task TestStoreAndRetrieveChat() { using var kernel = new FakeItEasyMockingKernel(); kernel.Rebind <ILogger>().ToConstant(Log.Logger); kernel.Rebind <Configuration>().ToConstant(config); kernel.Rebind <ITeamsChatStore>().To <ImapStore>().InSingletonScope(); var chatStore = kernel.Get <ITeamsChatStore>(); var chatId = $"chatId-{rand.Next()}"; var chat1 = new ProcessedChat(new TeamsInternal.TeamsInternalApi.api.csa.api.v1.teams.users.Chat() { id = chatId, version = 10, threadVersion = 1000 }); await chatStore.StoreMailThreadAndUpdateMetadataAsync(fakeContext, "TestGetAllChatMetadata_1", chat1, null); var metadata = await chatStore.GetChatMetadataAsync(fakeContext, false, chatId); Assert.IsNotNull(metadata); }
public async Task TestStoreAndGetAllChatMetadata() { using var kernel = new FakeItEasyMockingKernel(); kernel.Rebind <ILogger>().ToConstant(Log.Logger); kernel.Rebind <Configuration>().ToConstant(config); kernel.Rebind <ITeamsChatStore>().To <ImapStore>().InSingletonScope(); var chatStore = kernel.Get <ITeamsChatStore>(); var chat1 = new ProcessedChat(new TeamsInternal.TeamsInternalApi.api.csa.api.v1.teams.users.Chat() { id = "chat1", version = 10, threadVersion = 1000 }); await chatStore.StoreMailThreadAndUpdateMetadataAsync(fakeContext, "TestGetAllChatMetadata_1", chat1, null); var chat2 = new ProcessedChat(new TeamsInternal.TeamsInternalApi.api.csa.api.v1.teams.users.Chat() { id = "chat2", version = 20, threadVersion = 2000 }); await chatStore.StoreMailThreadAndUpdateMetadataAsync(fakeContext, "TestGetAllChatMetadata_2", chat2, null); //await chatStore.GetAllChatMetadataRecursivelyAsync(fakeContext); //Assert.IsTrue(sw.ElapsedMilliseconds < 10000, "Needing quite a lot of time to store users"); }
public async Task StoreMailThreadAsyncAndUpdateMetadataAsync(TeamsDataContext ctx, string title, ProcessedChat chat, IOrderedEnumerable <IChatMessage> messages) { await chatStore.StoreMailThreadAndUpdateMetadataAsync(ctx, title, chat, messages); await BlobCache.UserAccount.InsertObject(GetChatMetadataCacheKey(chat.Id), chat, DateTimeOffset.Now + TimeSpan.FromMinutes(10)); }