Пример #1
0
        protected override async Task <MessagingExtensionActionResponse> OnTeamsMessagingExtensionFetchTaskAsync(ITurnContext <IInvokeActivity> turnContext, MessagingExtensionQuery query, CancellationToken cancellationToken)
        {
            var reply = MessageFactory.Text("OnTeamsMessagingExtensionFetchTaskAsync MessagingExtensionQuery: " + JsonConvert.SerializeObject(query));
            await turnContext.SendActivityAsync(reply, cancellationToken);

            var tokenProvider = turnContext.Adapter as IUserTokenProvider;
            var tokenStatus   = await tokenProvider.GetTokenStatusAsync(turnContext, turnContext.Activity.From.Id, cancellationToken : cancellationToken);

            if (!tokenStatus.Any(t => t.HasToken == true))
            {
                var signInLink = await(turnContext.Adapter as IUserTokenProvider).GetOauthSignInLinkAsync(turnContext, "aadv2", cancellationToken).ConfigureAwait(false);

                return(new MessagingExtensionActionResponse
                {
                    ComposeExtension = new MessagingExtensionResult
                    {
                        Type = "auth",
                        SuggestedActions = new MessagingExtensionSuggestedAction()
                        {
                            Actions = new List <CardAction>
                            {
                                new CardAction
                                {
                                    Type = ActionTypes.OpenUrl,
                                    Value = signInLink,
                                },
                            },
                        },
                    },
                });
            }

            return(AdaptiveCardHelper.CreateTaskModuleAdaptiveCardResponse());
        }
Пример #2
0
        /// <inheritdoc/>
        public void BuildAdaptiveCardGroupReply <T>(Activity reply, BotResponse response, string cardPath, string attachmentLayout, List <T> cardDataAdapters, StringDictionary tokens = null)
            where T : CardDataBase
        {
            var tokensCopy     = CopyTokens(tokens);
            var parsedResponse = this.ParseResponse(response, tokensCopy);
            var parsedCards    = this.ParseAndCreateCards(cardPath, cardDataAdapters, tokensCopy, parsedResponse);

            this.PopulateReplyFromResponse(reply, response);

            if (cardDataAdapters.Count > 1)
            {
                reply.AttachmentLayout = attachmentLayout;
            }

            foreach (var card in parsedCards)
            {
                reply.Attachments.Add(AdaptiveCardHelper.CreateCardAttachment(card));
            }

            if (response.SuggestedActions?.Length > 0)
            {
                reply.SuggestedActions = new SuggestedActions(
                    actions: response.SuggestedActions.Select(choice =>
                                                              new CardAction(
                                                                  ActionTypes.ImBack,
                                                                  choice,
                                                                  value: choice.ToLower(),
                                                                  displayText: choice.ToLower(),
                                                                  text: choice.ToLower())).ToList());
            }
        }
Пример #3
0
        protected override async Task <MessagingExtensionActionResponse> OnTeamsMessagingExtensionFetchTaskAsync(ITurnContext <IInvokeActivity> turnContext, MessagingExtensionQuery query, CancellationToken cancellationToken)
        {
            var reply = MessageFactory.Text("OnTeamsMessagingExtensionFetchTaskAsync MessagingExtensionQuery: " + JsonConvert.SerializeObject(query));
            await turnContext.SendActivityAsync(reply, cancellationToken);

            return(AdaptiveCardHelper.CreateTaskModuleAdaptiveCardResponse());
        }
        protected override Task <MessagingExtensionActionResponse> OnTeamsMessagingExtensionBotMessagePreviewEditAsync(ITurnContext <IInvokeActivity> turnContext, MessagingExtensionAction action, CancellationToken cancellationToken)
        {
            // The data has been returned to the bot in the action structure.
            var activityPreview   = action.BotActivityPreview[0];
            var attachmentContent = activityPreview.Attachments[0].Content;
            var previewedCard     = JsonConvert.DeserializeObject <AdaptiveCard>(attachmentContent.ToString(), new JsonSerializerSettings {
                NullValueHandling = NullValueHandling.Ignore
            });
            var exampleData = AdaptiveCardHelper.CreateExampleData(previewedCard);

            // This is a preview edit call and so this time we want to re-create the adaptive card editor.
            var adaptiveCardEditor = AdaptiveCardHelper.CreateAdaptiveCardEditor(exampleData);

            return(Task.FromResult(new MessagingExtensionActionResponse
            {
                Task = new TaskModuleContinueResponse
                {
                    Value = new TaskModuleTaskInfo
                    {
                        Card = new Attachment
                        {
                            Content = adaptiveCardEditor,
                            ContentType = AdaptiveCard.ContentType,
                        },
                        Height = 450,
                        Width = 500,
                        Title = "Task Module Fetch Example",
                    },
                },
            }));
        }
Пример #5
0
        /// <inheritdoc/>
        public void BuildAdaptiveCardReply <T>(Activity reply, BotResponse response, string cardPath, T cardDataAdapter, StringDictionary tokens = null)
            where T : CardDataBase
        {
            var tokensCopy     = CopyTokens(tokens);
            var parsedResponse = this.ParseResponse(response, tokensCopy);
            var parsedCards    = this.ParseAndCreateCards(cardPath, new List <T> {
                cardDataAdapter
            }, tokensCopy, parsedResponse);

            this.PopulateReplyFromResponse(reply, response);

            if (reply.Attachments == null)
            {
                reply.Attachments = new List <Attachment>();
            }

            reply.Attachments.Add(AdaptiveCardHelper.CreateCardAttachment(parsedCards[0]));

            if (response.SuggestedActions?.Length > 0)
            {
                reply.SuggestedActions = new SuggestedActions(
                    actions: response.SuggestedActions.Select(choice =>
                                                              new CardAction(
                                                                  ActionTypes.ImBack,
                                                                  choice,
                                                                  value: choice.ToLower(),
                                                                  displayText: choice.ToLower(),
                                                                  text: choice.ToLower())).ToList());
            }
        }
        // Helper function for building the TaskInfo object based on the incoming request
        private static Models.TaskInfo GetTaskInfo(string actionInfo)
        {
            Models.TaskInfo taskInfo = new Models.TaskInfo();
            switch (actionInfo)
            {
            case TaskModuleIds.YouTube:
                taskInfo.Url = taskInfo.FallbackUrl = ApplicationSettings.BaseUrl + "/" + TaskModuleIds.YouTube;
                SetTaskInfo(taskInfo, TaskModuleUIConstants.YouTube);
                break;

            case TaskModuleIds.MsStream:
                taskInfo.Url = taskInfo.FallbackUrl = ApplicationSettings.BaseUrl + "/" + TaskModuleIds.MsStream;
                SetTaskInfo(taskInfo, TaskModuleUIConstants.MsStream);
                break;

            case TaskModuleIds.PowerApp:
                taskInfo.Url = taskInfo.FallbackUrl = ApplicationSettings.BaseUrl + "/" + TaskModuleIds.PowerApp;
                SetTaskInfo(taskInfo, TaskModuleUIConstants.PowerApp);
                break;

            case TaskModuleIds.CustomForm:
                taskInfo.Url = taskInfo.FallbackUrl = ApplicationSettings.BaseUrl + "/" + TaskModuleIds.CustomForm;
                SetTaskInfo(taskInfo, TaskModuleUIConstants.CustomForm);
                break;

            case TaskModuleIds.AdaptiveCard:
                taskInfo.Card = AdaptiveCardHelper.GetAdaptiveCard();
                SetTaskInfo(taskInfo, TaskModuleUIConstants.AdaptiveCard);
                break;

            default:
                break;
            }
            return(taskInfo);
        }
        protected override async Task <MessagingExtensionActionResponse> OnTeamsMessagingExtensionBotMessagePreviewSendAsync(ITurnContext <IInvokeActivity> turnContext, MessagingExtensionAction action, CancellationToken cancellationToken)
        {
            // The data has been returned to the bot in the action structure.
            var activityPreview   = action.BotActivityPreview[0];
            var attachmentContent = activityPreview.Attachments[0].Content;
            var previewedCard     = JsonConvert.DeserializeObject <AdaptiveCard>(attachmentContent.ToString(), new JsonSerializerSettings {
                NullValueHandling = NullValueHandling.Ignore
            });

            var exampleData = AdaptiveCardHelper.CreateExampleData(previewedCard);

            // This is a send so we are done and we will create the adaptive card editor.
            var adaptiveCard = AdaptiveCardHelper.CreateAdaptiveCard(exampleData);

            var message = MessageFactory.Attachment(new Attachment {
                ContentType = AdaptiveCard.ContentType, Content = adaptiveCard
            });

            // THIS WILL WORK IF THE BOT IS INSTALLED. (GetMembers() will NOT throw if the bot is installed.)
            // (The application should fail gracefully.)
            var channelId = turnContext.Activity.TeamsGetChannelId();

            //await turnContext.TeamsCreateConversationAsync(channelId, message, cancellationToken);

            return(null);
        }
Пример #8
0
        public void Test_GetCardFromJson()
        {
            List <string> testData = new List <string>();

            // 1# case with \r\n
            testData.Add("Hello \r\n\r\nYour agenda for Tuesday, November 13, 2018\r\n\r\n\r\nMulti-day\r\nEnds Wed 11/21\r\n\r\n\r\n\r\n\r\n\r\n\r\nvacation\r\n\r\n\r\n\r\n\r\n\r\n\r\nAgenda mail settings\r\nUnsubscribe • Privacy statement\r\nMicrosoft Corporation, One Microsoft Way, Redmond, WA 98052");
            // 2# case with "
            testData.Add("\"");
            // 3# case with '
            testData.Add("\'");
            // 4# case with \
            testData.Add("2\\3");
            // 5# case with \\
            testData.Add("\\\\");
            // 6# case with /
            testData.Add("/");
            // 7# case with \b
            testData.Add("\b");
            // 8# case with \f
            testData.Add("\f");
            // 9# case with \n
            testData.Add("\n");
            // 10# case with \r
            testData.Add("\r");
            // 11# case with \t
            testData.Add("\t");

            foreach (var testContent in testData)
            {
                var card = AdaptiveCardHelper.GetCardFromJson(cardJson, GetSpecialCharToken(testContent));

                Assert.IsNotNull(card);
            }
        }
        /// <summary>
        /// Add a new suggestion in company response entity in Microsoft Azure Table storage.
        /// </summary>
        /// <param name="turnContext">Context object containing information cached for a single turn of conversation with a user.</param>
        /// <param name="userRequestDetails">User response new request details object used to send new request data.</param>
        /// <param name="customAPIAuthenticationToken">Generate JWT token used by client application to authenticate HTTP calls with API.</param>
        /// <param name="cancellationToken">Propagates notification that operations should be canceled.</param>
        /// <returns>A task that represents the work queued to execute.</returns>
        private async Task <MessagingExtensionActionResponse> AddNewSuggestionResultAsync(
            ITurnContext <IInvokeActivity> turnContext,
            AddUserResponseRequestDetail userRequestDetails,
            string customAPIAuthenticationToken,
            CancellationToken cancellationToken)
        {
            var activity = turnContext.Activity;
            var companyResponseEntity = await this.companyStorageHelper.AddNewSuggestionAsync(activity, userRequestDetails);

            // Parse team channel deep link URL and get team id.
            var teamId = AdaptiveCardHelper.ParseTeamIdFromDeepLink(this.botSetting.Value.TeamIdDeepLink);

            if (string.IsNullOrEmpty(teamId))
            {
                throw new NullReferenceException("Provided team details seems to incorrect, please reach out to the Admin.");
            }

            var isAddSuggestionSuccess = await this.companyResponseStorageProvider.UpsertConverationStateAsync(companyResponseEntity);

            if (isAddSuggestionSuccess)
            {
                // Tracking for company response suggested request.
                this.RecordEvent(RecordSuggestCompanyResponse, turnContext);
                var attachment       = AdminCard.GetNewResponseRequestCard(companyResponseEntity, localizer: this.localizer);
                var resourceResponse = await this.SendCardToTeamAsync(turnContext, attachment, teamId, cancellationToken);

                companyResponseEntity.ActivityId = resourceResponse.ActivityId;
                await this.companyResponseStorageProvider.UpsertConverationStateAsync(companyResponseEntity);

                return(new MessagingExtensionActionResponse
                {
                    Task = new TaskModuleContinueResponse
                    {
                        Value = new TaskModuleTaskInfo
                        {
                            Url = $"{this.options.Value.AppBaseUri}/response-message?token={customAPIAuthenticationToken}&status=addSuccess&isCompanyResponse=true&message={this.localizer.GetString("AddNewSuggestionSuccessMessage")}&telemetry=${this.telemetrySettings.Value.InstrumentationKey}&theme=" + "{theme}&locale=" + "{locale}",
                            Height = TaskModuleHeight,
                            Width = TaskModuleWidth,
                            Title = this.localizer.GetString("ManageYourResponsesTitleText"),
                        },
                    },
                });
            }
            else
            {
                return(new MessagingExtensionActionResponse
                {
                    Task = new TaskModuleContinueResponse
                    {
                        Value = new TaskModuleTaskInfo
                        {
                            Url = $"{this.options.Value.AppBaseUri}/response-message?token={customAPIAuthenticationToken}&status=editFailed&isCompanyResponse=true&message={this.localizer.GetString("AddNewSuggestionFailedMessage")}&theme=" + "{theme}&locale=" + "{locale}",
                            Height = TaskModuleHeight,
                            Width = TaskModuleWidth,
                            Title = this.localizer.GetString("ManageYourResponsesTitleText"),
                        },
                    },
                });
            }
        }
Пример #10
0
        /// <summary>
        /// Send the adaptive card in reply to the original activity
        /// </summary>
        /// <param name="connectorClient">Connector client</param>
        /// <param name="originalActivity">Activity we will reply to</param>
        /// <param name="adaptiveCard">Adaptive card to show</param>
        /// <returns>Task</returns>
        public static Task ReplyWithAdaptiveCard(ConnectorClient connectorClient, Activity originalActivity, AdaptiveCard adaptiveCard)
        {
            var replyActivity = originalActivity.CreateReply();

            replyActivity.Attachments = new List <Attachment>
            {
                AdaptiveCardHelper.CreateAdaptiveCardAttachment(adaptiveCard)
            };

            return(connectorClient.Conversations.ReplyToActivityAsync(replyActivity));
        }
Пример #11
0
 public static async Task RespondAsync(DialogContext dc, RecognizerResult luisResults)
 {
     if (Hosts.TryGetHost(luisResults, out Host host))
     {
         await AdaptiveCardHelper.SendCardFromFileAsync(dc, host.GetVersionsFilePath());
     }
     else
     {
         await dc.Context.SendActivityAsync("Please specify which host you're curious about, like \"What version is supported in Outlook?\"");
     }
 }
        protected override async Task <MessagingExtensionActionResponse> OnTeamsMessagingExtensionBotMessagePreviewEditAsync(ITurnContext <IInvokeActivity> turnContext, MessagingExtensionAction action, CancellationToken cancellationToken)
        {
            var submitData = action.ToSubmitExampleData();

            return(AdaptiveCardHelper.CreateTaskModuleAdaptiveCardResponse(
                       submitData.Question,
                       bool.Parse(submitData.MultiSelect),
                       submitData.Option1,
                       submitData.Option2,
                       submitData.Option3));
        }
        private async Task HandleDebugWelcomeTeam(ConnectorClient connectorClient, Activity activity, string teamId)
        {
            var welcomeCard = WelcomeTeamAdaptiveCard.GetCardJson("TestTeam", teamId, activity.Recipient.Id, "Rocky");

            var replyActivity = activity.CreateReply();

            replyActivity.Attachments = new List <Attachment> {
                AdaptiveCardHelper.CreateAdaptiveCardAttachment(welcomeCard)
            };

            await connectorClient.Conversations.ReplyToActivityAsync(replyActivity);
        }
        private async Task HandleDebugNotifyUser(ConnectorClient connectorClient, Activity activity, TeamsChannelAccount sender)
        {
            var notifyCard = PairUpNotificationAdaptiveCard.GetCardJson("TestTeam", sender, sender, "LunchBuddy");

            var replyActivity = activity.CreateReply();

            replyActivity.Attachments = new List <Attachment> {
                AdaptiveCardHelper.CreateAdaptiveCardAttachment(notifyCard)
            };

            await connectorClient.Conversations.ReplyToActivityAsync(replyActivity);
        }
Пример #15
0
        private List <AdaptiveCard> ParseAndCreateCards <T>(string cardPath, List <T> cardDataAdapters, StringDictionary tokens, BotResponse parsedResponse)
            where T : CardDataBase
        {
            if (!tokens.ContainsKey("Text"))
            {
                tokens.Add("Text", parsedResponse.Reply.Text);
            }

            if (!tokens.ContainsKey("Speak"))
            {
                tokens.Add("Speak", parsedResponse.Reply.Speak);
            }

            var properties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);

            foreach (var property in properties)
            {
                if (!tokens.ContainsKey(property.Name))
                {
                    tokens.Add(property.Name, string.Empty);
                }
            }

            // Create list of cards.
            var cards = new List <AdaptiveCard>();

            foreach (var cardDataAdapter in cardDataAdapters)
            {
                // Add or update the public properties of the data type for the card to the tokens list.
                foreach (var property in properties)
                {
                    var value = cardDataAdapter.GetType().GetProperty(property.Name).GetValue(cardDataAdapter, null)?.ToString();
                    if (value != null)
                    {
                        value = SimpleTokensRegex.Replace(value, match => tokens[match.Groups[1].Value]);
                    }

                    if (!tokens.ContainsKey(property.Name))
                    {
                        tokens.Add(property.Name, value);
                    }
                    else
                    {
                        tokens[property.Name] = value;
                    }
                }

                cards.Add(AdaptiveCardHelper.GetCardFromJson(cardPath, tokens));
            }

            return(cards);
        }
        protected override Task <MessagingExtensionActionResponse> OnTeamsMessagingExtensionSubmitActionAsync(ITurnContext <IInvokeActivity> turnContext, MessagingExtensionAction action, CancellationToken cancellationToken)
        {
            var exampleData = JsonConvert.DeserializeObject <ExampleData>(action.Data.ToString());

            var adaptiveCard = AdaptiveCardHelper.CreateAdaptiveCard(exampleData);

            // a number of reasonable options here...

            // (1) send a message on a new conversation and return null (only works in group chats and teams)

            // THIS WILL WORK IF THE BOT IS INSTALLED. (GetMembers() will NOT throw if the bot is installed.)

            //var message = MessageFactory.Attachment(new Attachment { ContentType = AdaptiveCard.ContentType, Content = adaptiveCard });
            //var channelId = turnContext.Activity.TeamsGetChannelId();
            //await turnContext.TeamsCreateConversationAsync(channelId, message, cancellationToken);
            //return null;

            // (2) drop the content into the compose window ready for the user to send

            //return new MessagingExtensionActionResponse
            //{
            //    ComposeExtension = new MessagingExtensionResult
            //    {
            //        Type = "result",
            //        AttachmentLayout = "list",
            //        Attachments = new List<MessagingExtensionAttachment>
            //        {
            //            new MessagingExtensionAttachment
            //            {
            //                Content = adaptiveCard,
            //                ContentType = AdaptiveCard.ContentType,
            //            },
            //        },
            //    },
            //};

            // (3) start a preview flow

            return(Task.FromResult(new MessagingExtensionActionResponse
            {
                ComposeExtension = new MessagingExtensionResult
                {
                    Type = "botMessagePreview",
                    ActivityPreview = MessageFactory.Attachment(new Attachment
                    {
                        Content = adaptiveCard,
                        ContentType = AdaptiveCard.ContentType,
                    }) as Activity,
                },
            }));
        }
Пример #17
0
        protected override async Task <MessagingExtensionActionResponse> OnTeamsMessagingExtensionBotMessagePreviewEditAsync(ITurnContext <IInvokeActivity> turnContext, MessagingExtensionAction action, CancellationToken cancellationToken)
        {
            var reply = MessageFactory.Text("OnTeamsMessagingExtensionBotMessagePreviewEditAsync MessagingExtensionAction: " + JsonConvert.SerializeObject(action));
            await turnContext.SendActivityAsync(reply, cancellationToken);

            var submitData = action.ToSubmitExampleData();

            return(AdaptiveCardHelper.CreateTaskModuleAdaptiveCardResponse(
                       submitData.Question,
                       bool.Parse(submitData.MultiSelect),
                       submitData.Option1,
                       submitData.Option2,
                       submitData.Option3));
        }
Пример #18
0
        // Will be called when user triggers messaging extension
        protected override async Task <MessagingExtensionActionResponse> OnTeamsMessagingExtensionFetchTaskAsync(ITurnContext <IInvokeActivity> turnContext, MessagingExtensionAction action, CancellationToken cancellationToken)
        {
            AdaptiveCard adaptiveCardEditor;

            try
            {
                // create task action
                var cardModel = new CardDataModel();
                if (action.CommandId.Equals("CreateCalendarEvent"))
                {
                    var taskTitle = "Enter Task Title";;
                    if (action.MessagePayload.Body.Content.ToString().Contains("attachment id"))
                    {
                        var temp          = action.MessagePayload.Attachments[0].Content.ToString();
                        var objAttachment = JsonConvert.DeserializeObject <CCCardAttachmentModel>(temp);
                        taskTitle = objAttachment.body[0].text;
                    }
                    else
                    {
                        taskTitle = action.MessagePayload.Body.Content.ToString();
                    }
                    cardModel.TaskTitle = taskTitle;
                }
                adaptiveCardEditor = AdaptiveCardHelper.CreateCardCalendarEventInputs(cardModel);
            }
            catch (Exception ex)
            {
                throw ex;
            }

            return(await Task.FromResult(new MessagingExtensionActionResponse
            {
                Task = new TaskModuleContinueResponse
                {
                    Value = new TaskModuleTaskInfo
                    {
                        Card = new Microsoft.Bot.Schema.Attachment {
                            Content = adaptiveCardEditor, ContentType = AdaptiveCard.ContentType,
                        },
                        Height = 350,
                        Width = 400,
                        Title = "Event Creation",
                    },
                },
            }));

            //Needs to be replaced with OAuth Prompt
        }
        private async Task HandleDebugWelcomeUser(ConnectorClient connectorClient, Activity activity, string teamId)
        {
            var welcomeCard = WelcomeNewMemberAdaptiveCard.GetCard(
                new TeamContext {
                TeamId = teamId, TeamName = "TestTeam"
            },
                Model.EnrollmentStatus.NotJoined,
                "InstallerPerson",
                false);

            var replyActivity = activity.CreateReply();

            replyActivity.Attachments = new List <Attachment> {
                AdaptiveCardHelper.CreateAdaptiveCardAttachment(welcomeCard)
            };

            await connectorClient.Conversations.ReplyToActivityAsync(replyActivity);
        }
Пример #20
0
        protected override async Task <MessagingExtensionActionResponse> OnTeamsMessagingExtensionBotMessagePreviewSendAsync(ITurnContext <IInvokeActivity> turnContext, MessagingExtensionAction action, CancellationToken cancellationToken)
        {
            // The data has been returned to the bot in the action structure.
            var activityPreview   = action.BotActivityPreview[0];
            var attachmentContent = activityPreview.Attachments[0].Content;
            var previewedCard     = JsonConvert.DeserializeObject <AdaptiveCard>(attachmentContent.ToString(), new JsonSerializerSettings {
                NullValueHandling = NullValueHandling.Ignore
            });

            var exampleData = AdaptiveCardHelper.CreateExampleData(previewedCard);

            // This is a send so we are done and we will create the adaptive card editor.
            var adaptiveCard = AdaptiveCardHelper.CreateAdaptiveCard(exampleData);

            var message = MessageFactory.Attachment(new Attachment {
                ContentType = AdaptiveCard.ContentType, Content = adaptiveCard
            });

            // THIS WILL WORK IF THE BOT IS INSTALLED. (GetMembers() will NOT throw if the bot is installed.)
            // (The application should fail gracefully.)
            var channelId = turnContext.Activity.TeamsGetChannelId();

            var conversationParameters = new ConversationParameters
            {
                IsGroup     = true,
                ChannelData = new TeamsChannelData {
                    Channel = new ChannelInfo(channelId)
                },
                Activity = (Activity)message,
            };

            var connectorClient = turnContext.TurnState.Get <IConnectorClient>();

            // This call does NOT send the outbound Activity is not being sent through the middleware stack.
            var conversationResourceResponse = await connectorClient.Conversations.CreateConversationAsync(conversationParameters, cancellationToken).ConfigureAwait(false);

            var attachments = new MessagingExtensionAttachment(AdaptiveCard.ContentType, null, adaptiveCard);
            var result      = new MessagingExtensionResult(AttachmentLayoutTypes.List, "result", new[] { attachments }, null);

            return(new MessagingExtensionActionResponse()
            {
                ComposeExtension = result,
            });
        }
        protected override async Task <MessagingExtensionActionResponse> OnTeamsMessagingExtensionBotMessagePreviewSendAsync(ITurnContext <IInvokeActivity> turnContext, MessagingExtensionAction action, CancellationToken cancellationToken)
        {
            // The data has been returned to the bot in the action structure.
            var activityPreview   = action.BotActivityPreview[0];
            var attachmentContent = activityPreview.Attachments[0].Content;
            var previewedCard     = JsonConvert.DeserializeObject <AdaptiveCard>(attachmentContent.ToString(), new JsonSerializerSettings {
                NullValueHandling = NullValueHandling.Ignore
            });
            var exampleData = AdaptiveCardHelper.CreateExampleData(previewedCard);

            // This is a send so we are done and we will create the adaptive card editor.
            var adaptiveCard = AdaptiveCardHelper.CreateAdaptiveCard(exampleData);

            var message = MessageFactory.Attachment(new Attachment {
                ContentType = AdaptiveCard.ContentType, Content = adaptiveCard
            });

            //User Attribution for Bot messages
            if (exampleData.UserAttributionSelect == "true")
            {
                message.ChannelData = new
                {
                    OnBehalfOf = new[]
                    {
                        new
                        {
                            ItemId      = 0,
                            MentionType = "person",
                            Mri         = turnContext.Activity.From.Id,
                            DisplayName = turnContext.Activity.From.Name
                        }
                    }
                };
            }

            // THIS WILL WORK IF THE BOT IS INSTALLED. (SendActivityAsync will throw if the bot is not installed.)
            await turnContext.SendActivityAsync(message, cancellationToken);

            return(null);
        }
        private List <Attachment> GetAdaptiveCard(QnAMakerResults result)
        {
            var attachments = new List <Attachment>();

            foreach (var res in result.Answers)
            {
                var card = AdaptiveCardHelper.GetAdaptiveCard(res);
                attachments.Add(new Attachment
                {
                    ContentType = AdaptiveCard.ContentType,
                    Content     = card,
                    Name        = "Suggestion"
                });

                if (res.Score >= 0.95)
                {
                    break;
                }
            }

            return(attachments);
        }
        protected override Task <MessagingExtensionActionResponse> OnTeamsMessagingExtensionFetchTaskAsync(ITurnContext <IInvokeActivity> turnContext, MessagingExtensionAction action, CancellationToken cancellationToken)
        {
            var adaptiveCardEditor = AdaptiveCardHelper.CreateAdaptiveCardEditor();

            return(Task.FromResult(new MessagingExtensionActionResponse
            {
                Task = new TaskModuleContinueResponse
                {
                    Value = new TaskModuleTaskInfo
                    {
                        Card = new Attachment
                        {
                            Content = adaptiveCardEditor,
                            ContentType = AdaptiveCard.ContentType,
                        },
                        Height = 450,
                        Width = 500,
                        Title = "Task Module Fetch Example",
                    },
                },
            }));
        }
        public static AdaptiveCard CreateIncidentAdaptiveCard(string botId = null)
        {
            // Json Card for creating incident
            // TODO: Replace with Cards.Lg and responses
            AdaptiveCard adaptiveCard = AdaptiveCardHelper.GetCardFromJson("Dialogs/Teams/Resources/CreateIncident.json");

            adaptiveCard.Id = "GetUserInput";
            adaptiveCard.Actions.Add(new AdaptiveSubmitAction()
            {
                Title = "SubmitIncident",
                Data  = new AdaptiveCardValue <TaskModuleMetadata>()
                {
                    Data = new TaskModuleMetadata()
                    {
                        SkillId            = botId,
                        TaskModuleFlowType = TeamsFlowType.CreateTicket_Form.ToString(),
                        Submit             = true
                    }
                }
            });

            return(adaptiveCard);
        }
Пример #25
0
        /// <summary>
        /// Handle adaptive card submit in 1:1 chat.
        /// Submits the question or feedback to the SME team.
        /// </summary>
        /// <param name="message">A message in a conversation.</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 that represents the work queued to execute.</returns>
        private async Task OnAdaptiveCardSubmitInPersonalChatAsync(
            IMessageActivity message,
            ITurnContext <IMessageActivity> turnContext,
            CancellationToken cancellationToken)
        {
            Attachment   smeTeamCard = null;    // Notification to SME team
            Attachment   userCard    = null;    // Acknowledgement to the user
            TicketEntity newTicket   = null;    // New ticket

            switch (message?.Text)
            {
            case Constants.AskAnExpert:
                this.logger.LogInformation("Sending user ask an expert card (from answer)");
                var askAnExpertPayload = ((JObject)message.Value).ToObject <ResponseCardPayload>();
                await turnContext.SendActivityAsync(MessageFactory.Attachment(AskAnExpertCard.GetCard(askAnExpertPayload))).ConfigureAwait(false);

                break;

            case Constants.ShareFeedback:
                this.logger.LogInformation("Sending user share feedback card (from answer)");
                var shareFeedbackPayload = ((JObject)message.Value).ToObject <ResponseCardPayload>();
                await turnContext.SendActivityAsync(MessageFactory.Attachment(ShareFeedbackCard.GetCard(shareFeedbackPayload))).ConfigureAwait(false);

                break;

            case AskAnExpertCard.AskAnExpertSubmitText:
                this.logger.LogInformation("Received question for expert");
                newTicket = await AdaptiveCardHelper.AskAnExpertSubmitText(message, turnContext, cancellationToken, this.ticketsProvider).ConfigureAwait(false);

                if (newTicket != null)
                {
                    smeTeamCard = new SmeTicketCard(newTicket).ToAttachment(message?.LocalTimestamp);
                    userCard    = new UserNotificationCard(newTicket).ToAttachment(Strings.NotificationCardContent, message?.LocalTimestamp);
                }

                break;

            case ShareFeedbackCard.ShareFeedbackSubmitText:
                this.logger.LogInformation("Received app feedback");
                smeTeamCard = await AdaptiveCardHelper.ShareFeedbackSubmitText(message, turnContext, cancellationToken).ConfigureAwait(false);

                if (smeTeamCard != null)
                {
                    await turnContext.SendActivityAsync(MessageFactory.Text(Strings.ThankYouTextContent)).ConfigureAwait(false);
                }

                break;

            default:
                var payload = ((JObject)message.Value).ToObject <ResponseCardPayload>();

                if (payload.IsPrompt)
                {
                    this.logger.LogInformation("Sending input to QnAMaker for prompt");
                    await this.GetQuestionAnswerReplyAsync(turnContext, message).ConfigureAwait(false);
                }
                else
                {
                    this.logger.LogWarning($"Unexpected text in submit payload: {message.Text}");
                }

                break;
            }

            string expertTeamId = await this.configurationProvider.GetSavedEntityDetailAsync(ConfigurationEntityTypes.TeamId).ConfigureAwait(false);

            // Send message to SME team.
            if (smeTeamCard != null)
            {
                var resourceResponse = await this.SendCardToTeamAsync(turnContext, smeTeamCard, expertTeamId, cancellationToken).ConfigureAwait(false);

                // If a ticket was created, update the ticket with the conversation info.
                if (newTicket != null)
                {
                    newTicket.SmeCardActivityId       = resourceResponse.ActivityId;
                    newTicket.SmeThreadConversationId = resourceResponse.Id;
                    await this.ticketsProvider.UpsertTicketAsync(newTicket).ConfigureAwait(false);
                }
            }

            // Send acknowledgment to the user
            if (userCard != null)
            {
                await turnContext.SendActivityAsync(MessageFactory.Attachment(userCard), cancellationToken).ConfigureAwait(false);
            }
        }
 protected override async Task <MessagingExtensionActionResponse> OnTeamsMessagingExtensionFetchTaskAsync(ITurnContext <IInvokeActivity> turnContext, MessagingExtensionQuery query, CancellationToken cancellationToken)
 {
     return(AdaptiveCardHelper.CreateTaskModuleAdaptiveCardResponse());
 }
        /// <summary>
        /// Handle message activity in channel.
        /// </summary>
        /// <param name="message">A message in a conversation.</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 that represents the work queued to execute.</returns>
        private async Task OnMessageActivityInChannelAsync(
            IMessageActivity message,
            ITurnContext <IMessageActivity> turnContext,
            CancellationToken cancellationToken)
        {
            try
            {
                if (message.Value == null)
                {
                    await turnContext.SendActivityAsync(this.localizer.GetString("ErrorWhenMessageInChannel"));

                    return;
                }

                IMessageActivity      userNotification      = null;
                CompanyResponseEntity companyResponseEntity = null;
                var cardPostedData = ((JObject)message.Value).ToObject <AdaptiveSubmitActionData>();
                var text           = cardPostedData.AdaptiveCardActions.Text;
                var activity       = turnContext.Activity;

                switch (text)
                {
                case Constants.ApproveCommand:

                    if (string.IsNullOrEmpty(cardPostedData.UpdatedQuestionCategory) || string.IsNullOrEmpty(cardPostedData.UpdatedQuestionText) || string.IsNullOrEmpty(cardPostedData.UpdatedResponseText))
                    {
                        companyResponseEntity = this.companyResponseStorageProvider.GetCompanyResponseEntityAsync(cardPostedData.ResponseId).GetAwaiter().GetResult();
                        var attachment = AdminCard.GetNewResponseRequestCard(companyResponseEntity, localizer: this.localizer, emptyApproveField: true);
                        await AdaptiveCardHelper.RefreshCardAsync(turnContext, companyResponseEntity.ActivityId, attachment);

                        return;
                    }

                    companyResponseEntity = this.companyStorageHelper.AddApprovedData(cardPostedData, activity.From.Name, activity.From.AadObjectId);
                    var approveRequestResult = this.companyResponseStorageProvider.UpsertConverationStateAsync(companyResponseEntity).GetAwaiter().GetResult();

                    if (approveRequestResult)
                    {
                        // Refresh the approved card in channel.
                        var attachment = AdminCard.GetRefreshedCardForApprovedRequest(companyResponseEntity, activity.From.Name, localizer: this.localizer);
                        await AdaptiveCardHelper.RefreshCardAsync(turnContext, companyResponseEntity.ActivityId, attachment);

                        // Get user notification attachment and send it to user for approved request.
                        userNotification = MessageFactory.Attachment(UserCard.GetNotificationCardForApprovedRequest(companyResponseEntity, localizer: this.localizer));

                        var result = await this.conversationStorageProvider.GetConversationEntityAsync(companyResponseEntity.UserId);

                        if (result != null)
                        {
                            await AdaptiveCardHelper.SendNotificationCardAsync(turnContext, userNotification, result.ConversationId, cancellationToken);

                            // Tracking for number of requests approved.
                            this.RecordEvent(ApprovedRequestEventName, turnContext);
                        }
                        else
                        {
                            this.logger.LogInformation("Unable to send notification card for approved request because conversation id is null.");
                        }
                    }
                    else
                    {
                        this.logger.LogInformation("Unable to approve the request.");
                    }

                    break;

                case Constants.RejectCommand:

                    companyResponseEntity = this.companyStorageHelper.AddRejectedData(cardPostedData, activity.From.Name, activity.From.AadObjectId);
                    var rejectRequestResult = this.companyResponseStorageProvider.UpsertConverationStateAsync(companyResponseEntity).GetAwaiter().GetResult();

                    if (rejectRequestResult)
                    {
                        // Get user notification rejected card attachment.
                        var attachment = AdminCard.GetRefreshedCardForRejectedRequest(companyResponseEntity, activity.From.Name, localizer: this.localizer);
                        await AdaptiveCardHelper.RefreshCardAsync(turnContext, companyResponseEntity.ActivityId, attachment);

                        // Send end user notification for approved request.
                        userNotification = MessageFactory.Attachment(UserCard.GetNotificationCardForRejectedRequest(companyResponseEntity, localizer: this.localizer));

                        var result = await this.conversationStorageProvider.GetConversationEntityAsync(companyResponseEntity.UserId);

                        if (result != null)
                        {
                            await AdaptiveCardHelper.SendNotificationCardAsync(turnContext, userNotification, result.ConversationId, cancellationToken);

                            // Tracking for number of requests rejected.
                            this.RecordEvent(RejectedRequestEventName, turnContext);
                        }
                        else
                        {
                            this.logger.LogInformation("Unable to send notification card for rejected request because conversation id is null.");
                        }
                    }
                    else
                    {
                        this.logger.LogInformation("Unable to reject the request.");
                    }

                    return;

                default:
                    this.logger.LogInformation("Unrecognized input in channel");
                    break;
                }
            }
            catch (Exception ex)
            {
                this.logger.LogError(ex, $"Error processing message: {ex.Message}", SeverityLevel.Error);
                throw;
            }
        }
        /// <summary>
        /// Handle adaptive card submit in 1:1 chat.
        /// Submits the question or feedback to the SME team.
        /// </summary>
        /// <param name="message">A message in a conversation.</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 that represents the work queued to execute.</returns>
        public async Task SendAdaptiveCardInPersonalChatAsync(
            IMessageActivity message,
            ITurnContext <IMessageActivity> turnContext,
            CancellationToken cancellationToken)
        {
            Attachment   smeTeamCard = null;    // Notification to SME team
            Attachment   userCard    = null;    // Acknowledgement to the user
            TicketEntity newTicket   = null;    // New ticket

            string text = (message.Text ?? string.Empty).Trim();

            switch (text)
            {
            // Sends user ask an expert card from the answer card.
            case Constants.AskAnExpert:
                this.logger.LogInformation("Sending user ask an expert card (from answer)");
                var askAnExpertPayload = ((JObject)message.Value).ToObject <ResponseCardPayload>();
                await this.SendActivityInChatAsync(turnContext, MessageFactory.Attachment(AskAnExpertCard.GetCard(askAnExpertPayload)), cancellationToken);

                break;

            // Sends user the feedback card from the answer card.
            case Constants.ShareFeedback:
                this.logger.LogInformation("Sending user share feedback card (from answer)");
                var shareFeedbackPayload = ((JObject)message.Value).ToObject <ResponseCardPayload>();
                await this.SendActivityInChatAsync(turnContext, MessageFactory.Attachment(ShareFeedbackCard.GetCard(shareFeedbackPayload)), cancellationToken);

                break;

            // User submits the ask an expert card.
            case Constants.AskAnExpertSubmitText:
                this.logger.LogInformation("Received question for expert");
                newTicket = await AdaptiveCardHelper.AskAnExpertSubmitText(message, turnContext, cancellationToken, this.ticketsProvider).ConfigureAwait(false);

                if (newTicket != null)
                {
                    smeTeamCard = new SmeTicketCard(newTicket).ToAttachment();
                    userCard    = new UserNotificationCard(newTicket).ToAttachment(Strings.NotificationCardContent);
                }

                break;

            // User submits the share feedback card.
            case Constants.ShareFeedbackSubmitText:
                this.logger.LogInformation("Received app feedback");
                smeTeamCard = await AdaptiveCardHelper.ShareFeedbackSubmitText(message, turnContext, cancellationToken).ConfigureAwait(false);

                if (smeTeamCard != null)
                {
                    await this.SendActivityInChatAsync(turnContext, MessageFactory.Text(Strings.ThankYouTextContent), cancellationToken);
                }

                break;

            default:
                var payload = ((JObject)message.Value).ToObject <ResponseCardPayload>();

                if (payload.IsPrompt)
                {
                    this.logger.LogInformation("Sending input to QnAMaker for prompt");
                    await this.qnaPairServiceFacade.GetReplyToQnAAsync(turnContext, message).ConfigureAwait(false);
                }
                else
                {
                    this.logger.LogWarning($"Unexpected text in submit payload: {message.Text}");
                }

                break;
            }

            string expertTeamId = await this.configurationProvider.GetSavedEntityDetailAsync(ConfigurationEntityTypes.TeamId).ConfigureAwait(false);

            // Send message to SME team.
            if (smeTeamCard != null)
            {
                await this.SendTicketCardToSMETeamAsync(turnContext, smeTeamCard, expertTeamId, cancellationToken, newTicket);
            }

            // Send acknowledgment to the user
            if (userCard != null)
            {
                await this.SendActivityInChatAsync(turnContext, MessageFactory.Attachment(userCard), cancellationToken);
            }
        }
Пример #29
0
        // 1. Will be called when user triggers messaging extension which then calls CreateTaskModuleCommand
        protected override async Task <MessagingExtensionActionResponse> OnTeamsMessagingExtensionFetchTaskAsync(ITurnContext <IInvokeActivity> turnContext, MessagingExtensionAction action, CancellationToken cancellationToken)
        {
            // Check if the bot has been installed in the team by getting the team rooster
            try
            {
                var teamsMembers = await TeamsInfo.GetMembersAsync(turnContext);
            }
            catch
            {
                // if not installed we will send out the card instructing the user to install the bot
                string jitCardPath  = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Cards", "jitCard.json");
                var    jitCard      = File.ReadAllText(jitCardPath, Encoding.UTF8);
                string jitCardJson  = jitCard;
                var    jitCardTeams = AdaptiveCard.FromJson(jitCardJson);
                return(await Task.FromResult(new MessagingExtensionActionResponse
                {
                    Task = new TaskModuleContinueResponse
                    {
                        Value = new TaskModuleTaskInfo
                        {
                            Card = new Attachment
                            {
                                Content = jitCardTeams.Card,
                                ContentType = AdaptiveCard.ContentType,
                            },
                            Height = 300,
                            Width = 600,
                            Title = "Install bot",
                        },
                    },
                }));
            }


            var magicCode = string.Empty;
            var state     = (turnContext.Activity.Value as Newtonsoft.Json.Linq.JObject).Value <string>("state");

            if (!string.IsNullOrEmpty(state))
            {
                int parsed = 0;
                if (int.TryParse(state, out parsed))
                {
                    magicCode = parsed.ToString();
                }
            }

            var tokenResponse = await(turnContext.Adapter as IUserTokenProvider).GetUserTokenAsync(turnContext, _connectionName, magicCode, cancellationToken: cancellationToken);

            if (tokenResponse == null || string.IsNullOrEmpty(tokenResponse.Token))
            {
                // There is no token, so the user has not signed in yet.

                // Retrieve the OAuth Sign in Link to use in the MessagingExtensionResult Suggested Actions
                var signInLink = await(turnContext.Adapter as IUserTokenProvider).GetOauthSignInLinkAsync(turnContext, _connectionName, cancellationToken);

                return(new MessagingExtensionActionResponse
                {
                    ComposeExtension = new MessagingExtensionResult
                    {
                        Type = "auth",
                        SuggestedActions = new MessagingExtensionSuggestedAction
                        {
                            Actions = new List <CardAction>
                            {
                                new CardAction
                                {
                                    Type = ActionTypes.OpenUrl,
                                    Value = signInLink,
                                    Title = "Sign in Please",
                                },
                            },
                        },
                    },
                });
            }
            var accessToken = tokenResponse.Token;

            if (accessToken != null || !string.IsNullOrEmpty(accessToken))
            {
                // Create Graph Client
                var client = new SimpleGraphClient(accessToken);
                // Get Group details
                var channel = turnContext.Activity.TeamsGetChannelId();
                if (channel != null)
                {
                    var    members           = new List <TeamsChannelAccount>();
                    string continuationToken = null;
                    do
                    {
                        var currentPage = await TeamsInfo.GetPagedMembersAsync(turnContext, 100, continuationToken, cancellationToken);

                        continuationToken = currentPage.ContinuationToken;
                        members           = members.Concat(currentPage.Members).ToList();
                    }while (continuationToken != null);
                    TeamDetails teamDetails = await TeamsInfo.GetTeamDetailsAsync(turnContext, turnContext.Activity.TeamsGetTeamInfo().Id, cancellationToken);

                    if (teamDetails != null)
                    {
                        var groupId = teamDetails.AadGroupId;
                        plannerGroupId = groupId;
                        //Get Plans
                        var currentGroupPlan = await client.GetCurrentPlan(groupId);

                        var favoritePlans = await client.GetFavoritePlans();

                        // Fill Adaptive Card data
                        var exampleData = new ExampleData();
                        exampleData.MultiSelect = "false";
                        if (currentGroupPlan.CurrentPage.Count == 0)
                        {
                            exampleData.Option1      = favoritePlans.CurrentPage[4].Title;
                            exampleData.Option1Value = favoritePlans.CurrentPage[4].Id;
                        }
                        else
                        {
                            exampleData.Option1      = currentGroupPlan.CurrentPage[0].Title;
                            exampleData.Option1Value = currentGroupPlan.CurrentPage[0].Id;
                        }
                        exampleData.Option2      = favoritePlans.CurrentPage[0].Title;
                        exampleData.Option3      = favoritePlans.CurrentPage[1].Title;
                        exampleData.Option4      = favoritePlans.CurrentPage[2].Title;
                        exampleData.Option2Value = favoritePlans.CurrentPage[0].Id;
                        exampleData.Option3Value = favoritePlans.CurrentPage[1].Id;
                        exampleData.Option4Value = favoritePlans.CurrentPage[2].Id;
                        // Create and return card
                        var adaptiveCardEditor = AdaptiveCardHelper.CreateAdaptiveCardEditor(exampleData);
                        //var adaptiveCardEditor = CreateAdaptiveCard();

                        return(await Task.FromResult(new MessagingExtensionActionResponse
                        {
                            Task = new TaskModuleContinueResponse
                            {
                                Value = new TaskModuleTaskInfo
                                {
                                    Card = new Microsoft.Bot.Schema.Attachment
                                    {
                                        Content = adaptiveCardEditor,
                                        ContentType = AdaptiveCard.ContentType,
                                    },
                                    Height = 600,
                                    Width = 600,
                                    Title = "Task creation",
                                },
                            },
                        }));
                    }
                }
                else
                {
                    // Return only favorite plans without current plan as in 1:1 or group chat
                    var favoritePlans = await client.GetFavoritePlans();

                    // Fill Adaptive Card data
                    var exampleData = new ExampleData();
                    exampleData.MultiSelect = "false";
                    exampleData.Option1     = favoritePlans.CurrentPage[0].Title;
                    exampleData.Option2     = favoritePlans.CurrentPage[1].Title;
                    exampleData.Option3     = favoritePlans.CurrentPage[2].Title;

                    exampleData.Option1Value = favoritePlans.CurrentPage[0].Id;
                    exampleData.Option3Value = favoritePlans.CurrentPage[1].Id;
                    exampleData.Option4Value = favoritePlans.CurrentPage[2].Id;

                    // Create and return card
                    var adaptiveCardEditor = AdaptiveCardHelper.CreateAdaptiveCardEditor(exampleData);
                    //var adaptiveCardEditor = CreateAdaptiveCard();

                    return(await Task.FromResult(new MessagingExtensionActionResponse
                    {
                        Task = new TaskModuleContinueResponse
                        {
                            Value = new TaskModuleTaskInfo
                            {
                                Card = new Microsoft.Bot.Schema.Attachment
                                {
                                    Content = adaptiveCardEditor,
                                    ContentType = AdaptiveCard.ContentType,
                                },
                                Height = 600,
                                Width = 600,
                                Title = "Task creation",
                            },
                        },
                    }));
                }
            }
            //Needs to be replaced with OAuth Prompt
            return(null);
        }
Пример #30
0
        private async Task HandleUnrecognizedMsgInOneOnOneChat(ConnectorClient connectorClient, Activity activity, string tenantId, ChannelAccount sender)
        {
            // We either display a welcome user message or a simple unrecognized message.
            // Both will list all the actions you can do and admin actions if the user is an admin.

            // 1. Determine the team context.
            // 2. If we don't have just one, ask for which team to perform actions for
            // 3. Show welcome user if the user has not joined that team
            // 4. Show unrecognized message if the user has joined that team before.
            TeamContext teamForActions = null;

            // Try to get it from the message if this was from the welcome team "Chat with me" action.
            var teamIdFromWelcomeTeam = AdaptiveCardHelper.GetTeamIdFromChatWithMeMessage(activity.Text);

            if (!string.IsNullOrEmpty(teamIdFromWelcomeTeam))
            {
                string teamName = await this.bot.GetTeamNameAsync(connectorClient, teamIdFromWelcomeTeam);

                teamForActions = new TeamContext {
                    TeamId = teamIdFromWelcomeTeam, TeamName = teamName
                };
            }
            else
            {
                // Extract it from the ChooseTeamHeroCard response
                var userAndTeam = ActivityHelper.GetUserAndTeam(activity, sender.GetUserId(), sender.Name);
                teamForActions = userAndTeam?.Team;
            }

            if (teamForActions == null)
            {
                var allTeams = await this.bot.GetAllTeams(connectorClient);

                if (allTeams.Count > 1)
                {
                    var chooseTeamCard = ChooseTeamHeroCard.GetCard(Resources.UnrecognizedInputChooseTeam, allTeams, actionMessage: activity.Text);
                    await ActivityHelper.ReplyWithHeroCard(connectorClient, activity, chooseTeamCard);

                    return;
                }

                if (allTeams.Count == 0)
                {
                    await connectorClient.Conversations.ReplyToActivityAsync(activity.CreateReply(Resources.UnrecognizedInputNoTeam));

                    return;
                }

                teamForActions = allTeams.First();
            }

            var userInfo = await this.bot.GetOrCreateUnpersistedUserInfo(tenantId, sender.GetUserId());

            var userStatus        = userInfo.GetStatusInTeam(teamForActions.TeamId);
            var isUserAdminOfTeam = userInfo.AdminForTeams.Contains(teamForActions.TeamId);

            if (userStatus == EnrollmentStatus.NotJoined)
            {
                await this.bot.WelcomeUser(connectorClient, sender, tenantId, teamForActions, userStatus, botInstallerName : string.Empty, isUserAdminOfTeam);
            }
            else
            {
                await this.bot.SendUnrecognizedOneOnOneMessage(connectorClient, activity.CreateReply(), teamForActions, userStatus, isUserAdminOfTeam);
            }
        }