示例#1
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);
            }
        }
示例#2
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 teamId = TeamId.GetValueOrNull(dc.State);
            var    result = await TeamsInfo.GetTeamChannelsAsync(dc.Context, teamId, cancellationToken : cancellationToken).ConfigureAwait(false);

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

            return(await dc.EndDialogAsync(result, cancellationToken : cancellationToken).ConfigureAwait(false));
        }
示例#3
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);
        }
示例#4
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,
                },
            });
        }
        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());
        }
示例#6
0
        private async Task <IReportBodyDetails> GetReportBodyDetailsAsync(ITurnContext context, IEnumerable <IMessageDetails> messages, ReportParameters parameters, CancellationToken cancellationToken)
        {
            var details = new ReportBodyDetails()
            {
                IsChannel      = parameters.ReportType == ReportSourceType.Channel,
                IsConversation = parameters.ReportType == ReportSourceType.Conversation,
                IsGroupChat    = parameters.ReportType == ReportSourceType.Chat,
                Messages       = messages,
                Since          = parameters.Since,
                Till           = parameters.Till,
                Author         = context.Activity.From?.Name,
            };

            if (context.Activity.Conversation.ConversationType == Constants.ChannelConversationType)
            {
                var channelData = context.Activity.GetChannelData <TeamsChannelData>();
                var teamDetails = new TeamDetails(channelData.Team.Id, channelData.Team.Name);
                details.ChannelName = channelData.Channel.Name;
                if (channelData.Team.Id == channelData.Channel.Id)
                {
                    // The channel ID for the General channel always matches the team ID (from MS documentation).
                    // The name of the default General channel is returned as null to allow for localization. (from MS documentation).
                    details.ChannelName = Resources.Strings.TeamGeneralChannelDefaultTitle;
                }

                try
                {
                    teamDetails = await TeamsInfo.GetTeamDetailsAsync(context, channelData.Team.Id, cancellationToken);

                    if (teamDetails != null)
                    {
                        details.TeamName = teamDetails.Name;
                        details.TeamId   = teamDetails.AadGroupId;
                        if (string.IsNullOrEmpty(details.ChannelName))
                        {
                            var channels = await TeamsInfo.GetTeamChannelsAsync(context, channelData.Team.Id, cancellationToken);

                            details.ChannelName = channels?.FirstOrDefault(x => channelData.Channel.Id.Equals(x.Id))?.Name;
                        }
                    }
                }
                catch
                {
                    // Bot is not aaded to the team, Forbidden exception here
                    details.TeamName = channelData.Team.Id; // Team name is not available here
                    details.TeamId   = channelData.Team.Id;
                    logger.LogWarning($"Bot is not added to team {channelData.Team.Id}");
                }

                if (string.IsNullOrEmpty(details.ChannelName))
                {
                    // Fill it with channel id if name is not available.
                    details.ChannelName = channelData.Channel.Id;
                }
            }

            return(details);
        }
示例#7
0
        public async Task <IActionResult> GetTeamDetailsAsync(string teamId)
        {
            try
            {
                var userClaims = this.GetUserClaims();

                var teamsChannelAccounts = new List <TeamsChannelAccount>();
                IEnumerable <ChannelInfo> teamsChannelInfo = new List <ChannelInfo>();
                var conversationReference = new ConversationReference
                {
                    ChannelId  = teamId,
                    ServiceUrl = userClaims.ServiceUrl,
                    Bot        = new ChannelAccount()
                    {
                        Id = this.appId
                    },
                    Conversation = new ConversationAccount()
                    {
                        ConversationType = Constants.ConversationType, IsGroup = true, Id = teamId, TenantId = this.options.Value.TenantId
                    },
                };

                await this.botAdapter.ContinueConversationAsync(
                    this.appId,
                    conversationReference,
                    async (context, token) =>
                {
                    string continuationToken = null;
                    do
                    {
                        var currentPage   = await TeamsInfo.GetPagedMembersAsync(context, 100, continuationToken, CancellationToken.None);
                        continuationToken = currentPage.ContinuationToken;
                        teamsChannelAccounts.AddRange(currentPage.Members);
                    }while (continuationToken != null);

                    teamsChannelInfo = await TeamsInfo.GetTeamChannelsAsync(context, teamId, CancellationToken.None);
                },
                    default);

                this.logger.LogInformation("GET call for fetching team members and channels from team roster is successful");
                teamsChannelInfo.First(channel => channel.Name == null).Name = Constants.GeneralChannel;
                var teamDetails = new
                {
                    TeamMembers = teamsChannelAccounts.Select(member => new { content = member.Email, header = member.Name, aadobjectid = member.AadObjectId }),
                    Channels    = teamsChannelInfo.Select(member => new { ChannelId = member.Id, header = member.Name }),
                };

                return(this.Ok(teamDetails));
            }
            catch (Exception ex)
            {
                this.logger.LogError(ex, "Error occurred while getting team member list.");
                throw;
            }
        }
            private async Task CallGetChannelsAsync(ITurnContext turnContext)
            {
                var channels = (await TeamsInfo.GetTeamChannelsAsync(turnContext)).ToArray();

                Assert.AreEqual("channel-id-1", channels[0].Id);

                Assert.AreEqual("channel-id-2", channels[1].Id);
                Assert.AreEqual("channel-name-2", channels[1].Name);

                Assert.AreEqual("channel-id-3", channels[2].Id);
                Assert.AreEqual("channel-name-3", channels[2].Name);
            }
示例#9
0
        private async Task ShowChannelsAsync(ITurnContext <IMessageActivity> turnContext, CancellationToken cancellationToken)
        {
            var teamId = turnContext.Activity.TeamsGetTeamInfo().Id;

            var channels = await TeamsInfo.GetTeamChannelsAsync(turnContext, teamId, cancellationToken);

            var replyActivity = MessageFactory.Text($"Total of {channels.Count} channels are currently in team");

            await turnContext.SendActivityAsync(replyActivity);

            var messages = channels.Select(channel => $"{channel.Id} --> {channel.Name}");

            await SendInBatchesAsync(turnContext, messages, cancellationToken);
        }
示例#10
0
        private async Task ShowChannelsAsync(ITurnContext <IMessageActivity> turnContext, CancellationToken cancellationToken)
        {
            if (await TeamScopeCheck(turnContext, cancellationToken).ConfigureAwait(false))
            {
                var teamId   = turnContext.Activity.TeamsGetTeamInfo().Id;
                var channels = await TeamsInfo.GetTeamChannelsAsync(turnContext, "19:[email protected]", cancellationToken).ConfigureAwait(false);

                var replyActivity = MessageFactory.Text($"Total of {channels.Count} channels are currently in team");
                await turnContext.SendActivityAsync(replyActivity).ConfigureAwait(false);

                var messages = channels.Select(channel => $"{channel.Id} --> {channel.Name}");
                await SendInBatchesAsync(turnContext, messages, cancellationToken).ConfigureAwait(false);
            }
        }
示例#11
0
        private async Task <string> GetMessageTargetChannelNameAsync(TeamEntity teamEntity)
        {
            // Get team channels.
            IEnumerable <ChannelInfo> channels = null;

            await this.turnContextService.ContinueConversationAsync(
                teamEntity,
                async (turnContext) =>
            {
                channels = await TeamsInfo.GetTeamChannelsAsync(turnContext);
            });

            if (channels == null)
            {
                throw new ApplicationException($"Failed to get the channels for a MS Teams team {teamEntity.TeamId}.");
            }

            return(await this.messageTargetChannelNameService.GetMessageTargetChannelNameAsync(channels, teamEntity));
        }
示例#12
0
        /// <inheritdoc/>
        /// Handles the fetch method on a change message target request.
        public async Task <TaskModuleResponse> FetchAsync(
            ITurnContext <IInvokeActivity> turnContext,
            TaskModuleRequest taskModuleRequest)
        {
            var channels = await TeamsInfo.GetTeamChannelsAsync(turnContext);

            var teamsChannelData = turnContext.Activity.GetChannelData <TeamsChannelData>();
            var teamEntity       = await this.teamRepository.GetAsync(teamsChannelData?.Team?.Id);

            var messageTargetChannelId = teamEntity?.MessageTargetChannel;

            return(new TaskModuleResponse
            {
                Task = new TaskModuleContinueResponse
                {
                    Value = new TaskModuleTaskInfo()
                    {
                        Title = "Setup message target channel",
                        Width = 400,
                        Card = this.changeMessageTargetCardRenderer.BuildAttachment(channels, messageTargetChannelId),
                    },
                },
            });
        }
示例#13
0
        /// <inheritdoc/>
        public async Task <IEnumerable <Channel> > GetChannelsAsync(TeamInfo teamInfo, ITurnContext turnContext, CancellationToken cancellationToken)
        {
            var teamChannels = await TeamsInfo.GetTeamChannelsAsync(turnContext, teamInfo.Id, cancellationToken);

            return(teamChannels.Select(channel => this.ConvertToChannelInternal(channel, teamInfo)));
        }