public async Task StartRunbookAsync(IDialogContext context, LuisResult result)
        {
            EntityRecommendation runbookEntity;
            var accessToken = await context.GetAccessToken(resourceId.Value);

            if (string.IsNullOrEmpty(accessToken))
            {
                return;
            }

            var subscriptionId = context.GetSubscriptionId();

            var availableAutomationAccounts = await new AutomationDomain().ListRunbooksAsync(accessToken, subscriptionId);

            // check if the user specified a runbook name in the command
            if (result.TryFindEntity("Runbook", out runbookEntity))
            {
                // obtain the name specified by the user - text in LUIS result is different
                var runbookName = runbookEntity.GetEntityOriginalText(result.Query);

                EntityRecommendation automationAccountEntity;

                if (result.TryFindEntity("AutomationAccount", out automationAccountEntity))
                {
                    // obtain the name specified by the user - text in LUIS result is different
                    var automationAccountName = automationAccountEntity.GetEntityOriginalText(result.Query);

                    var selectedAutomationAccount = availableAutomationAccounts.SingleOrDefault(x => x.AutomationAccountName.Equals(automationAccountName, StringComparison.InvariantCultureIgnoreCase));

                    if (selectedAutomationAccount == null)
                    {
                        await context.PostAsync($"The '{automationAccountName}' automation account was not found in the current subscription");

                        context.Done <string>(null);
                        return;
                    }

                    var runbook = selectedAutomationAccount.Runbooks.SingleOrDefault(x => x.RunbookName.Equals(runbookName, StringComparison.InvariantCultureIgnoreCase));

                    // ensure that the runbook exists in the specified automation account
                    if (runbook == null)
                    {
                        await context.PostAsync($"The '{runbookName}' runbook was not found in the '{automationAccountName}' automation account.");

                        context.Done <string>(null);
                        return;
                    }

                    if (!runbook.RunbookState.Equals("Published", StringComparison.InvariantCultureIgnoreCase))
                    {
                        await context.PostAsync($"The '{runbookName}' runbook that you are trying to run is not published (State: {runbook.RunbookState}). Please go the Azure Portal and publish the runbook.");

                        context.Done <string>(null);
                        return;
                    }

                    runbookEntity.Entity = runbookName;
                    runbookEntity.Type   = "RunbookName";

                    automationAccountEntity.Entity = selectedAutomationAccount.AutomationAccountName;
                    automationAccountEntity.Type   = "AutomationAccountName";
                }
                else
                {
                    // ensure that the runbook exists in at least one of the automation accounts
                    var selectedAutomationAccounts = availableAutomationAccounts.Where(x => x.Runbooks.Any(r => r.RunbookName.Equals(runbookName, StringComparison.InvariantCultureIgnoreCase)));

                    if (selectedAutomationAccounts == null || !selectedAutomationAccounts.Any())
                    {
                        await context.PostAsync($"The '{runbookName}' runbook was not found in any of your automation accounts.");

                        context.Done <string>(null);
                        return;
                    }

                    var runbooks = selectedAutomationAccounts.SelectMany(x => x.Runbooks.Where(r => r.RunbookName.Equals(runbookName, StringComparison.InvariantCultureIgnoreCase) &&
                                                                                               r.RunbookState.Equals("Published", StringComparison.InvariantCultureIgnoreCase)));

                    if (runbooks == null || !runbooks.Any())
                    {
                        await context.PostAsync($"The '{runbookName}' runbook that you are trying to run is not Published. Please go the Azure Portal and publish the runbook.");

                        context.Done <string>(null);
                        return;
                    }

                    runbookEntity.Entity = runbookName;
                    runbookEntity.Type   = "RunbookName";

                    // todo: handle runbooks with same name in different automation accounts
                    availableAutomationAccounts = selectedAutomationAccounts.ToList();
                }
            }

            if (availableAutomationAccounts.Any())
            {
                var formState = new RunbookFormState(availableAutomationAccounts);

                if (availableAutomationAccounts.Count() == 1)
                {
                    formState.AutomationAccountName = availableAutomationAccounts.Single().AutomationAccountName;
                }

                var form = new FormDialog <RunbookFormState>(
                    formState,
                    AutomationForms.BuildRunbookForm,
                    FormOptions.PromptInStart,
                    result.Entities);
                context.Call(form, this.StartRunbookParametersAsync);
            }
            else
            {
                await context.PostAsync($"No automations accounts were found in the current subscription. Please create an Azure automation account or switch to a subscription which has an automation account in it.");

                context.Done <string>(null);
            }
        }
        private async Task RunbookFormComplete(IDialogContext context, RunbookFormState runbookFormState)
        {
            try
            {
                var accessToken = await context.GetAccessToken(resourceId.Value);

                if (string.IsNullOrEmpty(accessToken))
                {
                    return;
                }

                var runbookJob = await new AutomationDomain().StartRunbookAsync(
                    accessToken,
                    runbookFormState.SelectedAutomationAccount.SubscriptionId,
                    runbookFormState.SelectedAutomationAccount.ResourceGroup,
                    runbookFormState.SelectedAutomationAccount.AutomationAccountName,
                    runbookFormState.RunbookName,
                    runbookFormState.RunbookParameters.Where(param => !string.IsNullOrWhiteSpace(param.ParameterValue))
                    .ToDictionary(param => param.ParameterName, param => param.ParameterValue));

                IList <RunbookJob> automationJobs = context.GetAutomationJobs(runbookFormState.SelectedAutomationAccount.SubscriptionId);
                if (automationJobs == null)
                {
                    runbookJob.FriendlyJobId = AutomationJobsHelper.NextFriendlyJobId(automationJobs);
                    automationJobs           = new List <RunbookJob> {
                        runbookJob
                    };
                }
                else
                {
                    runbookJob.FriendlyJobId = AutomationJobsHelper.NextFriendlyJobId(automationJobs);
                    automationJobs.Add(runbookJob);
                }

                context.StoreAutomationJobs(runbookFormState.SelectedAutomationAccount.SubscriptionId, automationJobs);

                await context.PostAsync($"Created Job '{runbookJob.JobId}' for the '{runbookFormState.RunbookName}' runbook in '{runbookFormState.AutomationAccountName}' automation account. You'll receive a message when it is completed.");

                var notCompletedStatusList = new List <string> {
                    "Stopped", "Suspended", "Failed"
                };
                var completedStatusList = new List <string> {
                    "Completed"
                };
                var notifyStatusList = new List <string> {
                    "Running"
                };
                notifyStatusList.AddRange(completedStatusList);
                notifyStatusList.AddRange(notCompletedStatusList);

                accessToken = await context.GetAccessToken(resourceId.Value);

                if (string.IsNullOrEmpty(accessToken))
                {
                    return;
                }

#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
                CheckLongRunningOperationStatus(
                    context,
                    runbookJob,
                    accessToken,
                    new AutomationDomain().GetAutomationJobAsync,
                    rj => rj.EndDateTime.HasValue,
                    (previous, last, job) =>
                {
                    if (!string.Equals(previous?.Status, last?.Status) && notifyStatusList.Contains(last.Status))
                    {
                        if (notCompletedStatusList.Contains(last.Status))
                        {
                            return($"The runbook '{job.RunbookName}' (job '{job.JobId}') did not complete with status '{last.Status}'. Please go to the Azure Portal for more detailed information on why.");
                        }
                        else if (completedStatusList.Contains(last.Status))
                        {
                            return($"Runbook '{job.RunbookName}' is currently in '{last.Status}' status. Type **show {job.FriendlyJobId} output** to see the output.");
                        }
                        else
                        {
                            return($"Runbook '{job.RunbookName}' job '{job.JobId}' is currently in '{last.Status}' status.");
                        }
                    }

                    return(null);
                });
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
            }
            catch (Exception e)
            {
                await context.PostAsync($"Oops! Something went wrong :(. Technical Details: {e.InnerException.Message}");
            }

            context.Done <string>(null);
        }
 public static void StoreRunbookFormState(this IBotContext context, RunbookFormState runbookFormState)
 {
     context.PrivateConversationData.SetValue(ContextConstants.RunbookFormStateKey, runbookFormState);
 }