Exemplo n.º 1
0
        private async Task HandleNoQuestion(IDialogContext context, Microsoft.Bot.Connector.Activity activity, QuestionModel questionModel, string channelId)
        {
            var messageId = questionModel.MessageId;
            // We stripped the @mention and html tags. If nothing remains then this means the user forgot to tag the bot in the original question and tagged it in a reply, so we need to handle it
            // Get the ID of the parent message (which should be the root)
            var thisTeamsMessage = await GetMessage(questionModel.GroupId, channelId, messageId);

            // check for null below
            if (thisTeamsMessage == null)
            {
                // Get root message
                var rootTeamsMessage = await GetRootMessage(questionModel.GroupId, channelId, messageId, questionModel.ConversationId);

                var question = MicrosoftTeamsChannelHelper.StripHtmlTags(rootTeamsMessage.Body.Content);
                messageId = rootTeamsMessage.Id;
                var conversationId = channelId + @";messageid=" + messageId;

                questionModel.QuestionText   = question;
                questionModel.MessageId      = messageId;
                questionModel.ConversationId = conversationId;

                // Get original poster
                var connector = new ConnectorClient(new Uri(activity.ServiceUrl));
                IList <ChannelAccount> members = await connector.Conversations.GetConversationMembersAsync(questionModel.TeamId);

                var teamsMembers = members.AsTeamsChannelAccounts();
                var originalPosterAsTeamsChannelAccount = teamsMembers.Where(x => x.ObjectId == rootTeamsMessage.From.User.Id).FirstOrDefault();
                var userUpn = originalPosterAsTeamsChannelAccount.UserPrincipalName;
                var user    = SQLService.GetUser(userUpn);

                // Handle if the bot gets tagged again in the same set of replies
                if (SQLService.DoesConversationIdExist(conversationId))
                {
                    // WE DO NOTHING!
                }
                else
                {
                    // get courseID
                    var courseID = SQLService.GetCourseIDByName(questionModel.TeamName.Trim());
                    var course   = SQLService.GetCourse(courseID);
                    questionModel.CourseID = courseID;
                    await HandleQuestionWorkflow(context, activity, course, questionModel);
                }
            }
            else
            {
                // Empty was the root, which means the user simply forgot to ask a question.
                await context.PostAsync($"If you have a question, please include it as part of your message.");
            }
        }
Exemplo n.º 2
0
        private async Task HandleChannelConversation(IDialogContext context, Microsoft.Bot.Connector.Activity activity)
        {
            var connector = new ConnectorClient(new Uri(activity.ServiceUrl));

            // Channel conversation

            // Get the question text, and team and channel details
            var    question       = activity.Text;
            var    messageId      = activity.Id;
            var    conversationId = activity.Conversation.Id;
            var    channelData    = activity.GetChannelData <TeamsChannelData>();
            string tenantId       = channelData.Tenant.Id;
            string teamId         = channelData.Team.Id;
            string channelId      = channelData.Channel.Id;

            TeamDetails teamDetails = connector.GetTeamsConnectorClient().Teams.FetchTeamDetails(teamId);
            var         teamName    = teamDetails.Name;
            var         groupId     = teamDetails.AadGroupId;

            ConversationList channelList = connector.GetTeamsConnectorClient().Teams.FetchChannelList(teamId);
            var channel     = channelList.Conversations.Where(x => x.Id == channelId).FirstOrDefault();
            var channelName = channel?.Name;
            var topic       = channelName ?? "General";

            IList <ChannelAccount> members = await connector.Conversations.GetConversationMembersAsync(teamId);

            var teamsMembers = members.AsTeamsChannelAccounts();

            // Get original poster
            var originalPosterAsTeamsChannelAccount = teamsMembers.Where(x => x.ObjectId == activity.From.Properties["aadObjectId"].ToString()).FirstOrDefault();
            var userUpn = originalPosterAsTeamsChannelAccount.UserPrincipalName;
            var user    = SQLService.GetUser(userUpn);

            // strip @bot mention for teams
            if (activity.ChannelId == "msteams")
            {
                activity = MicrosoftTeamsChannelHelper.StripAtMentionText(activity);
            }
            else
            {
                activity.Text = activity.Text.Trim();
            }

            // strip the html tags
            question = MicrosoftTeamsChannelHelper.StripHtmlTags(activity.Text);

            var questionModel = new QuestionModel()
            {
                ID                = 0,
                TenantId          = tenantId,
                GroupId           = groupId,
                TeamId            = teamId,
                TeamName          = teamName,
                ConversationId    = conversationId,
                MessageId         = messageId,
                Topic             = topic,
                QuestionText      = question,
                QuestionSubmitted = DateTime.Now,
                OriginalPoster    = user,
                Link              = CreateLink(conversationId, tenantId, groupId, messageId, teamName, topic),
            };

            if (string.IsNullOrEmpty(question))
            {
                await HandleNoQuestion(context, activity, questionModel, channelId);
            }
            else
            {
                // get courseID
                var courseID = SQLService.GetCourseIDByName(teamName.Trim());
                var course   = SQLService.GetCourse(courseID);
                questionModel.CourseID = courseID;
                await HandleQuestionWorkflow(context, activity, course, questionModel);
            }
        }
Exemplo n.º 3
0
        private async Task <List <TeamsMessage> > GetAllReplies(string teamsId, string channelId, string messageId)
        {
            var authority = ServiceHelper.Authority;
            var resource  = ServiceHelper.GraphResource;

            var authService = new AuthService(authority);
            var authResult  = await authService.AuthenticateSilently(resource);

            var graphService  = new GraphService();
            var teamsMessages = await graphService.GetRepliesToMessage(authResult.AccessToken, teamsId, channelId, messageId);

            return(teamsMessages.Where(x => x.From.Application == null && !string.IsNullOrEmpty(MicrosoftTeamsChannelHelper.StripMentionAndHtml(x.Body.Content))).ToList());
        }
Exemplo n.º 4
0
        private async Task <HttpResponseMessage> HandleSelectAnswerFromMessageAction(Microsoft.Bot.Connector.Activity activity)
        {
            ConnectorClient connector = new ConnectorClient(new Uri(activity.ServiceUrl));

            TeamsMessage selectedReply = JsonConvert.DeserializeObject <TeamsMessage>(JsonConvert.SerializeObject((activity.Value as dynamic)["messagePayload"]));

            if (selectedReply.From.User == null)
            {
                return(Request.CreateResponse(HttpStatusCode.OK));
            }

            var question = SQLService.GetQuestionByMessageId(selectedReply.ReplyToId);

            if (question == null)
            {
                return(Request.CreateResponse(HttpStatusCode.OK));
            }

            // get user details
            var channelData = activity.GetChannelData <Microsoft.Bot.Connector.Teams.Models.TeamsChannelData>();
            var members     = await connector.Conversations.GetConversationMembersAsync(channelData.Team.Id);

            var teamsMembers = members.AsTeamsChannelAccounts();
            var currentUser  = teamsMembers.Where(x => x.ObjectId == activity.From.Properties["aadObjectId"].ToString()).FirstOrDefault();
            var studentUPN   = currentUser.UserPrincipalName;
            var isUserAdmin  = SQLService.IsUserAdmin(studentUPN);

            // check if user can set question status
            if (isUserAdmin || (studentUPN == question.OriginalPoster.Email) || (studentUPN == question.OriginalPoster.UserName))
            {
                var selectedReplyUser = teamsMembers.Where(x => x.ObjectId == selectedReply.From.User.Id).FirstOrDefault();
                var answeredBy        = SQLService.GetUser(selectedReplyUser.UserPrincipalName);

                // update question model
                question.QuestionStatus   = Constants.QUESTION_STATUS_ANSWERED;
                question.QuestionAnswered = DateTime.Now;
                question.AnswerText       = MicrosoftTeamsChannelHelper.StripMentionAndHtml(selectedReply.Body.Content);
                question.AnswerPoster     = answeredBy;

                SQLService.CreateOrUpdateQuestion(question);

                Microsoft.Bot.Connector.Activity updatedReply = activity.CreateReply();

                var card        = new AdaptiveCard();
                var answerBlock = new AdaptiveTextBlock("Answer: " + question.AnswerText.ReplaceLinksWithMarkdown());
                answerBlock.Weight = AdaptiveTextWeight.Bolder;
                answerBlock.Size   = AdaptiveTextSize.Medium;
                answerBlock.Wrap   = true;

                var markedBlock = new AdaptiveTextBlock($"Marked as " + question.QuestionStatus + " by " + currentUser.Name);
                markedBlock.Wrap = true;

                var answeredBlock = new AdaptiveTextBlock("Answered by: " + question.AnswerPoster.FullName);
                answeredBlock.Weight = AdaptiveTextWeight.Bolder;
                answeredBlock.Wrap   = true;

                card.Body.Add(answerBlock);
                card.Body.Add(answeredBlock);
                card.Body.Add(markedBlock);

                Attachment attachment = new Attachment()
                {
                    ContentType = AdaptiveCard.ContentType,
                    Content     = card,
                };

                updatedReply.Attachments.Add(attachment);

                if (question.AnswerCardActivityId == null)
                {
                    var r = await connector.Conversations.ReplyToActivityAsync(updatedReply.Conversation.Id, updatedReply.ReplyToId, updatedReply);

                    question.AnswerCardActivityId = r.Id;
                    SQLService.CreateOrUpdateQuestion(question);
                }
                else
                {
                    updatedReply.ReplyToId = question.AnswerCardActivityId;
                    var r = await connector.Conversations.UpdateActivityAsync(updatedReply.Conversation.Id, updatedReply.ReplyToId, updatedReply);

                    question.AnswerCardActivityId = r.Id;
                    SQLService.CreateOrUpdateQuestion(question);
                }
            }

            var baseUrl  = ServiceHelper.BaseUrl;
            var taskInfo = new Models.TaskInfo();

            taskInfo.Title  = "Select Answer";
            taskInfo.Height = 300;
            taskInfo.Width  = 400;
            taskInfo.Url    = baseUrl + @"/home/selectanswer?json=" + "Answer Updated";

            Models.TaskEnvelope taskEnvelope = new Models.TaskEnvelope
            {
                Task = new Models.Task()
                {
                    Type     = Models.TaskType.Continue,
                    TaskInfo = taskInfo,
                },
            };
            return(Request.CreateResponse(HttpStatusCode.OK, taskEnvelope));
        }
Exemplo n.º 5
0
        private async Task HandleMarkedAnswerFromCard(Microsoft.Bot.Connector.Activity activity)
        {
            ConnectorClient connector = new ConnectorClient(new Uri(activity.ServiceUrl));

            // Handle answer payload
            var adaptiveCardAnswerJson = activity.Value.ToString();
            var adaptiveCardAnswer     = JsonConvert.DeserializeObject <AdaptiveCardAnswerSubmit>(adaptiveCardAnswerJson);

            string selectedReplyJson = adaptiveCardAnswer.Answer;
            string questionId        = adaptiveCardAnswer.QuestionId;

            if (string.IsNullOrEmpty(selectedReplyJson))
            {
                Microsoft.Bot.Connector.Activity newReply = activity.CreateReply();
                newReply.Text = "There seems to be an issue saving the answer.";
                await connector.Conversations.ReplyToActivityAsync(activity.Conversation.Id, activity.ReplyToId, newReply);
            }
            else
            {
                var selectedReply = JsonConvert.DeserializeObject <TeamsMessage>(selectedReplyJson);
                var question      = SQLService.GetQuestion(Convert.ToInt32(questionId));

                // get user details
                var channelData = activity.GetChannelData <Microsoft.Bot.Connector.Teams.Models.TeamsChannelData>();
                var members     = await connector.Conversations.GetConversationMembersAsync(channelData.Team.Id);

                var         teamsMembers = members.AsTeamsChannelAccounts();
                var         currentUser  = teamsMembers.Where(x => x.ObjectId == activity.From.Properties["aadObjectId"].ToString()).FirstOrDefault();
                var         studentUPN   = currentUser.UserPrincipalName;
                var         isUserAdmin  = SQLService.IsUserAdmin(studentUPN);
                string      teamId       = channelData.Team.Id;
                TeamDetails teamDetails;
                try
                {
                    teamDetails = connector.GetTeamsConnectorClient().Teams.FetchTeamDetails(teamId);
                }
                catch (Exception e)
                {
                    teamDetails = connector.GetTeamsConnectorClient().Teams.FetchTeamDetails(teamId);
                    Trace.TraceError(e.ToString());
                }
                var teamName = teamDetails.Name;
                var courseID = SQLService.GetCourseIDByName(teamName.Trim());

                // check if user can set question status
                if (isUserAdmin || (studentUPN == question.OriginalPoster.Email) || (studentUPN == question.OriginalPoster.UserName))
                {
                    var selectedReplyUser = teamsMembers.Where(x => x.ObjectId == selectedReply.From.User.Id).FirstOrDefault();
                    var answeredBy        = SQLService.GetUser(selectedReplyUser.UserPrincipalName);

                    // update question model
                    question.QuestionStatus   = Constants.QUESTION_STATUS_ANSWERED;
                    question.QuestionAnswered = DateTime.Now;
                    question.AnswerText       = MicrosoftTeamsChannelHelper.StripMentionAndHtml(selectedReply.Body.Content);
                    question.AnswerPoster     = answeredBy;

                    SQLService.CreateOrUpdateQuestion(question);

                    // update old activity
                    Microsoft.Bot.Connector.Activity updatedReply = activity.CreateReply();

                    var card   = new AdaptiveCard();
                    var answer = new AdaptiveTextBlock("Answer: " + question.AnswerText.ReplaceLinksWithMarkdown());
                    answer.Weight = AdaptiveTextWeight.Bolder;
                    answer.Size   = AdaptiveTextSize.Medium;
                    answer.Wrap   = true;

                    var marked = new AdaptiveTextBlock($"Marked as " + question.QuestionStatus + " by " + currentUser.Name);
                    marked.Wrap = true;

                    var answered = new AdaptiveTextBlock("Answered by: " + question.AnswerPoster.FullName);
                    answered.Weight = AdaptiveTextWeight.Bolder;
                    answered.Wrap   = true;

                    card.Body.Add(answer);
                    card.Body.Add(answered);
                    card.Body.Add(marked);

                    Attachment attachment = new Attachment()
                    {
                        ContentType = AdaptiveCard.ContentType,
                        Content     = card,
                    };

                    updatedReply.Attachments.Add(attachment);

                    await connector.Conversations.UpdateActivityAsync(activity.Conversation.Id, activity.ReplyToId, updatedReply);

                    var predictiveQnAService = new PredictiveQnAService(courseID);
                    var res = await predictiveQnAService.AddQnAPair(question.QuestionText, question.AnswerText);
                }
            }
        }
Exemplo n.º 6
0
        private async Task HandleSelectAnswerFromCard(Microsoft.Bot.Connector.Activity activity)
        {
            ConnectorClient connector = new ConnectorClient(new Uri(activity.ServiceUrl));

            // get question details
            int questionId = Convert.ToInt32((activity.Value as dynamic)["questionId"]);
            var question   = SQLService.GetQuestion(questionId);

            // get user details
            var channelData = activity.GetChannelData <Microsoft.Bot.Connector.Teams.Models.TeamsChannelData>();
            var members     = await connector.Conversations.GetConversationMembersAsync(channelData.Team.Id);

            var teamsMembers = members.AsTeamsChannelAccounts();
            var currentUser  = teamsMembers.Where(x => x.ObjectId == activity.From.Properties["aadObjectId"].ToString()).FirstOrDefault();
            var studentUPN   = currentUser.UserPrincipalName;

            // var isUserAdmin = SharePointServices.IsUserAdmin(studentUPN);
            var isUserAdmin = SQLService.IsUserAdmin(studentUPN);

            // check if user can set question status
            if (isUserAdmin || (studentUPN == question.OriginalPoster.Email) || (studentUPN == question.OriginalPoster.UserName))
            {
                // find replies
                string teamId         = (activity.ChannelData as dynamic)["team"]["id"].ToString();
                string channelId      = (activity.ChannelData as dynamic)["channel"]["id"].ToString();
                var    conversationId = activity.Conversation.Id;
                string messageId      = conversationId.Split('=')[1];

                // update old activity
                Microsoft.Bot.Connector.Activity updatedReply = activity.CreateReply();

                var replies = await GetAllReplies(question.GroupId, channelId, messageId);

                var adaptiveCardChoices = new List <AdaptiveChoice>();
                if (replies != null && replies.Count > 0)
                {
                    foreach (var reply in replies)
                    {
                        adaptiveCardChoices.Add(new AdaptiveChoice()
                        {
                            Title = MicrosoftTeamsChannelHelper.StripMentionAndHtml(reply.Body.Content),
                            Value = JsonConvert.SerializeObject(reply),
                        });
                    }

                    var bodyTextBlock = new AdaptiveTextBlock()
                    {
                        Text = "Select an answer"
                    };
                    var bodyChoice = new AdaptiveChoiceSetInput()
                    {
                        Id            = "Answer",
                        Style         = AdaptiveChoiceInputStyle.Compact,
                        IsMultiSelect = false,
                        Choices       = adaptiveCardChoices,
                    };

                    var adaptiveCardAnswerSubmit = new AdaptiveCardAnswerSubmit(Constants.ACTIVITY_MARKED_ANSWERED, bodyChoice.Value, questionId.ToString());
                    var adaptiveCardAnswerString = JsonConvert.SerializeObject(adaptiveCardAnswerSubmit);
                    var actionJson = "{\"type\":\"" + Constants.ACTIVITY_SELECT_ANSWER + "\",\"questionId\": \"" + questionId.ToString() + "\"}";

                    var adaptiveCard = new AdaptiveCard()
                    {
                        Actions = new List <AdaptiveAction>()
                        {
                            new AdaptiveSubmitAction()
                            {
                                Title    = "Save",
                                DataJson = adaptiveCardAnswerString,
                            },
                            new AdaptiveSubmitAction()
                            {
                                Title    = "Refresh",
                                DataJson = actionJson,
                            },
                        },
                    };

                    adaptiveCard.Body.Add(bodyTextBlock);
                    adaptiveCard.Body.Add(bodyChoice);

                    var attachment = new Attachment()
                    {
                        ContentType = AdaptiveCard.ContentType,
                        Content     = adaptiveCard,
                    };

                    updatedReply.Attachments.Add(attachment);

                    try
                    {
                        // await connector.Conversations.UpdateActivityAsync(updatedReply);
                        updatedReply.Id = activity.ReplyToId;
                        var response = await connector.Conversations.UpdateActivityAsync(activity.Conversation.Id, activity.ReplyToId, updatedReply);
                    }
                    catch (Exception e)
                    {
                        Trace.TraceError(e.ToString());
                    }
                }
            }
        }