예제 #1
0
        public WorkflowBuilder GetWorkflowBuilder()
        {
            MongoConfiguration.Initialize();
            ExceptionHandlerService.DiscordConfiguration = this._configuration;

            return(WorkflowBuilder.Create(this._configuration.Token, this._context, typeof(WatchmanBot).Assembly)
                   .SetDefaultMiddlewares()
                   .AddOnReadyHandlers(builder =>
            {
                builder
                .AddHandler(() => Task.Run(() => Log.Information("Bot started and logged in...")))
                .AddFromIoC <ConfigurationService>(configurationService => configurationService.InitDefaultConfigurations)
                .AddFromIoC <CustomCommandsLoader>(customCommandsLoader => customCommandsLoader.InitDefaultCustomCommands)
                .AddFromIoC <HelpDataCollectorService, HelpDBGeneratorService>((dataCollector, helpService) =>
                                                                               () => helpService.FillDatabase(dataCollector.GetCommandsInfo(typeof(WatchmanBot).Assembly)))
                .AddFromIoC <ResponsesInitService>(responsesService => responsesService.InitNewResponsesFromResources)
                .AddFromIoC <InitializationService, DiscordServersService>((initService, serversService) => async() =>
                {
                    var stopwatch = Stopwatch.StartNew();
                    // when bot was offline for less than 1 minutes, it doesn't make sense to init all servers
                    if (WorkflowBuilder.DisconnectedTimes.LastOrDefault() > DateTime.Now.AddMinutes(-1))
                    {
                        Log.Information("Bot was connected less than 1 minute ago");
                        return;
                    }
                    await serversService.GetDiscordServersAsync().ForEachAwaitAsync(initService.InitServer);
                    Log.Information(stopwatch.ElapsedMilliseconds.ToString());
                })
                .AddHandler(() => Task.Run(() => Log.Information("Bot has done every Ready tasks.")));
            })
                   .AddOnUserJoinedHandlers(builder =>
            {
                builder
                .AddFromIoC <WelcomeUserService>(x => x.WelcomeUser)
                .AddFromIoC <MutingRejoinedUsersService>(x => x.MuteAgainIfNeeded);
            })
                   .AddOnDiscordServerAddedBotHandlers(builder =>
            {
                builder
                .AddFromIoC <InitializationService>(initService => initService.InitServer);
            })
                   .AddOnWorkflowExceptionHandlers(builder =>
            {
                builder
                .AddFromIoC <ExceptionHandlerService>(x => (e, _) => x.LogException(e))
                .AddFromIoC <ExceptionHandlerService>(x => x.SendExceptionResponse)
                .AddFromIoC <ExceptionHandlerService>(x => x.PrintDebugExceptionInfo, onlyOnDebug: true)
                .AddFromIoC <ExceptionHandlerService>(x => (e, _) => x.SendExceptionToDebugServer(e));
            })
                   .AddOnChannelCreatedHandlers(builder =>
            {
                builder
                .AddFromIoC <MuteRoleInitService>(x => x.InitForChannelAsync);
            })
                   .AddOnChannelRemovedHandler(builder =>
            {
                builder
                .AddFromIoC <ComplaintsChannelService>(x => x.RemoveIfNeededComplaintsChannel);
            }));
        }
예제 #2
0
        public static Workflow Build(string requiredRole)
        {
            var selectCategory = new StepBuilder <ISelectCategoryWithQueryCountStep>();
            var invokeWorkflow = new StepBuilder <IInvokeSearchQueryByCategoryIdWorkflowStep>();

            selectCategory
            .Edge(x => x.Back).MapsTo(EdgeDone)
            .Edge(x => x.Canceled).MapsTo(EdgeCanceled)
            .Edge(x => x.Create).MapsTo(selectCategory)
            .Edge(x => x.Edit).MapsTo(invokeWorkflow)
            .Edge(x => x.Delete).MapsTo(selectCategory)
            .Input(x => x.CanGoBack).Constant(false)
            .SetUniqueWorkflowStepId(WorkflowIds.SearchQueryByCategoryWorkflow);

            invokeWorkflow
            .Edge(x => x.Done).MapsTo(selectCategory)
            .Edge(x => x.Canceled).MapsTo(EdgeCanceled)
            .Edge(x => x.Failed).MapsTo(EdgeFailed)
            .Input(x => x.CategoryId).From(selectCategory).Output(x => x.SingleSelectId);

            return(WorkflowBuilder.Create()
                   .WithId(WorkflowIds.SearchQueryByCategoryWorkflow)
                   .WithDefinition(nameof(WorkflowIds.SearchQueryByCategoryWorkflow))
                   .WithEdges(EdgeDone, EdgeCanceled, EdgeFailed)
                   .WithRequiredRole(requiredRole)
                   .StartWith(selectCategory));
        }
        public static Workflow Build(string requiredRole)
        {
            var select = new StepBuilder <ISelectQueryExecutionStep>();
            var view   = new StepBuilder <IViewQueryExecutionStep>();

            select
            .Edge(x => x.Back).MapsTo(EdgeDone)
            .Edge(x => x.Canceled).MapsTo(EdgeCanceled)
            .Edge(x => x.Create).MapsTo(EdgeFailed)
            .Edge(x => x.Delete).MapsTo(EdgeFailed)
            .Edge(x => x.Edit).MapsTo(view)
            .Input(x => x.CanGoBack).Constant(false)
            .SetUniqueWorkflowStepId(WorkflowIds.QueryExecutionWorkflow);

            view
            .Edge(x => x.Back).MapsTo(select)
            .Edge(x => x.Canceled).MapsTo(EdgeCanceled)
            .Edge(x => x.Saved).MapsTo(EdgeFailed)
            .Input(x => x.Id).From(select).Output(x => x.SingleSelectId);

            return(WorkflowBuilder.Create()
                   .WithId(WorkflowIds.QueryExecutionWorkflow)
                   .WithDefinition(nameof(WorkflowIds.QueryExecutionWorkflow))
                   .WithEdges(EdgeDone, EdgeCanceled, EdgeFailed)
                   .WithRequiredRole(requiredRole)
                   .StartWith(select));
        }
        public static Workflow Build(string requiredRole)
        {
            var select         = new StepBuilder <ISelectCategoryStep>();
            var create         = new StepBuilder <ICreateCategoryStep>();
            var edit           = new StepBuilder <IEditCategoryStep>();
            var redirect       = new StepBuilder <IRedirectSelectOrCreated>();
            var delete         = new StepBuilder <IDeleteCategoryStep>();
            var importExisting = new StepBuilder <ICategoryImportExistingStep>();

            select
            .Edge(x => x.Back).MapsTo(EdgeDone)
            .Edge(x => x.Canceled).MapsTo(EdgeCanceled)
            .Edge(x => x.Create).MapsTo(create)
            .Edge(x => x.Edit).MapsTo(redirect)
            .Edge(x => x.Delete).MapsTo(delete)
            .Edge(x => x.ImportExisting).MapsTo(importExisting)
            .Input(x => x.CanGoBack).Constant(false)
            .SetUniqueWorkflowStepId(WorkflowIds.CategoryWorkflow)
            .UseGenericDashboardComponentConfiguration(WorkflowIds.CategoryWorkflow, "api/cea/categories/count", DAL.WebApplication.CatchEmAll_Categories.Key);

            create
            .Edge(x => x.Canceled).MapsTo(EdgeCanceled)
            .Edge(x => x.Saved).MapsTo(redirect)
            .Edge(x => x.Back).MapsTo(select)
            .UseDashboardComponentConfigurationFrom(select);

            redirect
            .Edge(x => x.Next).MapsTo(edit)
            .Edge(x => x.NotSet).MapsTo(select)
            .Input(x => x.CreatedId).From(create).Output(x => x.Id)
            .Input(x => x.SelectedId).From(select).Output(x => x.SingleSelectId);

            edit
            .Edge(x => x.Canceled).MapsTo(EdgeCanceled)
            .Edge(x => x.Saved).MapsTo(edit)
            .Edge(x => x.Back).MapsTo(select)
            .Input(x => x.Id).From(redirect).Output(x => x.RedirectId)
            .UseDashboardComponentConfigurationFrom(select);

            delete
            .Edge(x => x.Deleted).MapsTo(select)
            .Input(x => x.Ids).From(select).Output(x => x.MultiSelectIds);

            importExisting
            .Edge(x => x.Next).MapsTo(select);

            return(WorkflowBuilder.Create()
                   .WithId(WorkflowIds.CategoryWorkflow)
                   .WithDefinition(nameof(WorkflowIds.CategoryWorkflow))
                   .WithEdges(EdgeDone, EdgeCanceled, EdgeFailed)
                   .WithRequiredRole(requiredRole)
                   .StartWith(select));
        }
        public static Workflow Build(string requiredRole)
        {
            var createConfig   = new StepBuilder <Steps.Interactive.Categories.ICreateDashboardComponentConfigurationStep>();
            var selectQuery    = new StepBuilder <ISelectSearchQueryStep>();
            var createQuery    = new StepBuilder <ICreateSearchQueryStep>();
            var deleteQueries  = new StepBuilder <IDeleteSearchQueryStep>();
            var invokeWorkflow = new StepBuilder <IInvokeSearchQueryByIdWorkflowStep>();

            createConfig
            .Edge(x => x.Next).MapsTo(selectQuery)
            .Input(x => x.CategoryId).FromWorkflow(InputCategoryId);

            selectQuery
            .Edge(x => x.Back).MapsTo(EdgeDone)
            .Edge(x => x.Canceled).MapsTo(EdgeCanceled)
            .Edge(x => x.Create).MapsTo(createQuery)
            .Edge(x => x.Edit).MapsTo(invokeWorkflow)
            .Edge(x => x.Delete).MapsTo(deleteQueries)
            .Input(x => x.CanGoBack).FromWorkflow(InputCanGoBack)
            .Input(x => x.CategoryId).FromWorkflow(InputCategoryId)
            .SetUniqueWorkflowStepId(WorkflowIds.SearchQueryByCategoryIdWorkflow)
            .UseDashboardComponentConfigurationFrom(createConfig);

            createQuery
            .Edge(x => x.Canceled).MapsTo(EdgeCanceled)
            .Edge(x => x.Saved).MapsTo(selectQuery)
            .Edge(x => x.Back).MapsTo(selectQuery)
            .Input(x => x.CategoryId).FromWorkflow(InputCategoryId)
            .UseDashboardComponentConfigurationFrom(createConfig);

            deleteQueries
            .Edge(x => x.Deleted).MapsTo(selectQuery)
            .Input(x => x.Ids).From(selectQuery).Output(x => x.MultiSelectIds);

            invokeWorkflow
            .Edge(x => x.Done).MapsTo(selectQuery)
            .Edge(x => x.Canceled).MapsTo(EdgeCanceled)
            .Edge(x => x.Failed).MapsTo(EdgeFailed)
            .Input(x => x.QueryId).From(selectQuery).Output(x => x.SingleSelectId);

            return(WorkflowBuilder.Create()
                   .WithId(WorkflowIds.SearchQueryByCategoryIdWorkflow)
                   .WithDefinition(nameof(WorkflowIds.SearchQueryByCategoryIdWorkflow))
                   .WithEdges(EdgeDone, EdgeCanceled, EdgeFailed)
                   .AddInput <long>(InputCategoryId)
                   .AddInput <bool>(InputCanGoBack)
                   .WithRequiredRole(requiredRole)
                   .StartWith(createConfig));
        }
예제 #6
0
        public static Workflow Build(string requiredRole)
        {
            var edit = new StepBuilder <IEditSettingsStep>();

            edit.Edge(x => x.Canceled).MapsTo(EdgeCanceled)
            .Edge(x => x.Saved).MapsTo(edit)
            .Edge(x => x.Back).MapsTo(edit)
            .Input <object>(x => x.Id).Constant("1");

            return(WorkflowBuilder.Create()
                   .WithId(WorkflowIds.SettingsWorkflow)
                   .WithDefinition(nameof(WorkflowIds.SettingsWorkflow))
                   .WithEdges(EdgeDone, EdgeCanceled, EdgeFailed)
                   .WithRequiredRole(requiredRole)
                   .StartWith(edit));
        }
예제 #7
0
        public static Workflow Build(string requiredRole)
        {
            var select   = new StepBuilder <ISelectScheduleStep>();
            var create   = new StepBuilder <ICreateScheduleStep>();
            var edit     = new StepBuilder <IEditScheduleStep>();
            var redirect = new StepBuilder <IRedirectSelectOrCreated>();
            var delete   = new StepBuilder <IDeleteScheduleStep>();

            select
            .Edge(x => x.Back).MapsTo(EdgeDone)
            .Edge(x => x.Canceled).MapsTo(EdgeCanceled)
            .Edge(x => x.Create).MapsTo(create)
            .Edge(x => x.Edit).MapsTo(redirect)
            .Edge(x => x.Delete).MapsTo(delete)
            .Input(x => x.CanGoBack).Constant(false)
            .SetUniqueWorkflowStepId(WorkflowIds.ScheduleWorkflow);

            create
            .Edge(x => x.Canceled).MapsTo(EdgeCanceled)
            .Edge(x => x.Saved).MapsTo(redirect)
            .Edge(x => x.Back).MapsTo(select);

            redirect
            .Edge(x => x.Next).MapsTo(edit)
            .Edge(x => x.NotSet).MapsTo(select)
            .Input(x => x.CreatedId).From(create).Output(x => x.Id)
            .Input(x => x.SelectedId).From(select).Output(x => x.SingleSelectId);

            edit
            .Edge(x => x.Canceled).MapsTo(EdgeCanceled)
            .Edge(x => x.Saved).MapsTo(edit)
            .Edge(x => x.Back).MapsTo(select)
            .Input(x => x.Id).From(redirect).Output(x => x.RedirectId);

            delete
            .Edge(x => x.Deleted).MapsTo(select)
            .Input(x => x.Ids).From(select).Output(x => x.MultiSelectIds);

            return(WorkflowBuilder.Create()
                   .WithId(WorkflowIds.ScheduleWorkflow)
                   .WithDefinition(nameof(WorkflowIds.ScheduleWorkflow))
                   .WithEdges(EdgeDone, EdgeCanceled, EdgeFailed)
                   .WithRequiredRole(requiredRole)
                   .StartWith(select));
        }
예제 #8
0
        public static Workflow Build(string requiredRole)
        {
            var selectQuery    = new StepBuilder <ISelectSearchQueryStep>();
            var createQuery    = new StepBuilder <ICreateSearchQueryStep>();
            var deleteQueries  = new StepBuilder <IDeleteSearchQueryStep>();
            var invokeWorkflow = new StepBuilder <IInvokeSearchQueryByIdWorkflowStep>();

            selectQuery
            .Edge(x => x.Back).MapsTo(EdgeDone)
            .Edge(x => x.Canceled).MapsTo(EdgeCanceled)
            .Edge(x => x.Create).MapsTo(createQuery)
            .Edge(x => x.Edit).MapsTo(invokeWorkflow)
            .Edge(x => x.Delete).MapsTo(deleteQueries)
            .Input(x => x.CanGoBack).Constant(false)
            .SetUniqueWorkflowStepId(WorkflowIds.SearchQueryWorkflow)
            .UseGenericDashboardComponentConfiguration(WorkflowIds.SearchQueryWorkflow, "api/cea/searchqueries/count", DAL.WebApplication.CatchEmAll_SearchQueries.Key);

            createQuery
            .Edge(x => x.Canceled).MapsTo(EdgeCanceled)
            .Edge(x => x.Saved).MapsTo(selectQuery)
            .Edge(x => x.Back).MapsTo(selectQuery)
            .UseDashboardComponentConfigurationFrom(selectQuery);

            deleteQueries
            .Edge(x => x.Deleted).MapsTo(selectQuery)
            .Input(x => x.Ids).From(selectQuery).Output(x => x.MultiSelectIds);

            invokeWorkflow
            .Edge(x => x.Done).MapsTo(selectQuery)
            .Edge(x => x.Canceled).MapsTo(EdgeCanceled)
            .Edge(x => x.Failed).MapsTo(EdgeFailed)
            .Input(x => x.QueryId).From(selectQuery).Output(x => x.SingleSelectId);

            return(WorkflowBuilder.Create()
                   .WithId(WorkflowIds.SearchQueryWorkflow)
                   .WithDefinition(nameof(WorkflowIds.SearchQueryWorkflow))
                   .WithEdges(EdgeDone, EdgeCanceled, EdgeFailed)
                   .WithRequiredRole(requiredRole)
                   .StartWith(selectQuery));
        }
예제 #9
0
        public static Workflow Build(string requiredRole)
        {
            var createConfig          = new StepBuilder <ICreateDashboardComponentConfigurationStep>();
            var selectResult          = new StepBuilder <ISelectSearchResultStep>();
            var selectArchivedResult  = new StepBuilder <ISelectArchivedSearchResultStep>();
            var updateQuery           = new StepBuilder <IUpdateQueryFromSourceStep>();
            var deleteResults         = new StepBuilder <IDeleteSearchResultStep>();
            var deleteArchivedResults = new StepBuilder <IDeleteSearchResultStep>("DeleteArchivedResults");
            var viewResult            = new StepBuilder <IViewSearchResultStep>();
            var viewArchivedResult    = new StepBuilder <IViewSearchResultStep>("ViewArchivedResult");
            var updateResult          = new StepBuilder <IUpdateResultFromSourceStep>();
            var editQuery             = new StepBuilder <IEditSearchQueryStep>();

            createConfig
            .Edge(x => x.Next).MapsTo(selectResult)
            .Input(x => x.QueryId).FromWorkflow(InputQueryId);

            selectResult
            .Edge(x => x.Back).MapsTo(EdgeDone)
            .Edge(x => x.UpdateFromSource).MapsTo(updateQuery)
            .Edge(x => x.Canceled).MapsTo(EdgeCanceled)
            .Edge(x => x.Create).MapsTo(selectResult)
            .Edge(x => x.Edit).MapsTo(viewResult)
            .Edge(x => x.Delete).MapsTo(deleteResults)
            .Edge(x => x.ShowArchive).MapsTo(selectArchivedResult)
            .Edge(x => x.EditQuery).MapsTo(editQuery)
            .Input(x => x.CanGoBack).FromWorkflow(InputCanGoBack)
            .Input(x => x.QueryId).FromWorkflow(InputQueryId)
            .SetUniqueWorkflowStepId(WorkflowIds.SearchQueryByIdWorkflow)
            .UseDashboardComponentConfigurationFrom(createConfig);

            selectArchivedResult
            .Edge(x => x.Back).MapsTo(selectResult)
            .Edge(x => x.Canceled).MapsTo(EdgeCanceled)
            .Edge(x => x.Create).MapsTo(EdgeFailed)
            .Edge(x => x.Edit).MapsTo(viewArchivedResult)
            .Edge(x => x.Delete).MapsTo(deleteArchivedResults)
            .Input(x => x.CanGoBack).Constant(true)
            .Input(x => x.QueryId).FromWorkflow(InputQueryId)
            .SetUniqueWorkflowStepId(WorkflowIds.SearchQueryByIdWorkflow)
            .UseDashboardComponentConfigurationFrom(createConfig);

            updateQuery
            .Edge(x => x.Next).MapsTo(selectResult)
            .Edge(x => x.QueryNotFound).MapsTo(EdgeFailed)
            .Input(x => x.Id).FromWorkflow(InputQueryId)
            .Input(x => x.IsUserInitiated).Constant(true);

            deleteResults
            .Edge(x => x.Deleted).MapsTo(selectResult)
            .Input(x => x.Ids).From(selectResult).Output(x => x.MultiSelectIds);

            deleteArchivedResults
            .Edge(x => x.Deleted).MapsTo(selectArchivedResult)
            .Input(x => x.Ids).From(selectArchivedResult).Output(x => x.MultiSelectIds);

            viewResult
            .Edge(x => x.Canceled).MapsTo(EdgeCanceled)
            .Edge(x => x.Back).MapsTo(selectResult)
            .Edge(x => x.Saved).MapsTo(viewResult)
            .Edge(x => x.UpdateFromSource).MapsTo(updateResult)
            .Input(x => x.Id).From(selectResult).Output(x => x.SingleSelectId);

            viewArchivedResult
            .Edge(x => x.Canceled).MapsTo(EdgeCanceled)
            .Edge(x => x.Back).MapsTo(selectArchivedResult)
            .Edge(x => x.Saved).MapsTo(viewArchivedResult)
            .Edge(x => x.UpdateFromSource).MapsTo(EdgeFailed)
            .Input(x => x.Id).From(selectArchivedResult).Output(x => x.SingleSelectId);

            updateResult
            .Edge(x => x.Next).MapsTo(viewResult)
            .Edge(x => x.ResultNotFound).MapsTo(EdgeFailed)
            .Input(x => x.Id).From(selectResult).Output(x => x.SingleSelectId)
            .Input(x => x.IsUserInitiated).Constant(true);

            editQuery
            .Edge(x => x.Saved).MapsTo(editQuery)
            .Edge(x => x.Back).MapsTo(selectResult)
            .Edge(x => x.Canceled).MapsTo(EdgeCanceled)
            .Input(x => x.Id).FromWorkflow(InputQueryId)
            .UseDashboardComponentConfigurationFrom(createConfig);

            return(WorkflowBuilder.Create()
                   .WithId(WorkflowIds.SearchQueryByIdWorkflow)
                   .WithDefinition(nameof(WorkflowIds.SearchQueryByIdWorkflow))
                   .WithEdges(EdgeDone, EdgeCanceled, EdgeFailed)
                   .AddInput <long>(InputQueryId)
                   .AddInput <bool>(InputCanGoBack)
                   .WithRequiredRole(requiredRole)
                   .StartWith(createConfig));
        }
예제 #10
0
        public WorkflowBuilder GetWorkflowBuilder()
        {
            MongoConfiguration.Initialize();

            return(WorkflowBuilder.Create(this._configuration.Token, this._context, typeof(WatchmanBot).Assembly)
                   .SetDefaultMiddlewares()
                   .AddOnReadyHandlers(builder =>
            {
                builder
                .AddHandler(() => Task.Run(() => Log.Information("Bot started and logged in...")))
                .AddFromIoC <ConfigurationService>(configurationService => configurationService.InitDefaultConfigurations)
                .AddFromIoC <CustomCommandsLoader>(customCommandsLoader => customCommandsLoader.InitDefaultCustomCommands)
                .AddFromIoC <HelpDataCollectorService, HelpDBGeneratorService>((dataCollector, helpService) => () =>
                {
                    Task.Run(() => helpService.FillDatabase(dataCollector.GetCommandsInfo(typeof(WatchmanBot).Assembly)));
                    return Task.CompletedTask;
                })
                .AddFromIoC <UnmutingExpiredMuteEventsService, DiscordServersService>((unmutingService, serversService) => async() =>
                {
                    var servers = (await serversService.GetDiscordServers()).ToList();
                    servers.ForEach(unmutingService.UnmuteUsersInit);
                })
                .AddFromIoC <ResponsesInitService>(responsesService => async() =>
                {
                    await responsesService.InitNewResponsesFromResources();
                })
                .AddFromIoC <InitializationService, DiscordServersService>((initService, serversService) => () =>
                {
                    var stopwatch = Stopwatch.StartNew();

                    // when bot was offline for less than 5 minutes, it doesn't make sense to init all servers
                    if (WorkflowBuilder.DisconnectedTimes.LastOrDefault() > DateTime.Now.AddMinutes(-5))
                    {
                        Log.Information("Bot was connected less than 5 minutes ago");
                        return Task.CompletedTask;
                    }
                    var servers = serversService.GetDiscordServers().Result;
                    Task.WaitAll(servers.Select(async server =>
                    {
                        Log.Information($"Initializing server: {server.Name}");
                        await initService.InitServer(server);
                        Log.Information($"Done server: {server.Name}");
                    }).ToArray());

                    Log.Information(stopwatch.ElapsedMilliseconds.ToString());
                    return Task.CompletedTask;
                })
                .AddHandler(() => Task.Run(() => Log.Information("Bot has done every Ready tasks.")));
            })
                   .AddOnUserJoinedHandlers(builder =>
            {
                builder
                .AddFromIoC <WelcomeUserService>(x => x.WelcomeUser)
                .AddFromIoC <MutingRejoinedUsersService>(x => x.MuteAgainIfNeeded);
            })
                   .AddOnDiscordServerAddedBot(builder =>
            {
                builder
                .AddFromIoC <InitializationService>(initService => initService.InitServer);
            })
                   .AddOnWorkflowExceptionHandlers(builder =>
            {
                builder
                .AddFromIoC <ExceptionHandlerService>(x => x.LogException)
                .AddHandler(this.PrintDebugExceptionInfo, onlyOnDebug: true)
                .AddHandler(this.PrintExceptionOnConsole);
            })
                   .Build());
        }
        public static Workflow Build()
        {
            var startSchedule        = new StepBuilder <IStartScheduleStep>();
            var loadQuery            = new StepBuilder <ILoadQueryStep>();
            var updateQuery          = new StepBuilder <IUpdateQueryFromSourceStep>();
            var loadResult           = new StepBuilder <ILoadResultStep>();
            var updateResult         = new StepBuilder <IUpdateResultFromSourceStep>();
            var loadOutdatedResult   = new StepBuilder <ILoadOutdatedResultStep>();
            var updateOutdatedResult = new StepBuilder <IUpdateResultFromSourceStep>("UpdateOutdatedResult");
            var loadResults          = new StepBuilder <ILoadResultsStep>();
            var filterResults        = new StepBuilder <IFilterResultsStep>();
            var sendEmail            = new StepBuilder <ISendEmailStep>();
            var triggerWebhook       = new StepBuilder <ITriggerIftttWebhookStep>();
            var saveResults          = new StepBuilder <ISaveResultsStep>();

            startSchedule
            .Edge(x => x.GetNewResults).MapsTo(loadQuery)
            .Edge(x => x.UpdateOpenResults).MapsTo(loadResult)
            .Edge(x => x.UpdateOutdatedResults).MapsTo(loadOutdatedResult)
            .Edge(x => x.ScheduleNotFound).MapsTo(EdgeFailed)
            .Input(x => x.Batch).FromWorkflow(InputName);

            loadQuery
            .Edge(x => x.Next).MapsTo(updateQuery)
            .Edge(x => x.NoWorkToDo).MapsTo(EdgeDone)
            .Input(x => x.Options).From(startSchedule).Output(x => x.Options);

            updateQuery
            .Edge(x => x.Next).MapsTo(loadResults)
            .Edge(x => x.QueryNotFound).MapsTo(EdgeFailed)
            .Input(x => x.Id).From(loadQuery).Output(x => x.QueryId)
            .Input(x => x.IsUserInitiated).Constant(false);

            loadResult
            .Edge(x => x.Next).MapsTo(updateResult)
            .Edge(x => x.NoWorkToDo).MapsTo(EdgeDone)
            .Input(x => x.Options).From(startSchedule).Output(x => x.Options);

            updateResult
            .Edge(x => x.Next).MapsTo(EdgeDone)
            .Edge(x => x.ResultNotFound).MapsTo(EdgeFailed)
            .Input(x => x.Id).From(loadResult).Output(x => x.ResultId)
            .Input(x => x.IsUserInitiated).Constant(false);

            loadOutdatedResult
            .Edge(x => x.Next).MapsTo(updateOutdatedResult)
            .Edge(x => x.NoWorkToDo).MapsTo(EdgeDone)
            .Input(x => x.Options).From(startSchedule).Output(x => x.Options);

            updateOutdatedResult
            .Edge(x => x.Next).MapsTo(EdgeDone)
            .Edge(x => x.ResultNotFound).MapsTo(EdgeFailed)
            .Input(x => x.Id).From(loadOutdatedResult).Output(x => x.ResultId)
            .Input(x => x.IsUserInitiated).Constant(false);

            loadResults
            .Edge(x => x.Next).MapsTo(filterResults)
            .Edge(x => x.NoWorkToDo).MapsTo(EdgeDone)
            .Input(x => x.QueryId).From(loadQuery).Output(x => x.QueryId);

            filterResults
            .Edge(x => x.Next).MapsTo(sendEmail)
            .Input(x => x.QueryId).From(loadQuery).Output(x => x.QueryId)
            .Input(x => x.ResultIds).From(loadResults).Output(x => x.ResultIds);

            sendEmail
            .Edge(x => x.Next).MapsTo(triggerWebhook)
            .Input(x => x.ResultIds).From(filterResults).Output(x => x.FilteredResultIds);

            triggerWebhook
            .Edge(x => x.Next).MapsTo(saveResults)
            .Input(x => x.ResultIds).From(filterResults).Output(x => x.FilteredResultIds);

            saveResults
            .Edge(x => x.Next).MapsTo(EdgeDone)
            .Input(x => x.ResultIds).From(loadResults).Output(x => x.ResultIds);

            return(WorkflowBuilder.Create()
                   .WithId(WorkflowIds.ExecuteScheduleWorkflow)
                   .WithDefinition(nameof(WorkflowIds.ExecuteScheduleWorkflow))
                   .WithEdges(EdgeDone, EdgeCanceled, EdgeFailed)
                   .AddInput <BatchedParameter>(InputName)
                   .StartWith(startSchedule));
        }