public async Task UseTagAsync(ITurnContext turnContext, string name) { //TODO: roles and authentication AuthorizationService.RequireClaims(AuthorizationClaim.UseTag); ITeamsContext teamsContext = turnContext.TurnState.Get <ITeamsContext>(); string teamId = teamsContext.Team.Id; string channelId = teamsContext.Channel.Id; if (string.IsNullOrWhiteSpace(name)) { throw new ArgumentException("The tag name cannot be blank or whitespace.", nameof(name)); } name = name.Trim().ToLower(); using (var transaction = await TagRepository.BeginUseTransactionAsync()) { var tag = await TagRepository.ReadSummaryAsync(teamId, name); if (tag is null) { throw new InvalidOperationException($"The tag '{name}' does not exist."); } await turnContext.SendActivityAsync(tag.Content); transaction.Commit(); } }
public async Task DeleteTagAsync(ITurnContext turnContext, string name) { ITeamsContext teamsContext = turnContext.TurnState.Get <ITeamsContext>(); string teamId = teamsContext.Team.Id; string deleterId = turnContext.Activity.From.Id; if (string.IsNullOrWhiteSpace(name)) { throw new ArgumentException("The tag name cannot be blank or whitespace.", nameof(name)); } name = name.Trim().ToLower(); using (var transaction = await TagRepository.BeginMaintainTransactionAsync()) { var tag = await TagRepository.ReadSummaryAsync(teamId, name); if (tag is null) { throw new InvalidOperationException($"The tag '{name}' does not exist."); } //await EnsureUserCanMaintainTagAsync(tag, deleterId); await TagRepository.TryDeleteAsync(teamId, name, deleterId); transaction.Commit(); } }
private async Task <InvokeResponse> ProcessTeamsInvokeActivityAsync(ITurnContext turnContext) { ITeamsContext teamsContext = turnContext.TurnState.Get <ITeamsContext>(); if (teamsContext.IsRequestMessagingExtensionQuery()) { return(await this.invokeActivityHandler.HandleMessagingExtensionActionAsync(new MessagingExtensionActivityAction { MessagingExtensionQuery = teamsContext.GetMessagingExtensionQueryData(), TurnContext = turnContext, }).ConfigureAwait(false)); } if (teamsContext.IsRequestO365ConnectorCardActionQuery()) { return(await this.invokeActivityHandler.HandleO365ConnectorCardActionAsync(new O365ConnectorCardActivityAction { CardActionQuery = teamsContext.GetO365ConnectorCardActionQueryData(), TurnContext = turnContext, }).ConfigureAwait(false)); } if (teamsContext.IsRequestSigninStateVerificationQuery()) { return(await this.invokeActivityHandler.HandleSigninStateVerificationActionAsync(new SigninStateVerificationActivityAction { TurnContext = turnContext, VerificationQuery = teamsContext.GetSigninStateVerificationQueryData(), }).ConfigureAwait(false)); } return(await this.invokeActivityHandler.HandleInvokeTaskAsync(turnContext).ConfigureAwait(false)); }
/// <summary> /// Handles the team members removed event asynchronously. /// </summary> /// <param name="teamMembersRemovedEvent">The team members removed event.</param> /// <returns> /// Task tracking operation. /// </returns> public async Task HandleTeamMembersRemovedEventAsync(TeamMembersRemovedEvent teamMembersRemovedEvent) { TeamOperationHistory conversationHistory = await this.teamHistoryAccessor.AuditLog.GetAsync(teamMembersRemovedEvent.TurnContext, () => new TeamOperationHistory()).ConfigureAwait(false); foreach (ChannelAccount memberRemoved in teamMembersRemovedEvent.MembersRemoved) { ITeamsContext teamsContext = teamMembersRemovedEvent.TurnContext.TurnState.Get <ITeamsContext>(); TeamsChannelAccount teamsChannelAccount = teamsContext.AsTeamsChannelAccount(memberRemoved); if (conversationHistory.MemberOperations == null) { conversationHistory.MemberOperations = new List <OperationDetails>(); } conversationHistory.MemberOperations.Add(new OperationDetails { ObjectId = teamsChannelAccount.AadObjectId, Operation = "MemberRemoved", OperationTime = DateTimeOffset.Now, }); } await this.teamHistoryAccessor.AuditLog.SetAsync(teamMembersRemovedEvent.TurnContext, conversationHistory).ConfigureAwait(false); await this.teamHistoryAccessor.ConversationState.SaveChangesAsync(teamMembersRemovedEvent.TurnContext).ConfigureAwait(false); }
/// <summary> /// Every Conversation turn for our EchoBot will call this method. In here /// the bot checks the Activty type to verify it's a message, bumps the /// turn conversation 'Turn' count, and then echoes the users typing /// back to them. /// </summary> /// <param name="context">Turn scoped context containing all the data needed /// for processing this conversation turn. </param> /// <param name="cancellationToken">Cancellation token.</param> /// <returns>Task tracking operation.</returns> public async Task OnTurnAsync(ITurnContext context, CancellationToken cancellationToken = default(CancellationToken)) { // This bot is only handling Messages if (context.Activity.Type == ActivityTypes.Message) { try { // --> Get Teams Extensions. ITeamsContext teamsContext = context.TurnState.Get <ITeamsContext>(); EchoState state = await this.echoStateAccessor.CounterState.GetAsync(context, () => new EchoState()).ConfigureAwait(false); state.TurnCount++; await this.echoStateAccessor.CounterState.SetAsync(context, state).ConfigureAwait(false); await this.echoStateAccessor.ConversationState.SaveChangesAsync(context).ConfigureAwait(false); string suffixMessage = $"from tenant Id {teamsContext.Tenant.Id}"; // Echo back to the user whatever they typed. await context.SendActivityAsync($"Turn {state.TurnCount}: You sent '{context.Activity.Text}' {suffixMessage}").ConfigureAwait(false); } catch (Exception) { } } }
private async Task <InvokeResponse> ProcessTeamsInvokeActivityAsync(ITurnContext turnContext) { ITeamsContext teamsContext = turnContext.TurnState.Get <ITeamsContext>(); if (teamsContext.IsRequestO365ConnectorCardActionQuery()) { return(await this.invokeActivityHandler.HandleO365ConnectorCardActionAsync(turnContext, teamsContext.GetO365ConnectorCardActionQueryData()).ConfigureAwait(false)); } if (teamsContext.IsRequestSigninStateVerificationQuery()) { return(await this.invokeActivityHandler.HandleSigninStateVerificationActionAsync(turnContext, teamsContext.GetSigninStateVerificationQueryData()).ConfigureAwait(false)); } if (teamsContext.IsRequestFileConsentResponse()) { return(await this.invokeActivityHandler.HandleFileConsentResponseAsync(turnContext, teamsContext.GetFileConsentQueryData()).ConfigureAwait(false)); } if (teamsContext.IsRequestMessagingExtensionQuery()) { return(await this.invokeActivityHandler.HandleMessagingExtensionQueryAsync(turnContext, teamsContext.GetMessagingExtensionQueryData()).ConfigureAwait(false)); } if (teamsContext.IsRequestAppBasedLinkQuery()) { return(await this.invokeActivityHandler.HandleAppBasedLinkQueryAsync(turnContext, teamsContext.GetAppBasedLinkQueryData()).ConfigureAwait(false)); } if (teamsContext.IsRequestMessagingExtensionFetchTask()) { return(await this.invokeActivityHandler.HandleMessagingExtensionFetchTaskAsync(turnContext, teamsContext.GetMessagingExtensionActionData()).ConfigureAwait(false)); } if (teamsContext.IsRequestMessagingExtensionSubmitAction()) { return(await this.invokeActivityHandler.HandleMessagingExtensionSubmitActionAsync(turnContext, teamsContext.GetMessagingExtensionActionData()).ConfigureAwait(false)); } if (teamsContext.IsRequestTaskModuleFetch()) { return(await this.invokeActivityHandler.HandleTaskModuleFetchAsync(turnContext, teamsContext.GetTaskModuleRequestData()).ConfigureAwait(false)); } if (teamsContext.IsRequestTaskModuleSubmit()) { return(await this.invokeActivityHandler.HandleTaskModuleSubmitAsync(turnContext, teamsContext.GetTaskModuleRequestData()).ConfigureAwait(false)); } return(await this.invokeActivityHandler.HandleInvokeTaskAsync(turnContext).ConfigureAwait(false)); }
public async Task ListAllAsync() { ITeamsContext teamsContext = Context.TurnState.Get <ITeamsContext>(); var tags = await TagService.GetSummariesAsync(new TagSearchCriteria() { TeamId = teamsContext.Team.Id, }); //TODO Add embeds var embed = await BuildEmbedAsync(tags, ownerGuild: Context.Guild); await ReplyAsync("coming soon"); //await ReplyAsync(embed); }
/// <summary> /// Runs the test pipeline with activity asynchronously. /// </summary> /// <param name="activity">The activity.</param> /// <param name="callback">The callback.</param> /// <returns>Task tracking operation.</returns> internal static async Task RunTestPipelineWithActivityAsync(Activity activity, Func <ITeamsContext, Task> callback) { Mock <ICredentialProvider> mockCredentialProvider = new Mock <ICredentialProvider>(); TestAdapter testAdapter = new TestAdapter(new ConversationReference(activity.Id, activity.From, activity.Recipient, activity.Conversation, activity.ChannelId, activity.ServiceUrl)); testAdapter.Use(new TeamsMiddleware(mockCredentialProvider.Object)); await testAdapter.ProcessActivityAsync( activity, async (turnContext, cancellationToken) => { ITeamsContext teamsContext = turnContext.TurnState.Get <ITeamsContext>(); await callback(teamsContext).ConfigureAwait(false); }).ConfigureAwait(false); }
/// <summary> /// Handles the message activity asynchronously. /// </summary> /// <param name="turnContext">The turn context.</param> /// <returns>Task tracking operation.</returns> public async Task HandleMessageAsync(ITurnContext turnContext) { ITeamsContext teamsContext = turnContext.TurnState.Get <ITeamsContext>(); string actualText = teamsContext.GetActivityTextWithoutMentions(); if (actualText.Equals("Cards", StringComparison.OrdinalIgnoreCase)) { // Demo card 1 - adaptive card with bot bulder actions AdaptiveCards.AdaptiveCard adaptiveCard = new AdaptiveCards.AdaptiveCard(); adaptiveCard.Body.Add(new AdaptiveCards.AdaptiveTextBlock("Bot Builder actions")); var action1 = new CardAction("imback", "imBack", null, null, null, "text"); var action2 = new CardAction("messageBack", "message back", null, "text received by bots", "text display to users", JObject.Parse(@"{ ""key"" : ""value"" }")); var action3 = new CardAction("invoke", "invoke", null, null, null, JObject.Parse(@"{ ""key"" : ""value"" }")); adaptiveCard.Actions.Add(action1.ToAdaptiveCardAction()); adaptiveCard.Actions.Add(action2.ToAdaptiveCardAction()); adaptiveCard.Actions.Add(action3.ToAdaptiveCardAction()); // Task module action var taskModuleAction = new TaskModuleAction("Launch Task Module", @"{ ""hiddenKey"": ""hidden value from task module launcher"" }"); // Demo card 2 - launch task module from adaptive card AdaptiveCards.AdaptiveCard taskModuleCard1 = new AdaptiveCards.AdaptiveCard(); taskModuleCard1.Body.Add(new AdaptiveCards.AdaptiveTextBlock("Task Module Adaptive Card")); taskModuleCard1.Actions.Add(taskModuleAction.ToAdaptiveCardAction()); // Demo card 3 - launch task module from hero card (or any bot-builder framework card) HeroCard taskModuleCard2 = new HeroCard("Launch Task Module", null, null, null, new List <CardAction> { taskModuleAction }); Activity replyActivity = turnContext.Activity.CreateReply(); replyActivity.Attachments = new List <Attachment>() { adaptiveCard.ToAttachment(), taskModuleCard1.ToAttachment(), taskModuleCard2.ToAttachment(), }; await turnContext.SendActivityAsync(replyActivity).ConfigureAwait(false); } else { Activity replyActivity = turnContext.Activity.CreateReply(); replyActivity.TextFormat = "xml"; replyActivity.Text = $"You said: {turnContext.Activity.Text}"; await turnContext.SendActivityAsync(replyActivity).ConfigureAwait(false); } }
public async Task OnTurnAsync(ITurnContext turnCtx, CancellationToken cancellationToken) { try { if (turnCtx.Activity != null && turnCtx.Activity.Type != null && turnCtx.Activity.Type == ActivityTypes.Invoke) { ITeamsContext teamsContext = turnCtx.TurnState.Get <ITeamsContext>(); MessagingExtensionQuery meQuery = null; if (teamsContext.IsRequestMessagingExtensionQuery()) { meQuery = teamsContext.GetMessagingExtensionQueryData(); } InvokeResponse ir = new InvokeResponse { Body = new MessagingExtensionResponse { ComposeExtension = await searchHandler.GetSearchResultAsync(meQuery.Parameters[0].Value.ToString()) }, Status = 200, }; await turnCtx.SendActivityAsync( new Activity { Value = ir, Type = ActivityTypesEx.InvokeResponse, }).ConfigureAwait(false); } else { await turnCtx.SendActivityAsync(string.Format("Sorry! As of now I'm only support an invoke command, but you're trying to execute {0}", (turnCtx.Activity != null && turnCtx.Activity.Type != null) ? turnCtx.Activity.Type.ToString() : "empty activity")); } } catch (Exception ex) { await turnCtx.SendActivityAsync($"Oppps, seems like an error: {ex.InnerException}. Try again or contact your IT admin"); } }
public async Task CreateTagAsync(ITurnContext turnContext, string name, string content) { ITeamsContext teamsContext = turnContext.TurnState.Get <ITeamsContext>(); string teamId = teamsContext.Team.Id; string creatorId = turnContext.Activity.From.Id; if (string.IsNullOrWhiteSpace(name)) { throw new ArgumentException("The tag name cannot be blank or whitespace.", nameof(name)); } if (string.IsNullOrWhiteSpace(content)) { throw new ArgumentException("The tag content cannot be blank or whitespace.", nameof(content)); } name = name.Trim().ToLower(); using (var transaction = await TagRepository.BeginMaintainTransactionAsync()) { var existingTag = await TagRepository.ReadSummaryAsync(teamId, name); if (!(existingTag is null)) { throw new InvalidOperationException($"A tag with the name '{name}' already exists."); } await TagRepository.CreateAsync(new TagCreationData() { TeamId = teamId, CreatedById = creatorId, Name = name, Content = content, }); transaction.Commit(); await turnContext.SendActivityAsync("Tag created succesfully"); } }
/// <summary> /// Every conversation turn for our Echo Bot will call this method. /// There are no dialogs used, since it's "single turn" processing, meaning a single /// request and response. /// </summary> /// <param name="turnContext">A <see cref="ITurnContext"/> containing all the data needed /// for processing this conversation turn. </param> /// <param name="cancellationToken">(Optional) A <see cref="CancellationToken"/> that can be used by other objects /// or threads to receive notice of cancellation.</param> /// <returns>A <see cref="Task"/> that represents the work queued to execute.</returns> public async Task OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken = default(CancellationToken)) { // Handle Message activity type, which is the main activity type for shown within a conversational interface // Message activities may contain text, speech, interactive cards, and binary or unknown attachments. // see https://aka.ms/about-bot-activity-message to learn more about the message and other activity types if (turnContext.Activity.Type == ActivityTypes.Message) { // Before doing Teams specific stuff, get hold of the TeamsContext ITeamsContext teamsContext = turnContext.TurnState.Get <ITeamsContext>(); // Now fetch the Team ID, Channel ID, and Tenant ID off of the incoming activity string incomingTeamId = teamsContext.Team.Id; string incomingChannelid = teamsContext.Channel.Id; string incomingTenantId = teamsContext.Tenant.Id; // Make an operation call to fetch the list of channels in the team, and print count of channels. ConversationList channels = await teamsContext.Operations.FetchChannelListAsync(incomingTeamId); await turnContext.SendActivityAsync($"You have {channels.Conversations.Count} channels in this team"); // Make an operation call to fetch details of the team where the activity was posted, and print it. TeamDetails teamInfo = await teamsContext.Operations.FetchTeamDetailsAsync(incomingTeamId); await turnContext.SendActivityAsync($"Name of this team is {teamInfo.Name} and group-id is {teamInfo.AadGroupId}"); // Get the conversation state from the turn context. CounterState state = await _accessors.CounterState.GetAsync(turnContext, () => new CounterState()); // Bump the turn count for this conversation. state.TurnCount++; // Set the property using the accessor. await _accessors.CounterState.SetAsync(turnContext, state); // Save the new turn count into the conversation state. await _accessors.ConversationState.SaveChangesAsync(turnContext); // Echo back to the user whatever they typed. string responseMessage = $"Turn {state.TurnCount}: You sent '{turnContext.Activity.Text}'. Toodles!\n"; await turnContext.SendActivityAsync(responseMessage); } else if (turnContext.Activity.Type == ActivityTypes.Invoke) { try { MessagingExtensionResult composeExtensionResult = new MessagingExtensionResult { Type = "result", AttachmentLayout = "list", Attachments = new List <MessagingExtensionAttachment>(), }; ThumbnailCard card = new ThumbnailCard { Title = "I'm a thumbnail", Text = "Normally I'd be way more useful.", Images = new CardImage[] { new CardImage("http://web.hku.hk/~jmwchiu/cats/cat10.jpg") }, }; composeExtensionResult.Attachments.Add(card.ToAttachment().ToMessagingExtensionAttachment()); InvokeResponse ir = new InvokeResponse { Body = new MessagingExtensionResponse { ComposeExtension = composeExtensionResult }, Status = 200, }; await turnContext.SendActivityAsync(new Activity { Value = ir, Type = ActivityTypesEx.InvokeResponse, }); } catch (Exception ex) { await turnContext.SendActivityAsync($"oops: {ex.InnerException}"); } } else { await turnContext.SendActivityAsync($"{turnContext.Activity.Type} event detected"); } }
/// <summary> /// Every conversation turn for our Echo Bot will call this method. /// There are no dialogs used, since it's "single turn" processing, meaning a single /// request and response. /// </summary> /// <param name="turnContext">A <see cref="ITurnContext"/> containing all the data needed /// for processing this conversation turn. </param> /// <param name="cancellationToken">(Optional) A <see cref="CancellationToken"/> that can be used by other objects /// or threads to receive notice of cancellation.</param> /// <returns>A <see cref="Task"/> that represents the work queued to execute.</returns> /// <seealso cref="BotStateSet"/> /// <seealso cref="ConversationState"/> /// <seealso cref="IMiddleware"/> public async Task OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken = default(CancellationToken)) { DialogContext dc = null; ITeamsContext teamsContext = turnContext.TurnState.Get <ITeamsContext>(); var asdd = turnContext.Activity.ChannelData; if (teamsContext != null) { // Now fetch the Team ID, Channel ID, and Tenant ID off of the incoming activity var incomingTeamId = teamsContext.Team.Id; var incomingChannelid = teamsContext.Channel.Id; var incomingTenantId = teamsContext.Tenant.Id; SigninStateVerificationQuery asd = teamsContext.GetSigninStateVerificationQueryData(); // Make an operation call to fetch the list of channels in the team, and print count of channels. var channels = await teamsContext.Operations.FetchChannelListAsync(incomingTeamId, cancellationToken : cancellationToken); await turnContext.SendActivityAsync($"You have {channels.Conversations.Count} channels in this team"); // Make an operation call to fetch details of the team where the activity was posted, and print it. var teamInfo = await teamsContext.Operations.FetchTeamDetailsAsync(incomingTeamId); await turnContext.SendActivityAsync($"Name of this team is {teamInfo.Name} and group-id is {teamInfo.AadGroupId}"); } if (turnContext.Activity.Type == ActivityTypes.Message) { dc = await _dialogs.CreateContextAsync(turnContext, cancellationToken); // Get the state properties from the turn context. Usuario userProfile = await _accessors.UserProfile.GetAsync(turnContext, () => new Usuario()); if (userProfile.EsperaRespuestaQNA || turnContext.Activity.Text.ToLower() == "ayuda") { var recognizerResult = await botServices.LuisServices["DispatchPepe"].RecognizeAsync(turnContext, cancellationToken); var topIntent = recognizerResult?.GetTopScoringIntent(); await DispatchToTopIntentAsync(turnContext, dc, topIntent, cancellationToken); } // Continue any current dialog. DialogTurnResult dialogTurnResult = await dc.ContinueDialogAsync(); if (dialogTurnResult.Status == DialogTurnStatus.Empty) //if (dialogTurnResult.Result is null) { // Get the intent recognition result var recognizerResult = await botServices.LuisServices["DispatchPepe"].RecognizeAsync(turnContext, cancellationToken); var topIntent = recognizerResult?.GetTopScoringIntent(); if (topIntent == null) { await turnContext.SendActivityAsync("Unable to get the top intent."); } else { await DispatchToTopIntentAsync(turnContext, dc, topIntent, cancellationToken); } } else if (dialogTurnResult.Status == DialogTurnStatus.Complete) { await dc.BeginDialogAsync("SendWelcomeMessage", cancellationToken); } //COMBINAR CON ESTO // //await ProcessInputAsync(turnContext, cancellationToken); } else if (turnContext.Activity.Type == ActivityTypes.Invoke || turnContext.Activity.Type == ActivityTypes.Event) { // This handles the Microsoft Teams Invoke Activity sent when magic code is not used. // See: https://docs.microsoft.com/en-us/microsoftteams/platform/concepts/authentication/auth-oauth-card#getting-started-with-oauthcard-in-teams // Manifest Schema Here: https://docs.microsoft.com/en-us/microsoftteams/platform/resources/schema/manifest-schema // It also handles the Event Activity sent from The Emulator when the magic code is not used. // See: https://blog.botframework.com/2018/08/28/testing-authentication-to-your-bot-using-the-bot-framework-emulator/ // Sanity check the activity type and channel Id. if (turnContext.Activity.Type == ActivityTypes.Invoke && turnContext.Activity.ChannelId != "msteams") { throw new InvalidOperationException("The Invoke type is only valid onthe MSTeams channel."); } dc = await _dialogs.CreateContextAsync(turnContext, cancellationToken); await dc.ContinueDialogAsync(cancellationToken); if (!turnContext.Responded) { await dc.BeginDialogAsync(OutlookDialogID); } } else if (turnContext.Activity.Type == ActivityTypes.ConversationUpdate) { // Send a welcome message to the user and tell them what actions they may perform to use this bot if (turnContext.Activity.MembersAdded != null) { dc = await _dialogs.CreateContextAsync(turnContext, cancellationToken); //await dc.BeginDialogAsync("SendWelcomeMessageAsync"); var reply = turnContext.Activity.CreateReply(); reply.Type = ActivityTypes.Typing; await dc.Context.SendActivityAsync(reply); if (turnContext.Activity.MembersAdded != null) { foreach (var member in turnContext.Activity.MembersAdded) { if (member.Id != turnContext.Activity.Recipient.Id) { this.nuevaConversacion = true; //await SendWelcomeMessageAsync(turnContext, cancellationToken, true); await dc.BeginDialogAsync("SendWelcomeMessage"); } } } } } else if (turnContext.Activity.Type == ActivityTypes.DeleteUserData) { string idChannel = turnContext.Activity.ChannelId; string idChannelx = turnContext.Activity.Conversation.AadObjectId; string idChannelxd = turnContext.Activity.MembersAdded.First().Id; await _accessors.UserState.DeleteAsync(turnContext, cancellationToken); await _accessors.ConversationState.DeleteAsync(turnContext, cancellationToken); //context.Reset(); //context.ConversationData.Clear(); //context.UserData.Clear(); //context.PrivateConversationData.Clear(); //await context.FlushAsync(CancellationToken.None); } else if (turnContext.Activity.Type == ActivityTypes.Typing) { } else if (turnContext.Activity.Type == ActivityTypes.Handoff) { } else if (turnContext.Activity.Type == ActivityTypes.Trace) { } else if (turnContext.Activity.Type == ActivityTypes.Suggestion) { } //else if (turnContext.Activity.Type == ActivityTypes.) //{ //} // Save the new turn count into the conversation state. await _accessors.UserState.SaveChangesAsync(turnContext, false, cancellationToken); await _accessors.ConversationState.SaveChangesAsync(turnContext, false, cancellationToken); }
/// <summary> /// Handles the message activity asynchronously. /// </summary> /// <param name="turnContext">The turn context.</param> /// <returns> /// Task tracking operation. /// </returns> public async Task HandleMessageAsync(ITurnContext turnContext) { ITeamsContext teamsContext = turnContext.TurnState.Get <ITeamsContext>(); string actualText = teamsContext.GetActivityTextWithoutMentions(); if (actualText.Equals("ShowHistory", StringComparison.OrdinalIgnoreCase) || actualText.Equals("Show History", StringComparison.OrdinalIgnoreCase)) { TeamOperationHistory memberHistory = await this.teamHistoryAccessor.AuditLog.GetAsync(turnContext, () => new TeamOperationHistory()).ConfigureAwait(false); Activity replyActivity = turnContext.Activity.CreateReply(); teamsContext.AddMentionToText(replyActivity, turnContext.Activity.From); replyActivity.Text = replyActivity.Text + $" Total of {memberHistory.MemberOperations.Count} operations were performed"; await turnContext.SendActivityAsync(replyActivity).ConfigureAwait(false); // Going in reverse chronological order. for (int i = memberHistory.MemberOperations.Count % 10; i >= 0; i--) { List <OperationDetails> elementsToSend = memberHistory.MemberOperations.Skip(10 * i).Take(10).ToList(); StringBuilder stringBuilder = new StringBuilder(); if (elementsToSend.Count > 0) { for (int j = elementsToSend.Count - 1; j >= 0; j--) { stringBuilder.Append($"{elementsToSend[j].ObjectId} --> {elementsToSend[j].Operation} --> {elementsToSend[j].OperationTime} </br>"); } Activity memberListActivity = turnContext.Activity.CreateReply(stringBuilder.ToString()); await turnContext.SendActivityAsync(memberListActivity).ConfigureAwait(false); } } } else if (actualText.Equals("ShowCurrentMembers", StringComparison.OrdinalIgnoreCase) || actualText.Equals("Show Current Members", StringComparison.OrdinalIgnoreCase)) { List <ChannelAccount> teamMembers = (await turnContext.TurnState.Get <IConnectorClient>().Conversations.GetConversationMembersAsync( turnContext.Activity.GetChannelData <TeamsChannelData>().Team.Id).ConfigureAwait(false)).ToList(); Activity replyActivity = turnContext.Activity.CreateReply(); teamsContext.AddMentionToText(replyActivity, turnContext.Activity.From); replyActivity.Text = replyActivity.Text + $" Total of {teamMembers.Count} members are currently in team"; await turnContext.SendActivityAsync(replyActivity).ConfigureAwait(false); for (int i = teamMembers.Count % 10; i >= 0; i--) { List <TeamsChannelAccount> elementsToSend = teamMembers.Skip(10 * i).Take(10).ToList().ConvertAll <TeamsChannelAccount>((account) => teamsContext.AsTeamsChannelAccount(account)); StringBuilder stringBuilder = new StringBuilder(); if (elementsToSend.Count > 0) { for (int j = elementsToSend.Count - 1; j >= 0; j--) { stringBuilder.Append($"{elementsToSend[j].AadObjectId} --> {elementsToSend[j].Name} --> {elementsToSend[j].UserPrincipalName} </br>"); } Activity memberListActivity = turnContext.Activity.CreateReply(stringBuilder.ToString()); await turnContext.SendActivityAsync(memberListActivity).ConfigureAwait(false); } } } else if (actualText.Equals("ShowChannelList", StringComparison.OrdinalIgnoreCase) || actualText.Equals("Show Channels", StringComparison.OrdinalIgnoreCase) || actualText.Equals("ShowChannels", StringComparison.OrdinalIgnoreCase) || actualText.Equals("Show Channel List", StringComparison.OrdinalIgnoreCase)) { ConversationList channelList = await teamsContext.Operations.FetchChannelListAsync(turnContext.Activity.GetChannelData <TeamsChannelData>().Team.Id).ConfigureAwait(false); Activity replyActivity = turnContext.Activity.CreateReply(); teamsContext.AddMentionToText(replyActivity, turnContext.Activity.From); replyActivity.Text = replyActivity.Text + $" Total of {channelList.Conversations.Count} channels are currently in team"; await turnContext.SendActivityAsync(replyActivity).ConfigureAwait(false); for (int i = channelList.Conversations.Count % 10; i >= 0; i--) { List <ChannelInfo> elementsToSend = channelList.Conversations.Skip(10 * i).Take(10).ToList(); StringBuilder stringBuilder = new StringBuilder(); if (elementsToSend.Count > 0) { for (int j = elementsToSend.Count - 1; j >= 0; j--) { stringBuilder.Append($"{elementsToSend[j].Id} --> {elementsToSend[j].Name}</br>"); } Activity memberListActivity = turnContext.Activity.CreateReply(stringBuilder.ToString()); await turnContext.SendActivityAsync(memberListActivity).ConfigureAwait(false); } } } else { await turnContext.SendActivityAsync("Invalid command").ConfigureAwait(false); } }