示例#1
0
        /// <inheritdoc/>
        /// Handles the submit method on a change message target request.
        public async Task <TaskModuleResponse> SubmitAsync(
            ITurnContext <IInvokeActivity> turnContext,
            TaskModuleRequest taskModuleRequest)
        {
            var teamEntity = await this.GetTeamEntityAsync(turnContext, taskModuleRequest);

            var channels = await TeamsInfo.GetTeamChannelsAsync(turnContext);

            var messageTargetChannelName =
                await this.messageTargetChannelNameService.GetMessageTargetChannelNameAsync(channels, teamEntity);

            var whoChangedTarget = turnContext.Activity.From.Name;

            var displayMessage = $"{whoChangedTarget} has selected the channel, {messageTargetChannelName}, as the message target.";
            var reply          = MessageFactory.Text(displayMessage);
            await turnContext.SendActivityAsync(reply);

            return(new TaskModuleResponse
            {
                Task = new TaskModuleMessageResponse()
                {
                    Value = displayMessage,
                },
            });
        }
示例#2
0
        protected override async Task OnMessageActivityAsync(ITurnContext <IMessageActivity> turnContext, CancellationToken cancellationToken)
        {
            var input = turnContext.Activity.Text?.Trim();

            if (input.ToLower().Contains("raise", StringComparison.InvariantCultureIgnoreCase))
            {
                serviceName = "Office 365";
                imagePath   = $"{imageBasePath}/office365_logo.jpg";

                if (input.ToLower().Contains("sharepoint", StringComparison.InvariantCultureIgnoreCase))
                {
                    serviceName = "SharePoint";
                    imagePath   = $"{imageBasePath}/sharepoint_logo.png";
                }
                else if (input.ToLower().Contains("teams", StringComparison.InvariantCultureIgnoreCase))
                {
                    serviceName = "MS Teams";
                    imagePath   = $"{imageBasePath}/teams_logo.png";
                }

                var member = await TeamsInfo.GetMemberAsync(turnContext, turnContext.Activity.From.Id, cancellationToken);
                await SendHttpToTeams(HttpMethod.Post, MessageFactory.Attachment(new CardResource("InitialCard.json").AsAttachment(
                                                                                     new
                {
                    createdByUserID = member.Id,
                    createdBy       = turnContext.Activity.From.Name,
                    serviceName     = serviceName,
                    imagePath       = imagePath
                })), turnContext.Activity.Conversation.Id);
            }
            else
            {
                await turnContext.SendActivityAsync(MessageFactory.Text("Invalid parameter"), cancellationToken);
            }
        }
示例#3
0
        /// <summary>
        /// Handle when a message is addressed to the bot.
        /// </summary>
        /// <param name="turnContext">The turn context.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>A task that represents the work queued to execute.</returns>
        protected override async Task OnMessageActivityAsync(ITurnContext <IMessageActivity> turnContext, CancellationToken cancellationToken)
        {
            if (turnContext.Activity.Text != null)
            {
                if (turnContext.Activity.Text.ToLower().Trim() == "staticsearch")
                {
                    string[] path   = { ".", "Cards", "StaticSearchCard.json" };
                    var      member = await TeamsInfo.GetMemberAsync(turnContext, turnContext.Activity.From.Id, cancellationToken);

                    var initialAdaptiveCard = GetFirstOptionsAdaptiveCard(path, turnContext.Activity.From.Name, member.Id);

                    await turnContext.SendActivityAsync(MessageFactory.Attachment(initialAdaptiveCard), cancellationToken);
                }
                else if (turnContext.Activity.Text.ToLower().Trim() == "dynamicsearch")
                {
                    string[] path   = { ".", "Cards", "DynamicSearchCard.json" };
                    var      member = await TeamsInfo.GetMemberAsync(turnContext, turnContext.Activity.From.Id, cancellationToken);

                    var initialAdaptiveCard = GetFirstOptionsAdaptiveCard(path, turnContext.Activity.From.Name, member.Id);

                    await turnContext.SendActivityAsync(MessageFactory.Attachment(initialAdaptiveCard), cancellationToken);
                }
            }
            else if (turnContext.Activity.Value != null)
            {
                var data = JsonConvert.DeserializeObject <StaticSearchCard>(turnContext.Activity.Value.ToString());
                await turnContext.SendActivityAsync(MessageFactory.Text("Selected option is: " + data.choiceSelect), cancellationToken);
            }
        }
        private async Task ShowDetailsAsync(ITurnContext <IMessageActivity> turnContext, CancellationToken cancellationToken)
        {
            var teamId      = turnContext.Activity.TeamsGetTeamInfo().Id;
            var teamDetails = await TeamsInfo.GetTeamDetailsAsync(turnContext, teamId, cancellationToken);

            await SendMessageAndLogActivityIdAsync(turnContext, $"The team name is {teamDetails.Name}. The team ID is {teamDetails.Id}. The ADD GroupID is {teamDetails.AadGroupId}.", cancellationToken);
        }
示例#5
0
        protected override async Task <MessagingExtensionActionResponse> OnTeamsMessagingExtensionSubmitActionAsync(ITurnContext <IInvokeActivity> turnContext, MessagingExtensionAction action, CancellationToken cancellationToken)
        {
            var taskModuleOutput = JsonConvert.DeserializeObject <TaskModuleSubmitDataDeserializer>(turnContext.Activity.Value.ToString());

            if (taskModuleOutput.data.SubmittedByMail == null)
            {
                action.CommandId = taskModuleOutput.commandId;
                var task = await OnTeamsMessagingExtensionFetchTaskAsync(turnContext, action, cancellationToken);

                return(task);
            }

            if (taskModuleOutput.commandId == Constants.MessageExtensionCommandId)
            {
                var member = await TeamsInfo.GetMemberAsync(turnContext, taskModuleOutput.data.AssignedTo.objectId, cancellationToken);

                taskModuleOutput.data.AssignedTo.objectId = member.Id;
                var blobId = await BlobHelper.UploadToBlob(taskModuleOutput, turnContext);

                var blobData        = BlobHelper.GetBlob(blobId, null).Result;
                var cardResponse    = CardHelper.CreateAdaptiveCardAttachment(Status.BaseCard, blobData, "msteams", out string cardJsonstring);
                var messageResponse = await turnContext.SendActivityAsync(MessageFactory.Attachment(cardResponse), cancellationToken);

                string messageId = messageResponse.Id;
                BlobHelper.GetBlob(blobId, null, messageId);

                //Send Mail
                await OutlookConnector.SendMailAsync(Constants.SenderEmail, blobData.assignedToMail, cardJsonstring, Constants.MailSubject);
            }
            return(new MessagingExtensionActionResponse());
        }
        /// <summary>
        /// Check if a user is a member of a certain team.
        /// </summary>
        /// <param name="teamId">The team id that the validator uses to check if the user is a member of the team. </param>
        /// <param name="userAadObjectId">The user's Azure Active Directory object id.</param>
        /// <returns>The flag indicates that the user is a part of certain team or not.</returns>
        private async Task <bool> ValidateUserAsync(string teamId, string userAadObjectId)
        {
            this.memoryCache.TryGetValue(userAadObjectId, out bool isUserValid);
            if (isUserValid == false)
            {
                var userTeamMembershipEntities = await this.teamTagStorageProvider.GetTeamTagAsync(teamId);

                if (userTeamMembershipEntities == null)
                {
                    return(false);
                }

                TeamsChannelAccount teamMember = new TeamsChannelAccount();

                var conversationReference = new ConversationReference
                {
                    ChannelId  = Constants.TeamsBotFrameworkChannelId,
                    ServiceUrl = userTeamMembershipEntities.ServiceUrl,
                };
                await((BotFrameworkAdapter)this.botAdapter).ContinueConversationAsync(
                    this.microsoftAppCredentials.MicrosoftAppId,
                    conversationReference,
                    async(context, token) =>
                {
                    teamMember = await TeamsInfo.GetTeamMemberAsync(context, userAadObjectId, teamId, CancellationToken.None);
                }, default);

                var isValid = teamMember != null;
                this.memoryCache.Set(userAadObjectId, isValid, TimeSpan.FromHours(1));
                return(isValid);
            }

            return(isUserValid);
        }
示例#7
0
        /// <summary>
        /// Gets the email id's of the SME uses who are available for oncallSupport.
        /// </summary>
        /// <param name="turnContext">Context object containing information cached for a single turn of conversation with a user.</param>
        /// <param name="onCallSupportDetailSearchService">Provider to search on call support details in Azure Table Storage.</param>
        /// <param name="teamId">Team id to which the message is being sent.</param>
        /// <param name="logger">Sends logs to the Application Insights service.</param>
        /// <returns>string with appended email id's.</returns>
        public static async Task <string> GetOnCallSMEuserListAsync(ITurnContext <IInvokeActivity> turnContext, IOnCallSupportDetailSearchService onCallSupportDetailSearchService, string teamId, ILogger <RemoteSupportActivityHandler> logger)
        {
            try
            {
                var teamsChannelAccounts = await TeamsInfo.GetTeamMembersAsync(turnContext, teamId, CancellationToken.None);

                var onCallSupportDetails = await onCallSupportDetailSearchService?.SearchOnCallSupportTeamAsync(string.Empty, 1);

                string onCallSMEUsers = string.Empty;
                if (onCallSupportDetails != null && onCallSupportDetails.Any())
                {
                    var onCallSMEDetail = JsonConvert.DeserializeObject <List <OnCallSMEDetail> >(onCallSupportDetails.First().OnCallSMEs);
                    if (onCallSMEDetail != null)
                    {
                        foreach (var onCallSME in onCallSMEDetail)
                        {
                            onCallSMEUsers += string.IsNullOrEmpty(onCallSMEUsers) ? teamsChannelAccounts.FirstOrDefault(teamsChannelAccount => teamsChannelAccount.AadObjectId == onCallSME.ObjectId)?.Email : "," + teamsChannelAccounts.FirstOrDefault(teamsChannelAccount => teamsChannelAccount.AadObjectId == onCallSME.ObjectId)?.Email;
                        }
                    }
                }

                return(onCallSMEUsers);
            }
#pragma warning disable CA1031 // Do not catch general exception types
            catch (Exception ex)
#pragma warning restore CA1031 // Do not catch general exception types
            {
                logger.LogError(ex, "Error in getting the oncallSMEUsers list.");
            }

            return(null);
        }
示例#8
0
        /// <summary>
        /// Update the first trail card with user details.
        /// </summary>
        /// <param name="scrumSummary">Scrum summary information to be shown on card.</param>
        /// <param name="scrum">Scrum details.</param>
        /// <param name="scrumMaster">Scrum master details.</param>
        /// <param name="membersActivityIdMap">Members id who are part of the scrum.</param>
        /// <param name="timeZone">Used to convert scrum start time as per specified time zone.</param>
        /// <param name="turnContext">Context object containing information cached for a single turn of conversation with a user.</param>
        /// <param name="cancellationToken">Propagates notification that operations should be canceled.</param>
        /// <returns>A task of type bool where true represents summary card updated successfully while false indicates failure in updating the summary card.</returns>
        public async Task <bool> UpdateSummaryCardWithEndScrumAsync(ScrumSummary scrumSummary, Scrum scrum, ScrumMaster scrumMaster, Dictionary <string, string> membersActivityIdMap, string timeZone, ITurnContext turnContext, CancellationToken cancellationToken)
        {
            if (scrumSummary != null)
            {
                var activitySummary  = MessageFactory.Attachment(ScrumCard.GetScrumStartCard(scrumSummary, membersActivityIdMap, scrumMaster?.ScrumMasterId, scrum?.ScrumStartActivityId, this.localizer, timeZone));
                var teamsChannelInfo = await TeamsInfo.GetTeamChannelsAsync(turnContext, scrumMaster.TeamId, CancellationToken.None);

                var channelInfo = teamsChannelInfo.Where(channel => channel.Id.Equals(scrumMaster.ChannelId, StringComparison.OrdinalIgnoreCase)).FirstOrDefault();

                if (channelInfo != null)
                {
                    activitySummary.Id           = scrum.ScrumStartCardResponseId;
                    activitySummary.Conversation = new ConversationAccount
                    {
                        Id = $"{scrumMaster.ChannelId};messageid={scrum.ScrumStartCardResponseId}",
                    };
                    this.logger.LogInformation($"Trail card updated for: {scrum.ThreadConversationId} summaryCardActivityId: {scrum.ScrumStartCardResponseId}");
                    await turnContext?.UpdateActivityAsync(activitySummary, cancellationToken);
                }

                return(true);
            }
            else
            {
                this.logger.LogInformation($"No data obtained from storage to update summary card for summaryCardActivityId : {scrum?.ScrumStartCardResponseId}");
                return(false);
            }
        }
        private async Task <List <Entity> > GetPeopleToMention(ITurnContext turnContext, CancellationToken cancellationToken)
        {
            IEnumerable <TeamsChannelAccount> members = await TeamsInfo.GetMembersAsync(turnContext, cancellationToken);

            List <Entity> entities = new List <Entity>();

            foreach (TeamsChannelAccount member in members)
            {
                foreach (string upn in dataFromRequest.Mentions)
                {
                    if (String.Compare(member.UserPrincipalName, upn, true) == 0)
                    {
                        // Construct a ChannelAccount Object.
                        ChannelAccount mentionedUser = new ChannelAccount(member.Id, member.Name, member.Role, member.AadObjectId);
                        // Construct a Mention object.
                        var mentionObject = new Mention
                        {
                            Mentioned = mentionedUser,
                            Text      = $"<at>{XmlConvert.EncodeName(member.Name)}</at>",
                        };
                        entities.Add(mentionObject);
                    }
                }
            }
            return(entities);
        }
        // Called when the task module is fetched for an action
        public async Task <MessagingExtensionActionResponse> HandleMessagingExtensionFetchTaskAsync(ITurnContext turnContext, MessagingExtensionAction query)
        {
            var emptyRequest = new ConsultingRequestDetails();
            ConsultingDataService dataService = new ConsultingDataService();

            emptyRequest.possibleProjects = await dataService.GetProjects("");

            IEnumerable <TeamsChannelAccount> members = await TeamsInfo.GetMembersAsync(turnContext);

            emptyRequest.possiblePersons = members.Select((w) => new Person
            {
                name  = w.Name,
                email = w.Email
            })
                                           .ToList();

            var card = await AddToProjectCard.GetCardAsync(turnContext, emptyRequest);

            var response = new Microsoft.Bot.Schema.Teams.TaskModuleContinueResponse()
            {
                Type  = "continue",
                Value = new TaskModuleTaskInfo()
                {
                    Title = "Select a sample",
                    Card  = card.ToAttachment()
                }
            };

            return(new MessagingExtensionActionResponse
            {
                Task = response
            });
        }
        /// <inheritdoc/>
        public override async Task <DialogTurnResult> BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (options is CancellationToken)
            {
                throw new ArgumentException($"{nameof(options)} cannot be a cancellation token");
            }

            if (Disabled != null && Disabled.GetValue(dc.State))
            {
                return(await dc.EndDialogAsync(cancellationToken : cancellationToken).ConfigureAwait(false));
            }

            if (dc.Context.Activity.ChannelId != Channels.Msteams)
            {
                throw new InvalidOperationException($"{Kind} works only on the Teams channel.");
            }

            string continuationToken = ContinuationToken.GetValueOrNull(dc.State);
            string teamId            = TeamId.GetValueOrNull(dc.State);
            int?   pageSize          = PageSize.GetValueOrNull(dc.State);

            var result = await TeamsInfo.GetPagedTeamMembersAsync(dc.Context, teamId, continuationToken, pageSize, cancellationToken : cancellationToken).ConfigureAwait(false);

            if (Property != null)
            {
                dc.State.SetValue(Property.GetValue(dc.State), result);
            }

            return(await dc.EndDialogAsync(result, cancellationToken : cancellationToken).ConfigureAwait(false));
        }
        /// <summary>
        /// Called when the dialog is started and pushed onto the dialog stack.
        /// </summary>
        /// <param name="dc">The <see cref="DialogContext"/> for the current turn of conversation.</param>
        /// <param name="options">Optional, initial information to pass to the dialog.</param>
        /// <param name="cancellationToken">A cancellation token that can be used by other objects
        /// or threads to receive notice of cancellation.</param>
        /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
        public override async Task <DialogTurnResult> BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (options is CancellationToken)
            {
                throw new ArgumentException($"{nameof(options)} cannot be a cancellation token");
            }

            if (this.Disabled != null && this.Disabled.GetValue(dc.State) == true)
            {
                return(await dc.EndDialogAsync(cancellationToken : cancellationToken).ConfigureAwait(false));
            }

            if (dc.Context.Activity.ChannelId != Channels.Msteams)
            {
                throw new Exception("TeamsInfo.GetMeetingParticipantAsync() works only on the Teams channel.");
            }

            string meetingId     = GetValueOrNull(dc, this.MeetingId);
            string participantId = GetValueOrNull(dc, this.ParticipantId);
            string tenantId      = GetValueOrNull(dc, this.TenantId);

            if (participantId == null)
            {
                // TeamsInfo.GetMeetingParticipantAsync will default to retrieving the current meeting's participant
                // if none is provided.  This could lead to unexpected results.  Therefore, GetMeetingParticipant action
                // throws an exception if the expression provided somehow maps to an invalid result.
                throw new InvalidOperationException($"GetMeetingParticipant could determine the participant id by expression value provided. {nameof(participantId)} is required.");
            }

            var result = await TeamsInfo.GetMeetingParticipantAsync(dc.Context, meetingId, participantId, tenantId, cancellationToken : cancellationToken).ConfigureAwait(false);

            dc.State.SetValue(this.Property.GetValue(dc.State), result);

            return(await dc.EndDialogAsync(result, cancellationToken : cancellationToken).ConfigureAwait(false));
        }
        private async Task GetSingleMemberAsync(ITurnContext <IMessageActivity> turnContext, CancellationToken cancellationToken)
        {
            var member = new TeamsChannelAccount();

            try
            {
                member = await TeamsInfo.GetMemberAsync(turnContext, turnContext.Activity.From.Id, cancellationToken);
            }
            catch (ErrorResponseException e)
            {
                if (e.Body.Error.Code.Equals("MemberNotFoundInConversation"))
                {
                    await turnContext.SendActivityAsync("Member not found.");

                    return;
                }
                else
                {
                    throw e;
                }
            }

            var message = MessageFactory.Text($"You are: {member.Name}.");
            var res     = await turnContext.SendActivityAsync(message);
        }
示例#14
0
        private async Task HydrateTeamsData(List <AzureDevOpsWorkItem> workItems, ITurnContext <IMessageActivity> turnContext, CancellationToken cancellationToken)
        {
            // Get the roster one time in the current team and look up people inside it as needed
            var members = await TeamsInfo.GetMembersAsync(turnContext, cancellationToken);

            foreach (var wi in workItems)
            {
                // Plug the Team user-id for assigned-to
                if (wi.Fields.AssignedTo != null)
                {
                    wi.Fields.AssignedTo.TeamsUserId = members.Where(m =>
                                                                     m.UserPrincipalName.Equals(wi.Fields.AssignedTo.Uniquename, StringComparison.InvariantCultureIgnoreCase))
                                                       .FirstOrDefault()?.Id
                                                       ?? turnContext.Activity.From.Id;
                }

                // Plug the Team user-id for EM owner
                if (wi.Fields.EMOwner != null)
                {
                    wi.Fields.EMOwner.TeamsUserId = members.Where(m =>
                                                                  m.UserPrincipalName.Equals(wi.Fields.EMOwner.Uniquename, StringComparison.InvariantCultureIgnoreCase))
                                                    .FirstOrDefault()?.Id
                                                    ?? turnContext.Activity.From.Id;
                }

                // Plug the Team user-id for PM owner
                if (wi.Fields.PMOwner != null)
                {
                    wi.Fields.PMOwner.TeamsUserId = members.Where(m =>
                                                                  m.UserPrincipalName.Equals(wi.Fields.PMOwner.Uniquename, StringComparison.InvariantCultureIgnoreCase))
                                                    .FirstOrDefault()?.Id
                                                    ?? turnContext.Activity.From.Id;
                }
            }
        }
示例#15
0
        private async Task <List <Person> > ResolvePerson(string name, ITurnContext turnContext, CancellationToken cancellationToken)
        {
            List <Person> result = null;

            IEnumerable <TeamsChannelAccount> members = await TeamsInfo.GetMembersAsync(turnContext, cancellationToken);

            result = members.Where((w) => w.Name.ToLower().Contains(name.ToLower()))
                     .Select((w) => new Person
            {
                name  = w.Name,
                email = w.Email
            })
                     .ToList();
            result.Sort((p, q) => string.Compare(p.name, q.name));

            if (result == null || result.Count == 0)
            {
                result = new List <Person> {
                    new Person {
                        name = name, email = ""
                    }
                };
            }

            return(result);
        }
示例#16
0
        /// <summary>
        /// Get general channel Id if scrum channel id does not exist.
        /// </summary>
        /// <param name="turnContext">Context object containing information cached for a single turn of conversation with a user.</param>
        /// <param name="scrumMasterDetails">Scrum master details.</param>
        /// <returns>Returns general channel Id if scrum channel id does not exist.</returns>
        private async Task <string> GetValidChannelIdAsync(ITurnContext turnContext, ScrumMaster scrumMasterDetails)
        {
            var teamsChannelInfo = await TeamsInfo.GetTeamChannelsAsync(turnContext, scrumMasterDetails.TeamId, CancellationToken.None);

            var channelInfo = teamsChannelInfo.Where(channel => channel.Id.Equals(scrumMasterDetails.ChannelId, StringComparison.OrdinalIgnoreCase)).FirstOrDefault();

            if (channelInfo != null)
            {
                return(scrumMasterDetails.ChannelId);
            }

            scrumMasterDetails.ChannelId   = scrumMasterDetails.TeamId;
            scrumMasterDetails.ChannelName = Constants.GeneralChannel;

            List <ScrumMaster> scrumMasters = new List <ScrumMaster>();

            scrumMasters.Add(scrumMasterDetails);

            var saveResponse = await this.scrumMasterStorageProvider.StoreOrUpdateScrumMasterEntitiesAsync(scrumMasters);

            if (!saveResponse)
            {
                this.logger.LogError("Error while saving scrum master details.");
            }

            return(scrumMasterDetails.TeamId);
        }
        /// <summary>
        /// Fetches the roster with the new paginated calls to handles larger teams.
        /// https://docs.microsoft.com/en-us/microsoftteams/platform/bots/how-to/get-teams-context?tabs=dotnet#fetching-the-roster-or-user-profile.
        /// </summary>
        /// <param name="turnContext">The context object for this turn.</param>
        /// <param name="cancellationToken">A cancellation token that can be used by other objects.</param>
        /// <returns>The roster fetched by calling the new paginated SDK API.</returns>
        private async Task <IEnumerable <TeamsChannelAccount> > GetMembersAsync(
            ITurnContext turnContext,
            CancellationToken cancellationToken)
        {
            var       members           = new List <TeamsChannelAccount>();
            string    continuationToken = null;
            const int pageSize          = 500;

            do
            {
                var currentPage = await TeamsInfo.GetPagedMembersAsync(
                    turnContext,
                    pageSize,
                    continuationToken,
                    cancellationToken);

                continuationToken = currentPage.ContinuationToken;

                // Skip Guest users.
                var membersWithoutGuests = currentPage.Members.Where(member => !member.UserPrincipalName.ToLower().Contains("#ext#"));
                members.AddRange(membersWithoutGuests);
            }while (continuationToken != null && !cancellationToken.IsCancellationRequested);

            return(members);
        }
        private async Task <DialogTurnResult> TitleStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
        {
            var team = (Models.Team)stepContext.Result;

            if (team == null)
            {
                await stepContext.Context.SendActivityAsync(MessageFactory.Text("No team was selected. Cancelled creating idea."), cancellationToken);

                return(await stepContext.EndDialogAsync(cancellationToken : cancellationToken));
            }

            var createIdeaOptions = (CreateIdeaOptions)stepContext.Options;

            if (createIdeaOptions.Title != null)
            {
                return(await stepContext.NextAsync(createIdeaOptions.Title, cancellationToken));
            }

            var member = await TeamsInfo.GetMemberAsync(stepContext.Context, stepContext.Context.Activity.From.Id, cancellationToken);

            var promptOptions = new PromptOptions
            {
                Prompt = MessageFactory.Text($"Hi @{member.GivenName}! What is your idea?")
            };

            return(await stepContext.PromptAsync(nameof(TextPrompt), promptOptions, cancellationToken));
        }
示例#19
0
        public async Task <ActionResult <string> > GetAdaptiveCardToChangeMessageTargetAsync(string teamId)
        {
            var teamEntity = await this.teamRepository.GetAsync(teamId);

            if (teamEntity == null)
            {
                return(this.NotFound($"Cannot find the team with id {teamId}."));
            }

            AdaptiveCard adaptiveCard = null;

            await this.turnContextService.ContinueConversationAsync(
                teamEntity,
                async (turnContext) =>
            {
                var channels        = await TeamsInfo.GetTeamChannelsAsync(turnContext);
                var targetChannelId = teamEntity.MessageTargetChannel;
                adaptiveCard        = this.changeMessageTargetCardRenderer.Build(channels, targetChannelId);
            });

            if (adaptiveCard == null)
            {
                throw new ApplicationException("Cannot build up the turn context. Failed to retrieve the message target info.");
            }

            return(adaptiveCard.ToJson());
        }
示例#20
0
        /// <inheritdoc/>
        public override async Task <DialogTurnResult> BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (options is CancellationToken)
            {
                throw new ArgumentException($"{nameof(options)} cannot be a cancellation token");
            }

            if (Disabled != null && Disabled.GetValue(dc.State))
            {
                return(await dc.EndDialogAsync(cancellationToken : cancellationToken).ConfigureAwait(false));
            }

            if (dc.Context.Activity.ChannelId != Channels.Msteams)
            {
                throw new InvalidOperationException($"{Kind} works only on the Teams channel.");
            }

            string memberId = MemberId.GetValueOrNull(dc.State);

            if (string.IsNullOrEmpty(memberId))
            {
                throw new InvalidOperationException($"Missing {nameof(MemberId)} in {Kind}.");
            }

            var result = await TeamsInfo.GetMemberAsync(dc.Context, memberId, cancellationToken : cancellationToken).ConfigureAwait(false);

            if (Property != null)
            {
                dc.State.SetValue(Property.GetValue(dc.State), result);
            }

            return(await dc.EndDialogAsync(result, cancellationToken : cancellationToken).ConfigureAwait(false));
        }
        protected override async Task <MessagingExtensionActionResponse> OnTeamsMessagingExtensionBotMessagePreviewSendAsync(ITurnContext <IInvokeActivity> turnContext, MessagingExtensionAction action, CancellationToken cancellationToken)
        {
            var        submitData       = action.ToSubmitExampleData();
            var        adaptiveCard     = submitData.ToAdaptiveCard();
            var        responseActivity = Activity.CreateMessageActivity();
            Attachment attachment       = new Attachment()
            {
                ContentType = AdaptiveCard.ContentType,
                Content     = adaptiveCard,
            };

            responseActivity.Attachments.Add(attachment);
            try
            {
                // Send to channel where messaging extension invoked.
                var channelId = turnContext.Activity.TeamsGetChannelId();
                await turnContext.TeamsCreateConversationAsync(channelId, responseActivity);

                // Send card to "General" channel.
                var teamDetails = await TeamsInfo.GetTeamDetailsAsync(turnContext);

                await turnContext.TeamsCreateConversationAsync(teamDetails.Id, responseActivity);
            }
            catch (Exception ex)
            {
                // In group chat or personal scope..
                await turnContext.SendActivityAsync($"In Group Chat or Personal Teams scope. Sending card to compose-only.");
            }

            return(adaptiveCard.ToComposeExtensionResultResponse());
        }
        /// <summary>
        /// Add channel or personal data in Table Storage.
        /// </summary>
        /// <param name="turnContext">The context object for this turn.</param>
        /// <param name="activity">Teams activity instance.</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 the work queued to execute.</returns>
        public async Task OnBotAddedAsync(ITurnContext turnContext, IConversationUpdateActivity activity, CancellationToken cancellationToken)
        {
            // Take action if the event includes the bot being added.
            var membersAdded = activity.MembersAdded;

            if (membersAdded == null || !membersAdded.Any(p => p.Id == activity.Recipient.Id))
            {
                return;
            }

            switch (activity.Conversation.ConversationType)
            {
            case TeamsDataCapture.ChannelType:
                await this.teamDataRepository.SaveTeamDataAsync(activity);

                break;

            case TeamsDataCapture.PersonalType:
                // Skip Guest users
                TeamsChannelAccount teamsUser = await TeamsInfo.GetMemberAsync(turnContext, activity.From.Id, cancellationToken);

                if (!teamsUser.UserPrincipalName.ToLower().Contains("#ext#"))
                {
                    await this.userDataService.SaveUserDataAsync(activity);
                }

                break;

            default: break;
            }

            // Update service url app setting.
            await this.UpdateServiceUrl(activity.ServiceUrl);
        }
        protected override async Task OnMessageActivityAsync(ITurnContext <IMessageActivity> turnContext, CancellationToken cancellationToken)
        {
            if (turnContext.Activity.Text == "Add me")
            {
                var member = await TeamsInfo.GetMemberAsync(turnContext, turnContext.Activity.From.Id, cancellationToken);

                var user = new UserDetailsEntity()
                {
                    Name              = (member.Name).Split(" ")[0], //indsert proper name
                    UserUniqueID      = turnContext.Activity.From.Id,
                    AadId             = turnContext.Activity.From.AadObjectId,
                    EmailId           = member.Email,
                    ProfilePictureURL = string.Empty,
                    RowKey            = Guid.NewGuid().ToString(),
                    PartitionKey      = PartitionKeyNames.UserDetailsDataTable.TableName
                };

                await _userDetailsRepository.CreateOrUpdateAsync(user);

                var reply = MessageFactory.Text("Your data is recorded !");
                await turnContext.SendActivityAsync(reply, cancellationToken);
            }
            else
            {
                var reply = MessageFactory.Text("Welcome to Task Manager, Try crating new Tasks using Messaging extension");
                await turnContext.SendActivityAsync(reply, cancellationToken);
            }
        }
        public async Task <IActionResult> GetTeamMembersAsync(string teamId)
        {
            try
            {
                if (teamId == null)
                {
                    return(this.BadRequest(new { message = "Team ID cannot be empty." }));
                }

                var userClaims = this.GetUserClaims();

                IEnumerable <TeamsChannelAccount> teamsChannelAccounts = new List <TeamsChannelAccount>();
                var conversationReference = new ConversationReference
                {
                    ChannelId  = teamId,
                    ServiceUrl = userClaims.ServiceUrl,
                };

                await this.botAdapter.ContinueConversationAsync(
                    this.appId,
                    conversationReference,
                    async (context, token) =>
                {
                    teamsChannelAccounts = await TeamsInfo.GetTeamMembersAsync(context, teamId, default);
                },
        /// <summary>
        /// Validates endorsement status.
        /// </summary>
        /// <param name="turnContext">Context object containing information cached for a single turn of conversation with a user.</param>
        /// <param name="valuesforTaskModule">Get the binded values from the card.</param>
        /// <returns>Returns the true, if endorsement is successful, else false.</returns>
        private async Task <bool> CheckEndorseStatusAsync(ITurnContext <IInvokeActivity> turnContext, AdaptiveCardAction valuesforTaskModule)
        {
            var teamsDetails         = turnContext.Activity.TeamsGetTeamInfo();
            var teamsChannelAccounts = await TeamsInfo.GetTeamMembersAsync(turnContext, teamsDetails.Id, CancellationToken.None);

            var userDetails   = teamsChannelAccounts.Where(member => member.AadObjectId == turnContext.Activity.From.AadObjectId).FirstOrDefault();
            var endorseEntity = await this.endorseDetailStorageProvider.GetEndorseDetailAsync(teamsDetails.Id, valuesforTaskModule.RewardCycleId, valuesforTaskModule.NominatedToPrincipalName);

            var result = endorseEntity.Where(row => row.EndorseForAwardId == valuesforTaskModule.AwardId && row.EndorsedByObjectId == userDetails.AadObjectId).FirstOrDefault();

            if (result == null)
            {
                var endorsedetails = new EndorseEntity
                {
                    TeamId                  = teamsDetails.Id,
                    EndorsedByObjectId      = userDetails.AadObjectId,
                    EndorsedByPrincipalName = userDetails.Email,
                    EndorseForAward         = valuesforTaskModule.AwardName,
                    EndorsedToPrincipalName = valuesforTaskModule.NominatedToPrincipalName,
                    EndorsedToObjectId      = valuesforTaskModule.NominatedToObjectId,
                    EndorsedOn              = DateTime.UtcNow,
                    EndorseForAwardId       = valuesforTaskModule.AwardId,
                    AwardCycle              = valuesforTaskModule.RewardCycleId,
                };

                return(await this.endorseDetailStorageProvider.StoreOrUpdateEndorseDetailAsync(endorsedetails));
            }

            return(false);
        }
示例#26
0
        private async Task PairingProgrammingAsync(ITurnContext <IMessageActivity> turnContext, CancellationToken cancellationToken)
        {
            var teamsChannelId = turnContext.Activity.TeamsGetChannelId();

            if (teamsChannelId != _MMDTeamGenaralChannelID)
            {
                await turnContext.SendActivityAsync("No permission for this command");

                return;
            }
            var members = await TeamsInfo.GetMembersAsync(turnContext, cancellationToken);

            var membersList = members.ToList();
            var mentionText = "Hello every, here is weekly pairing programing. Next is God's choice: \n\r";
            var mentionList = new List <Entity> {
            };
            Random rd       = new Random();

            while (membersList.Count > 1)
            {
                var firstIndex   = rd.Next(membersList.Count);
                var firstMember  = membersList[firstIndex];
                var firstMention = new Mention
                {
                    Mentioned = firstMember,
                    Text      = $"<at>{XmlConvert.EncodeName(firstMember.Name)}</at>",
                };
                membersList.RemoveAt(firstIndex);
                var secondIndex   = rd.Next(membersList.Count);
                var secondMember  = membersList[secondIndex];
                var secondMention = new Mention
                {
                    Mentioned = secondMember,
                    Text      = $"<at>{XmlConvert.EncodeName(secondMember.Name)}</at>",
                };
                membersList.RemoveAt(secondIndex);
                mentionText += firstMention.Text + " & " + secondMention.Text + "\n\r";
                mentionList.Add(firstMention);
                mentionList.Add(secondMention);
            }

            if (membersList.Count == 1)
            {
                var lastMember  = membersList[0];
                var lastMention = new Mention
                {
                    Mentioned = lastMember,
                    Text      = $"<at>{XmlConvert.EncodeName(lastMember.Name)}</at>",
                };
                mentionText += "And " + lastMention.Text + ", feel free to join each group of them.";
                mentionList.Add(lastMention);
            }

            var replyActivity = MessageFactory.Text(mentionText);

            replyActivity.Entities = mentionList;

            await turnContext.SendActivityAsync(replyActivity, cancellationToken);
        }
            private async Task CallGetTeamDetailsAsync(ITurnContext turnContext)
            {
                var teamDetails = await TeamsInfo.GetTeamDetailsAsync(turnContext);

                Assert.AreEqual("team-id", teamDetails.Id);
                Assert.AreEqual("team-name", teamDetails.Name);
                Assert.AreEqual("team-aadgroupid", teamDetails.AadGroupId);
            }
示例#28
0
        private async Task ShowDetailsAsync(ITurnContext <IMessageActivity> turnContext, CancellationToken cancellationToken)
        {
            var teamDetails = await TeamsInfo.GetTeamDetailsAsync(turnContext, cancellationToken);

            var message = $"The team name is <b>{teamDetails.Name}</b>. The team ID is <b>{teamDetails.Id}</b>. The ADDGroupID is <b>{teamDetails.AadGroupId}</b>.";

            await SendMessageAndLogActivityId(turnContext, message, cancellationToken);
        }
示例#29
0
            private async Task CallTeamsInfoGetParticipantAsync(ITurnContext turnContext)
            {
                var participant = await TeamsInfo.GetMeetingParticipantAsync(turnContext);

                Assert.Equal("Organizer", participant.Meeting.Role);
                Assert.Equal("meetigConversationId-1", participant.Conversation.Id);
                Assert.Equal("userPrincipalName-1", participant.User.UserPrincipalName);
            }
示例#30
0
        /// <summary>
        /// Get Azure Active Directory group Id of the team in which bot is installed.
        /// </summary>
        /// <param name="turnContext">Context object containing information cached for a single turn of conversation with a user.</param>
        /// <param name="cancellationToken">Propagates notification that operations should be canceled.</param>
        /// <returns>Return Active Directory group Id of the team.</returns>
        public async Task <string> GetTeamAadGroupIdAsync(ITurnContext turnContext, CancellationToken cancellationToken)
        {
            turnContext = turnContext ?? throw new ArgumentNullException(nameof(turnContext));
            var teamInformation = turnContext.Activity.TeamsGetTeamInfo();
            var teamDetails     = await TeamsInfo.GetTeamDetailsAsync(turnContext, teamInformation.Id, cancellationToken).ConfigureAwait(false);

            return(teamDetails.AadGroupId);
        }