/// <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 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}"); var fromAaDId = turnContext.Activity.From.AadObjectId; var from = teamsContext.AsTeamsChannelAccount(turnContext.Activity.From); List <ChannelAccount> teamMembers = (await turnContext.TurnState.Get <IConnectorClient>().Conversations.GetConversationMembersAsync( turnContext.Activity.GetChannelData <TeamsChannelData>().Team.Id).ConfigureAwait(false)).ToList(); var roster = teamsContext.GetConversationParametersForCreateOrGetDirectConversation(turnContext.Activity.From).Members; await turnContext.SendActivityAsync($"There are {roster.Count} people in this group. You are {from.Name} and your AAD Id is {fromAaDId}"); // 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> /// 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); } }