// Handle message activity in 1:1 chat
        private async Task OnMessageActivityInPersonalChatAsync(IMessageActivity message, ITurnContext <IMessageActivity> turnContext, CancellationToken cancellationToken)
        {
            if (!string.IsNullOrEmpty(message.ReplyToId) && (message.Value != null) && ((JObject)message.Value).HasValues)
            {
                this.telemetryClient.TrackTrace("Card submit in 1:1 chat");
                await this.OnAdaptiveCardSubmitInPersonalChatAsync(message, turnContext, cancellationToken);

                return;
            }

            string text = (message.Text ?? string.Empty).Trim().ToLower();

            switch (text)
            {
            case AskAnExpert:
                this.telemetryClient.TrackTrace("Sending user ask an expert card");
                await turnContext.SendActivityAsync(MessageFactory.Attachment(AskAnExpertCard.GetCard()));

                break;

            case ShareFeedback:
                this.telemetryClient.TrackTrace("Sending user feedback card");
                await turnContext.SendActivityAsync(MessageFactory.Attachment(ShareFeedbackCard.GetCard()));

                break;

            case TakeATour:
                this.telemetryClient.TrackTrace("Sending user tour card");
                var userTourCards = TourCarousel.GetUserTourCards(this.appBaseUri);
                await turnContext.SendActivityAsync(MessageFactory.Carousel(userTourCards));

                break;

            default:
                this.telemetryClient.TrackTrace("Sending input to QnAMaker");
                var queryResult = await this.GetAnswerFromQnAMakerAsync(text, turnContext, cancellationToken);

                if (queryResult != null)
                {
                    string answer = this.ReplaceWildCard(message, turnContext, queryResult.Answer);
                    await turnContext.SendActivityAsync(MessageFactory.Attachment(ResponseCard.GetCard(queryResult.Questions[0], answer, queryResult.Source, text)));
                }
                else
                {
                    await turnContext.SendActivityAsync(MessageFactory.Attachment(UnrecognizedInputCard.GetCard(text)));
                }

                // Save conversation
                var saveConversations = await this.configurationProvider.GetSavedEntityDetailAsync(ConfigurationEntityTypes.SaveConversations);

                if (bool.Parse(saveConversations))
                {
                    var userDetails = await this.GetUserDetailsInPersonalChatAsync(turnContext, cancellationToken);

                    ConversationEntity newConversation = await this.CreateConversationAsync(message, queryResult, userDetails);
                }

                break;
            }
        }
Esempio n. 2
0
        private Conversation MapToConversation(ConversationEntity entity)
        {
            var conversation = Mapper.Map <Conversation>(entity);

            conversation.UsersIds = entity.Users.Select(u => u.Id).ToList();
            return(conversation);
        }
        /// <summary>
        /// Store or update Conversation entity in table storage.
        /// </summary>
        /// <param name="entity">Represents Conversation entity used for storage and retrieval.</param>
        /// <returns><see cref="Task"/> that represents configuration entity is saved or updated.</returns>
        private async Task <TableResult> StoreOrUpdatConversationEntityAsync(ConversationEntity entity)
        {
            await this.EnsureInitializedAsync().ConfigureAwait(false);

            TableOperation addOrUpdateOperation = TableOperation.InsertOrReplace(entity);

            return(await this.conversationCloudTable.ExecuteAsync(addOrUpdateOperation).ConfigureAwait(false));
        }
Esempio n. 4
0
        /// <summary>
        /// Add the conversation entity object in table storage.
        /// </summary>
        /// <param name="conversationEntity">Conversation table entity.</param>
        /// <returns>A <see cref="Task"/> of type bool where true represents conversation entity object is added in table storage successfully while false indicates failure in saving data.</returns>
        public async Task <bool> AddConversationEntityAsync(ConversationEntity conversationEntity)
        {
            await this.EnsureInitializedAsync();

            TableOperation insertOrMergeOperation = TableOperation.InsertOrReplace(conversationEntity);
            TableResult    result = await this.ResponsesCloudTable.ExecuteAsync(insertOrMergeOperation);

            return(result.HttpStatusCode == (int)HttpStatusCode.NoContent);
        }
Esempio n. 5
0
 public static ConversationDto ToDto(this ConversationEntity entity)
 {
     return(new ConversationDto
     {
         Id = entity.Id,
         Title = entity.Title,
         LastMessage = entity.Messages?.LastOrDefault().Text
     });
 }
Esempio n. 6
0
        /// <summary>
        /// Store or update conversation entity in table storage
        /// </summary>
        /// <param name="conversation">conversationEntity.</param>
        /// <returns><see cref="Task"/> that represents configuration entity is saved or updated.</returns>
        public Task SaveOrUpdateConversationAsync(ConversationEntity conversation)
        {
            conversation.PartitionKey = PartitionKey;
            conversation.RowKey       = conversation.ConversationId;

            // if (conversation.Status > (int)ConversationState.MaxValue)
            // {
            //     throw new ConversationValidationException($"The conversation status ({conversation.Status}) is not valid.");
            // }

            return(this.StoreOrUpdateConversationEntityAsync(conversation));
        }
Esempio n. 7
0
        private ConversationModel EntityToModel(ConversationEntity entity)
        {
            var model = new ConversationModel
            {
                ConversationId = entity.ConversationId,
                Conversation   = entity.ConversationText
            };

            if (entity.LeadToStoryId != null)
            {
                model.StoryLeadId = entity.LeadToStoryId;
            }

            return(model);
        }
Esempio n. 8
0
        public static ConversationEntity MapConversation(Conversation conversation, string ignoreName)
        {
            var conversationEntity = new ConversationEntity();

            conversation.Participants.RemoveAll(x => x.Name == ignoreName);

            if (conversation.Participants.Count == 0)
            {
                return(null);
            }

            conversationEntity.ParticipantId = conversation.Participants[0].Name;
            conversationEntity.Id            = HashGenerator.Generate($"{conversation.Title} chat");

            return(conversationEntity);
        }
Esempio n. 9
0
        public async Task SaveConversation(Conversation conversation)
        {
            ConversationEntity entity = _dbContext
                                        .ConversationEntities
                                        .Include(c => c.Messages)
                                        .Include(c => c.ConversationOptions)
                                        .FirstOrDefault(e => e.Id == conversation.Id);

            if (entity != null)
            {
                var toAdd = conversation.Messages.Select(m => m.Id).Except(entity.Messages.Select(m => m.Id));
                foreach (var messageId in toAdd.ToList())
                {
                    var message = Mapper.Map <MessageEntity>(conversation.Messages
                                                             .Single(m => m.Id == messageId));

                    entity.Messages.Add(message);
                }

                var optionIds = entity.ConversationOptions.Select(ec => ec.Id).ToList();
                foreach (var option in entity.ConversationOptions)
                {
                    Mapper.Map <ConversationOption, ConversationOptionEntity>(
                        conversation.ConversationOptions.Single(c => c.Id == option.Id), option);
                }
            }
            else
            {
                entity = Mapper.Map <ConversationEntity>(conversation);
                _dbContext.ConversationEntities.Add(entity);
                await _dbContext.SaveChangesAsync();

                entity = _dbContext.ConversationEntities
                         .Include(c => c.Users)
                         .Include(c => c.ConversationOptions)
                         .FirstOrDefault(e => e.Id == conversation.Id);
                conversation
                .UsersIds
                .ForEach(userId => entity.Users.Add(_dbContext.UserEntities.Find(userId)));
                conversation
                .ConversationOptions
                .ForEach(option => entity.ConversationOptions.Add(Mapper.Map <ConversationOptionEntity>(option)));
            }

            await _dbContext.SaveChangesAsync();
        }
        public ConversationEntity CreateAsync(int senderId, int receiverId, string text)
        {
            var sender = context.Users.FirstOrDefault(x => x.Id == senderId);

            if (sender == null)
            {
                throw new InvalidOperationException("Invalid sender id");
            }

            var receiver = context.Users.FirstOrDefault(x => x.Id == receiverId);

            if (sender == null)
            {
                throw new InvalidOperationException("Invalid receiver id");
            }

            var conversation = new ConversationEntity
            {
                CreatedById       = senderId,
                Title             = receiver.NormalizedUserName,
                CreatedAt         = DateTime.Now,
                ConversationUsers = new List <ConversationUserEntity> {
                    new ConversationUserEntity
                    {
                        UserId = senderId
                    },
                    new ConversationUserEntity
                    {
                        UserId = receiverId
                    },
                },
                Messages = new List <MessageEntity> {
                    new MessageEntity {
                        SenderId = senderId,
                        Text     = text
                    }
                }
            };

            context.Conversations.Add(conversation);
            context.SaveChanges();

            return(conversation);
        }
        // Create a new conversation from the input
        private async Task <ConversationEntity> CreateConversationAsync(IMessageActivity message, QueryResult data, TeamsChannelAccount member)
        {
            ConversationEntity conversationEntity = new ConversationEntity
            {
                ConversationId             = Guid.NewGuid().ToString(),
                RequesterName              = member.Name,
                RequesterUserPrincipalName = member.UserPrincipalName,
                RequesterGivenName         = member.GivenName,
                RequesterConversationId    = message.Conversation.Id,
                UserQuestion              = message.Text,
                KnowledgeBaseAnswer       = data == null ? string.Empty : data.Answer,
                KnowledgeBaseQuestion     = data == null ? string.Empty : data.Questions.Length == 0 ? string.Empty : data.Questions[0],
                KnowledgeBaseScore        = data == null ? 0 : data.Score,
                KnowledgeBaseAnswerSource = data == null ? string.Empty : data.Source
            };

            await this.conversationsProvider.SaveOrUpdateConversationAsync(conversationEntity);

            return(conversationEntity);
        }
Esempio n. 12
0
        public async Task None(IDialogContext context, IAwaitable <IMessageActivity> activity, LuisResult result)
        {
            LanguageManager lang = await LanguageManager.GetLanguage(context, activity);

            string message = "";
            string image   = "";

            if (result.Entities.Any(e => e.Type == "Genexus"))
            {
                message = lang.Genexus;
            }
            else
            {
                ConversationObject convObj = await Watson.Conversation.SendMessage(result.Query);

                if (convObj != null && convObj.entities.Length > 0)
                {
                    ConversationEntity        convEnt = convObj.entities[0];
                    WatsonEntityHelper.Entity ent     = WatsonEntityHelper.GetEntity(convEnt.entity);
                    Break b;
                    switch (ent)
                    {
                    case WatsonEntityHelper.Entity.Radisson:
                        message = lang.Map;
                        image   = ImageHelper.GetLocationImage();
                        break;

                    case WatsonEntityHelper.Entity.CoatCheck:
                        message = lang.CoatCheck;
                        image   = ImageHelper.GetCoatCheck();
                        break;

                    case WatsonEntityHelper.Entity.FrontDesk:
                        message = lang.FrontDesk;
                        break;

                    case WatsonEntityHelper.Entity.Room:
                        int floor;
                        image   = ImageHelper.GetRoomImage(convEnt.value, out floor);
                        message = string.Format(lang.RoomMap, convEnt.value, floor);
                        break;

                    case WatsonEntityHelper.Entity.Break:
                        b = NextBreak.Find();
                        if (b != null)
                        {
                            message = string.Format(lang.Break, b.Sessionstarttimetext, convEnt.value);
                        }
                        else
                        {
                            message = lang.NoMoreBreaks;
                        }
                        break;

                    case WatsonEntityHelper.Entity.Snack:
                        b = NextBreak.Find();
                        if (b != null)
                        {
                            message = string.Format(lang.Snack, b.Sessionstarttimetext, convEnt.value);
                        }
                        else
                        {
                            message = lang.NoMoreBreaks;
                        }
                        break;

                    case WatsonEntityHelper.Entity.TimeQ:
                        break;

                    default:
                        break;
                    }
                }
            }

            if (string.IsNullOrEmpty(message) && result.Query.Length > 2)
            {
                SearchServiceSoapClient client = new SearchServiceSoapClient();
                List <SourceParam>      parm   = new List <SourceParam>();
                parm.Add(new SourceParam()
                {
                    sourceName = BotConfiguration.GXSEARCH_KEY
                });
                Search2Response response = await client.Search2Async($"{result.Query} webidioid:{lang.SearchCode}", parm.ToArray(), "SearchHighlight", 1, 10);

                if (response.Body.Search2Result.DocumentsCount > 0)
                {
                    await SendMessage(context, string.Format(lang.SearchFound, response.Body.Search2Result.DocumentsCount, result.Query), result.Query, NONE);

                    foreach (var doc in response.Body.Search2Result.Documents)
                    {
                        StringBuilder msg = new StringBuilder($"- {doc.Description.Sanitize()}");
                        foreach (var p in doc.Properties)
                        {
                            if (p.Key == "charlaexp")
                            {
                                msg.Append($" ({p.Value.Sanitize()})");
                            }
                        }

                        await SendMessage(context, msg.ToString());
                    }
                    context.Wait(MessageReceived);
                    return;
                }
            }

            if (string.IsNullOrEmpty(message))
            {
                int fails = 1;
                if (context.UserData.TryGetValue <int>(CONSECUTIVES_FAILS, out fails))
                {
                    fails++;
                    if (fails > 6)
                    {
                        message = lang.MyBad6;
                    }
                    else if (fails > 4)
                    {
                        message = lang.MyBad4;
                    }
                    else if (fails > 2)
                    {
                        message = lang.MyBad2;
                    }
                    else
                    {
                        message = lang.MyBad1;
                    }
                }
                else
                {
                    message = lang.MyBad1;
                }

                context.UserData.SetValue <int>(CONSECUTIVES_FAILS, fails);
            }
            else
            {
                OnSuccess(context);
            }


            await SendMessage(context, message, image, result.Query, NONE);

            context.Wait(MessageReceived);
        }
Esempio n. 13
0
        public async Task Location(IDialogContext context, IAwaitable <IMessageActivity> activity, LuisResult result)
        {
            if (IsScoreTooLow(context, result))
            {
                await None(context, activity, result);

                return;
            }
            else
            {
                OnSuccess(context);
            }

            LanguageManager lang = await LanguageManager.GetLanguage(context, activity);

            ConversationObject convObj = await Watson.Conversation.SendMessage(result.Query);

            if (convObj != null && convObj.entities.Length > 0)
            {
                ConversationEntity        entity = convObj.entities[0];
                WatsonEntityHelper.Entity ent    = WatsonEntityHelper.GetEntity(entity.entity);
                string message = "";                // $"{entity.entity}:{entity.value}";
                string image   = null;
                Break  b;
                switch (ent)
                {
                case WatsonEntityHelper.Entity.CDS:
                    break;

                case WatsonEntityHelper.Entity.Radisson:
                    message = lang.Map;
                    image   = ImageHelper.GetLocationImage();
                    break;

                case WatsonEntityHelper.Entity.CoatCheck:
                    message = lang.CoatCheck;
                    image   = ImageHelper.GetCoatCheck();
                    break;

                case WatsonEntityHelper.Entity.FrontDesk:
                    message = lang.FrontDesk;
                    break;

                case WatsonEntityHelper.Entity.Room:
                    int floor;
                    image   = ImageHelper.GetRoomImage(entity.value, out floor);
                    message = string.Format(lang.RoomMap, entity.value, floor);
                    break;

                case WatsonEntityHelper.Entity.Break:
                    b = NextBreak.Find();
                    if (b != null)
                    {
                        message = string.Format(lang.Break, b.Sessionstarttimetext);
                    }
                    else
                    {
                        message = lang.NoMoreBreaks;
                    }
                    break;

                case WatsonEntityHelper.Entity.Snack:
                    b = NextBreak.Find();
                    if (b != null)
                    {
                        message = string.Format(lang.Snack, b.Sessionstarttimetext, entity.value);
                    }
                    else
                    {
                        message = lang.NoMoreBreaks;
                    }
                    break;

                case WatsonEntityHelper.Entity.Restroom:
                    var floors = new[] { 2, 3, 4 };
                    PromptDialog.Choice(context, RestroomFloorComplete, floors, string.Format(lang.WhatFloor, floors), string.Format(lang.InvalidFloor, floors), 3, PromptStyle.Auto);
                    return;

                default:
                    break;
                }

                await SendMessage(context, message, image, result.Query, LOCATION);
            }
            else
            {
                await SendMessage(context, lang.NoLocation, result.Query, LOCATION);
            }

            context.Wait(MessageReceived);
        }
 /// <summary>
 /// Store or update Conversation entity in table storage.
 /// </summary>
 /// <param name="conversation">Represents Conversation entity used for storage and retrieval.</param>
 /// <returns>that represents Conversation entity is saved or updated.</returns>
 public Task UpsertConversationAsync(ConversationEntity conversation)
 {
     conversation.PartitionKey = PartitionKey;
     conversation.RowKey       = conversation.ConversationID;
     return(this.StoreOrUpdatConversationEntityAsync(conversation));
 }
        /// <summary>
        /// Invoked when Bot/Messaging Extension is installed in team to send welcome card.
        /// </summary>
        /// <param name="membersAdded">A list of all the members added to the conversation, as described by the conversation update activity.</param>
        /// <param name="turnContext">Provides context for a turn of a bot.</param>
        /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
        /// <returns>A task that represents welcome card when bot is added first time by user.</returns>
        /// <remarks>
        /// Reference link: https://docs.microsoft.com/en-us/dotnet/api/microsoft.bot.builder.activityhandler.onmembersaddedasync?view=botbuilder-dotnet-stable.
        /// </remarks>
        protected override async Task OnMembersAddedAsync(IList <ChannelAccount> membersAdded, ITurnContext <IConversationUpdateActivity> turnContext, CancellationToken cancellationToken)
        {
            try
            {
                turnContext = turnContext ?? throw new ArgumentNullException(nameof(turnContext));
                this.RecordEvent(nameof(this.OnMembersAddedAsync), turnContext);

                var activity = turnContext.Activity;
                this.logger.LogInformation($"conversationType: {activity.Conversation.ConversationType}, membersAdded: {activity.MembersAdded?.Count}, membersRemoved: {activity.MembersRemoved?.Count}");

                if (activity.Conversation.ConversationType.Equals(Personal, StringComparison.OrdinalIgnoreCase))
                {
                    if (activity.MembersAdded.FirstOrDefault(member => member.Id != activity.Recipient.Id) != null)
                    {
                        this.logger.LogInformation($"Bot added {activity.Conversation.Id}");
                        var userStateAccessors    = this.userState.CreateProperty <UserConversationState>(nameof(UserConversationState));
                        var userConversationState = await userStateAccessors.GetAsync(turnContext, () => new UserConversationState());

                        if (userConversationState?.IsWelcomeCardSent == null || userConversationState?.IsWelcomeCardSent == false)
                        {
                            userConversationState.IsWelcomeCardSent = true;
                            await userStateAccessors.SetAsync(turnContext, userConversationState);

                            var userWelcomeCardAttachment = WelcomeCard.GetWelcomeCardAttachmentForPersonal(this.options.Value.AppBaseUri, localizer: this.localizer);
                            await turnContext.SendActivityAsync(MessageFactory.Attachment(userWelcomeCardAttachment));

                            // Store user conversation id in table storage for future use.
                            ConversationEntity conversationEntity = new ConversationEntity {
                                ConversationId = activity.Conversation.Id, UserId = activity.From.AadObjectId
                            };
                            bool operationStatus = await this.conversationStorageProvider.AddConversationEntityAsync(conversationEntity);

                            if (!operationStatus)
                            {
                                this.logger.LogInformation($"Unable to add conversation data in table storage.");
                            }
                        }
                    }
                    else
                    {
                        this.logger.LogError("User data could not be found at OnMembersAddedAsync().");
                    }
                }
                else
                {
                    if (activity.MembersAdded.FirstOrDefault(member => member.Id == activity.Recipient.Id) != null)
                    {
                        this.logger.LogInformation($"Bot added {activity.Conversation.Id}");
                        var userWelcomeCardAttachment = WelcomeCard.GetWelcomeCardAttachmentForTeams(this.options.Value.AppBaseUri, localizer: this.localizer);
                        await turnContext.SendActivityAsync(MessageFactory.Attachment(userWelcomeCardAttachment));
                    }
                    else
                    {
                        this.logger.LogError("User data could not be found at OnMembersAddedAsync().");
                    }
                }
            }
            catch (Exception ex)
            {
                this.logger.LogError("Exception occurred while sending the welcome card", ex);
                throw;
            }
        }