/// <summary>
        /// Handle an invoke activity.
        /// </summary>
        private async Task <HttpResponseMessage> HandleInvokeActivity(Activity activity)
        {
            var activityValue = activity.Value.ToString();

            switch (activity.Name)
            {
            case "signin/verifyState":
                await Conversation.SendAsync(activity, () => new RootDialog());

                break;

            case "composeExtension/query":
                // Handle fetching task module content
                using (var connector = new ConnectorClient(new Uri(activity.ServiceUrl)))
                {
                    var channelData = activity.GetChannelData <TeamsChannelData>();
                    var tid         = channelData.Tenant.Id;

                    string emailId = await RootDialog.GetUserEmailId(activity);

                    if (emailId == null)
                    {
                        return(new HttpResponseMessage(HttpStatusCode.OK));
                    }
                    var response = await MessageExtension.HandleMessageExtensionQuery(connector, activity, tid, emailId);

                    return(response != null
                            ? Request.CreateResponse(response)
                            : new HttpResponseMessage(HttpStatusCode.OK));
                }

            case "task/fetch":
                // Handle fetching task module content
                return(await HandleTaskModuleFetchRequest(activity, activityValue));

            case "task/submit":
                // Handle submission of task module info
                // Run this on a task so that
                new Task(async() =>
                {
                    var action    = JsonConvert.DeserializeObject <TaskModule.BotFrameworkCardValue <ActionDetails> >(activityValue);
                    activity.Name = action.Data.ActionType;
                    await Conversation.SendAsync(activity, () => new RootDialog());
                }).Start();

                await Task.Delay(TimeSpan.FromSeconds(2));    // Give it some time to start showing output.

                break;
            }
            return(new HttpResponseMessage(HttpStatusCode.Accepted));
        }
        private static async Task SendWelcomeMessageToAllMembers(Tenant tenant, Activity message, TeamsChannelData channelData, IEnumerable <TeamsChannelAccount> members)
        {
            var tid     = channelData.Tenant.Id;
            var emailId = await RootDialog.GetUserEmailId(message);

            var tenatInfo = await Cache.Tenants.GetItemAsync(tid);

            Role role = Common.GetUserRole(emailId, tenatInfo);
            var  card = CardHelper.GetWelcomeScreen(false, role);

            foreach (var member in members)
            {
                var userDetails = await Cache.Users.GetItemAsync(member.UserPrincipalName.ToLower());

                if (userDetails == null)
                {
                    userDetails = new User()
                    {
                        BotConversationId = member.Id,
                        Id   = member.UserPrincipalName.ToLower().Trim(),
                        Name = member.Name ?? member.GivenName
                    };
                    await Cache.Users.AddOrUpdateItemAsync(userDetails.Id, userDetails);

                    tenant.Users.Add(userDetails.Id);
                    await Cache.Tenants.AddOrUpdateItemAsync(tenant.Id, tenant);

                    if (tenant.IsAdminConsented)
                    {
                        if (tenant.Moderators.Contains(userDetails.Id))
                        {
                            await ProactiveMessageHelper.SendNotification(message.ServiceUrl, channelData.Tenant.Id, member.Id, null, card);
                        }
                        else
                        {
                            // Get User welcome card.
                            await ProactiveMessageHelper.SendNotification(message.ServiceUrl, channelData.Tenant.Id, member.Id,
                                                                          $"Welcome to {ApplicationSettings.AppName}. We will deliver company {ApplicationSettings.AppFeature}s here.", null);
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Handle messageReaction events, which indicate user liked/unliked a message sent by the bot.
        /// </summary>
        private static async Task HandleReactions(Activity message)
        {
            if (message.ReactionsAdded != null || message.ReactionsRemoved != null)
            {
                // Determine if likes were net added or removed
                var reactionToAdd = message.ReactionsAdded != null ? 1 : -1;
                var channelData   = message.GetChannelData <TeamsChannelData>();
                var replyToId     = message.ReplyToId;
                if (channelData.Team != null)
                {
                    replyToId = message.Conversation.Id;
                }

                // Look for the announcement that was liked/unliked, and update the reaction count on that announcement
                var tenant = await Cache.Tenants.GetItemAsync(channelData.Tenant.Id);

                bool messageFound = false;
                foreach (var announcementId in tenant.Announcements)
                {
                    var announcement = await Cache.Announcements.GetItemAsync(announcementId);

                    if (announcement?.Recipients == null)
                    {
                        continue;
                    }

                    if (channelData.Team == null)
                    {
                        foreach (var group in announcement.Recipients.Groups)
                        {
                            var user = group.Users.FirstOrDefault(u => u.MessageId == replyToId);
                            if (user != null)
                            {
                                messageFound   = true;
                                user.LikeCount = reactionToAdd == 1 ? 1 : 0;
                            }
                        }
                    }
                    if (!messageFound && channelData.Team != null)
                    {
                        foreach (var channel in announcement.Recipients.Channels)
                        {
                            //var user = channel.LikedUsers.FirstOrDefault(u => u.MessageId == replyToId);

                            if (channel.Channel.MessageId == replyToId)
                            {
                                var EmailId = await RootDialog.GetUserEmailId(message);

                                if (message.ReactionsAdded != null && message.ReactionsAdded.Count != 0)
                                {
                                    if (!channel.LikedUsers.Contains(EmailId))
                                    {
                                        channel.LikedUsers.Add(EmailId);
                                    }
                                }
                                else if (message.ReactionsRemoved != null)
                                {
                                    if (channel.LikedUsers.Contains(EmailId))
                                    {
                                        channel.LikedUsers.Remove(EmailId);
                                    }
                                }
                                // channel.Channel.LikeCount += reactionToAdd;
                                messageFound = true;
                                break;
                            }
                        }
                    }
                    if (messageFound)
                    {
                        await Cache.Announcements.AddOrUpdateItemAsync(announcement.Id, announcement);

                        break;
                    }
                }
            }
        }