private async Task AdminNotifyPairs(ProactiveMessage proactiveMessage, MakePairsResult makePairsResult)
        {
            using (var connectorClient = new ConnectorClient(new Uri(proactiveMessage.ServiceUrl)))
            {
                string replyMessage = string.Empty;

                try
                {
                    var members = await connectorClient.Conversations.GetConversationMembersAsync(makePairsResult.TeamId);

                    var membersByChannelAccountId = members.ToDictionary(key => key.Id, value => value);

                    // Evaluate all values so we can fail early if someone no longer exists
                    var pairs = makePairsResult.PairChannelAccountIds.Select(pair => new Tuple <ChannelAccount, ChannelAccount>(
                                                                                 membersByChannelAccountId[pair.Item1],
                                                                                 membersByChannelAccountId[pair.Item2])).ToList();

                    var team = await this.bot.GetInstalledTeam(makePairsResult.TeamId);

                    var numUsersNotified = await this.bot.NotifyAllPairs(team, pairs);

                    replyMessage = string.Format(Resources.ManualNotifiedUsersMessage, numUsersNotified, pairs.Count * 2);
                }
                catch (Exception ex)
                {
                    replyMessage = Resources.ManualNotifiedUsersErrorMessage;
                    this.telemetryClient.TrackTrace($"Error while notifying pairs: {ex.Message}", SeverityLevel.Warning);
                    this.telemetryClient.TrackException(ex);
                }

                await proactiveMessage.Send(connectorClient, replyMessage);
            }
        }
        private async Task AdminMakePairs(ProactiveMessage proactiveMessage, string teamId, string teamName)
        {
            using (var connectorClient = new ConnectorClient(new Uri(proactiveMessage.ServiceUrl)))
            {
                var team = await this.bot.GetInstalledTeam(teamId);

                var matchResult = await this.bot.MakePairsForTeam(team);

                List <Attachment> attachments = null;
                string            replyText   = string.Empty;

                if (matchResult.Pairs.Any())
                {
                    attachments = new List <Attachment>
                    {
                        this.bot.CreateMatchAttachment(matchResult, team.Id, teamName)
                    };
                }
                else
                {
                    var numUsers = matchResult.OddPerson != null ? 1 : 0;
                    replyText = string.Format(Resources.NewPairingsNotEnoughUsers, numUsers);
                }

                await proactiveMessage.Send(connectorClient, replyText, attachments);
            }
        }
        private async Task HandleAdminMakePairs(string msgId, ConnectorClient connectorClient, Activity activity, string senderAadId)
        {
            this.telemetryClient.TrackTrace($"User {senderAadId} triggered make pairs");
            var teamContext      = ActivityHelper.ParseCardActionData <TeamContext>(activity);
            var proactiveMessage = new ProactiveMessage(activity);
            await connectorClient.Conversations.ReplyToActivityAsync(activity.CreateReply("Creating pairs..."));

            HostingEnvironment.QueueBackgroundWorkItem(ct => this.AdminMakePairs(proactiveMessage, teamContext.TeamId, teamContext.TeamName));
        }
        private async Task HandleAdminNotifyPairs(string msgId, ConnectorClient connectorClient, Activity activity, string senderAadId)
        {
            this.telemetryClient.TrackTrace($"User {senderAadId} triggered notify pairs");

            // The bot framework resends the message if we don't respond within a short period of time (roughly 5 seconds)
            // Sending notify messages to 12 users caused 4 notifypairs messages and it was resend 4 times.
            // So reply immediately and put the work on a background thread. Any further replies will be a proactive bot message.
            var proactiveMessage = new ProactiveMessage(activity);
            var makePairsResult  = ActivityHelper.ParseCardActionData <MakePairsResult>(activity);
            await connectorClient.Conversations.ReplyToActivityAsync(activity.CreateReply(Resources.ManualNotifyingUsersMessage));

            HostingEnvironment.QueueBackgroundWorkItem(ct => this.AdminNotifyPairs(proactiveMessage, makePairsResult));
        }