### Install Elsa [extension-name] NuGet Package Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/README-TEMPLATE.md Install the necessary NuGet packages for the Elsa [extension-name] extension. Use Implementation1 for initial setup. ```bash dotnet add package Elsa.[extension-name].Implementation1 ``` -------------------------------- ### Manage Channel Example Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/_autodocs/api-reference/Slack-Extension.md Example demonstrating how to create a new Slack channel and then set its topic. The ChannelId from creation is used for setting the topic. ```csharp // Create channel var create = new CreateChannel { Token = new Input { Value = "xoxb-..." }, ChannelName = new Input { Value = "project-team" }, IsPrivate = new Input { Value = true } }; await create.ExecuteAsync(context); // Set topic var setTopic = new SetChannelTopic { Token = new Input { Value = "xoxb-..." }, ChannelId = new Input { Value = context.Get(create.Channel).Id }, Topic = new Input { Value = "Project coordination and updates" } }; await setTopic.ExecuteAsync(context); ``` -------------------------------- ### Install Elsa Agents Packages Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/src/modules/agents/README.md Install the core and activities packages for the Elsa Agents module using the .NET CLI. ```bash dotnet add package Elsa.Agents.Core dotnet add package Elsa.Agents.Activities ``` -------------------------------- ### Search and React to Messages Example Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/_autodocs/api-reference/Slack-Extension.md Example of searching for messages containing a specific query and then adding a reaction to each found message. Requires valid Token, Channel, and MessageTimestamp. ```csharp var search = new SearchForMessage { Token = new Input { Value = "xoxb-..." }, Query = new Input { Value = "deployment" } }; await search.ExecuteAsync(context); var results = context.Get(search.Results); foreach (var msg in results) { var addReaction = new AddReaction { Token = new Input { Value = "xoxb-..." }, Channel = new Input { Value = msg.Channel }, MessageTimestamp = new Input { Value = msg.Ts }, Emoji = new Input { Value = "rocket" } }; await addReaction.ExecuteAsync(context); } ``` -------------------------------- ### Agent Activity Input/Output Example Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/src/modules/agents/README.md Illustrates the expected inputs and outputs for a configured agent activity, such as CustomerSupport. ```text CustomerSupport Activity: Inputs: - question (String): The customer's question Outputs: - Output (String): The agent's response ``` -------------------------------- ### Install Elsa.Sql NuGet Packages Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/src/modules/sql/README.md Install the required Elsa.Sql NuGet packages for your specific database client. Replace '' with your database type (e.g., MySql, PostgreSql, Sqlite, SqlServer). ```bash dotnet add package Elsa.Sql. ``` -------------------------------- ### Install Elsa Extensions Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/_autodocs/README.md Install desired Elsa extensions using the .NET CLI. Each extension is provided as a separate NuGet package. ```bash dotnet add package Elsa.Sql dotnet add package Elsa.Slack dotnet add package Elsa.DevOps.GitHub dotnet add package Elsa.Ldap dotnet add package Elsa.Data.Csv ``` -------------------------------- ### Usage Example for Output Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/_autodocs/types.md Shows how to retrieve a value from an activity's output using the ActivityExecutionContext. ```csharp var createdIssue = context.Get(createIssueActivity.CreatedIssue); ``` -------------------------------- ### Install Elsa Extension Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/README.md Use the .NET CLI to add a specific Elsa extension package to your project. ```sh dotnet add package Elsa.Gmail ``` -------------------------------- ### Agent Tool Configuration Example Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/src/modules/agents/README.md Shows how to define an agent's capabilities by specifying which plugins, other agents, and Elsa activities it can use as tools. ```json { "Agents": [ { "Name": "ResearchAgent", "Plugins": ["WebSearch", "DocumentQuery"], "Agents": ["FactChecker", "Summarizer"] } ] } ``` -------------------------------- ### Add Elsa.DevOps.GitHub Package Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/src/modules/devops/Elsa.DevOps.GitHub/README.md Install the GitHub extension package using the .NET CLI. ```bash dotnet add package Elsa.DevOps.GitHub ``` -------------------------------- ### Install Elsa.Data.Csv NuGet Package Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/src/modules/data/Elsa.Data.Csv/README.md Install the necessary NuGet package for CSV processing capabilities in your project. ```bash dotnet add package Elsa.Data.Csv ``` -------------------------------- ### Usage Example for Input Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/_autodocs/types.md Demonstrates how to instantiate and assign values to an Input for activity properties like Title and Owner. ```csharp var activity = new CreateIssue { Title = new Input { Value = "Bug in dashboard" }, Owner = new Input { Value = "myorg" } }; ``` -------------------------------- ### Install Elsa.Ldap NuGet Package Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/src/modules/ldap/Elsa.Ldap/README.md Install the Elsa.Ldap NuGet package to add LDAP capabilities to your Elsa Workflows project. ```bash dotnet add package Elsa.Ldap ``` -------------------------------- ### Create Release Notes from Milestones Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/_autodocs/api-reference/GitHub-Extension.md This example shows how to retrieve a milestone, find all closed issues within that milestone, and then prepare to generate release notes. You will need to implement the logic for generating notes from the closed issues. ```csharp var getMilestone = new GetMilestone { Token = new Input { Value = "ghp_..." }, Owner = new Input { Value = "myorg" }, Repository = new Input { Value = "myrepo" }, MilestoneNumber = new Input { Value = 1 } }; await getMilestone.ExecuteAsync(context); var milestone = context.Get(getMilestone.Milestone); // Find all closed issues in milestone var search = new SearchIssues { Token = new Input { Value = "ghp_..." }, Query = new Input { Value = $"milestone:{milestone.Number} is:closed" } }; await search.ExecuteAsync(context); var closedIssues = context.Get(search.Issues); // Generate release notes from issues... ``` -------------------------------- ### Multi-Environment Elsa Setup Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/_autodocs/README.md Configures Elsa to use different database providers (PostgreSQL for Production, SQLite for Development) based on the environment. ```csharp var environment = configuration["ASPNETCORE_ENVIRONMENT"]; services.AddElsa(elsa => { if (environment == "Production") { elsa.AddSql(sql => sql.UsePostgreSql()); // PostgreSQL in prod } else { elsa.AddSql(sql => sql.UseSqlite()); // SQLite in dev } }); ``` -------------------------------- ### Send Channel Message Example Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/_autodocs/api-reference/Slack-Extension.md Example of sending a message to a Slack channel using the CreateMessage activity. Ensure the Token, Channel, and Text are correctly provided. ```csharp var message = new CreateMessage { Token = new Input { Value = "xoxb-..." }, Channel = new Input { Value = "general" }, Text = new Input { Value = "Workflow execution completed" } }; await message.ExecuteAsync(context); var msgTs = context.Get(message.MessageTimestamp); ``` -------------------------------- ### Example Extension Directory Structure Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/README-TEMPLATE.md Illustrates the recommended folder organization for an Elsa extension. Copy this README template into the root of your extension's directory. ```text [group-name]/ ├── README.md ├── Elsa.[extension-name]/ │ ├── Services/ │ ├── Activities/ │ ├── AI/ └── Elsa.[extension-name].Implementation/ ├── Services/ ├── Activities/ ├── AI/ ``` -------------------------------- ### Use Configuration Builders Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/_autodocs/configuration.md Configure your application using `ConfigurationBuilder` to load settings from various sources like JSON files, user secrets, and environment variables. This example shows how to build the configuration and then retrieve a connection string for Elsa. ```csharp var builder = new ConfigurationBuilder() .AddJsonFile("appsettings.json") .AddUserSecrets() .AddEnvironmentVariables() .Build(); services.AddElsa(elsa => { var dbConn = builder.GetConnectionString("DefaultConnection"); // Use dbConn in LDAP/SQL configuration }); ``` -------------------------------- ### DirectoryAttribute Usage Example Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/_autodocs/types.md Provides examples of creating DirectoryAttribute instances for common LDAP attributes like 'cn' (common name) and 'mail'. ```csharp var cnAttribute = new DirectoryAttribute { Name = "cn", Values = new[] { Encoding.UTF8.GetBytes("John Smith") } }; var mailAttribute = new DirectoryAttribute { Name = "mail", Values = new[] { Encoding.UTF8.GetBytes("john@example.com") } }; ``` -------------------------------- ### Example CSV Record Dictionary Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/_autodocs/types.md Illustrates the creation of a dictionary representing a CSV record with string keys and object values. ```csharp var record = new Dictionary { { "Name", "John Doe" }, { "Email", "john@example.com" }, { "Age", "30" } }; ``` -------------------------------- ### Configure Slack Activity with Token Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/_autodocs/configuration.md Example of configuring a Slack activity, such as CreateMessage, with a Slack API token retrieved from secure storage. The token is provided via the Token input. ```csharp // Token from secure storage var slackToken = await secretStore.GetAsync("slack-bot-token"); var sendMessage = new CreateMessage { Token = new Input { Value = slackToken }, Channel = new Input { Value = "C123456" }, Text = new Input { Value = "Workflow completed" } }; ``` -------------------------------- ### Move LDAP Entry Example Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/_autodocs/api-reference/LDAP-Extension.md Demonstrates how to move an LDAP entry to a new location and optionally rename its RDN. Ensure the 'Default' LDAP connection is configured. ```csharp // Move user from Users OU to Archive OU and rename RDN var move = new MoveLdapEntry { ConnectionName = new Input { Value = "Default" }, CurrentDn = new Input { Value = "cn=jsmith,ou=Users,dc=example,dc=com" }, NewRdn = new Input { Value = "cn=smith_john_archived" }, NewParentDn = new Input { Value = "ou=Archive,dc=example,dc=com" } }; await move.ExecuteAsync(context); ``` -------------------------------- ### Register Kafka Module with Consumer Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/src/modules/servicebus/Elsa.ServiceBus.Kafka/Documentation.md Register the Kafka module and configure a consumer. This example sets up a consumer that deserializes JSON messages into dynamic objects using ExpandoObjectConsumerFactory. ```csharp services.AddElsa(elsa => { elsa.UseKafka(kafka => { kafka.ConfigureOptions(options => { // Declare a consumer that deserializes JSON messages into dynamic objects. options.Consumers.Add(new ConsumerDefinition { Id = "my-consumer", Name = "My Consumer", FactoryType = typeof(ExpandoObjectConsumerFactory), Config = new ConsumerConfig { BootstrapServers = "localhost:9092", GroupId = "workflow-engine", AutoOffsetReset = AutoOffsetReset.Earliest } }); }); }); }); ``` -------------------------------- ### Configure Kafka Producer and Topic Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/src/modules/servicebus/Elsa.ServiceBus.Kafka/Documentation.md Declare a producer and a topic for sending messages. This setup is required before using the ProduceMessage activity. ```csharp options.Topics.Add(new TopicDefinition { Id = "replies", Name = "order-replies" }); options.Producers.Add(new ProducerDefinition { Id = "my-producer", Name = "My Producer", FactoryType = typeof(ExpandoObjectProducerFactory), Config = new ProducerConfig { BootstrapServers = "localhost:9092" } }); ``` -------------------------------- ### Configure GitHub Activity with Token Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/_autodocs/configuration.md Example of configuring a GitHub activity, such as CreateIssue, with a GitHub personal access token retrieved from secure storage. The token is provided via the Token input. ```csharp var githubToken = await secretStore.GetAsync("github-pat"); var createIssue = new CreateIssue { Token = new Input { Value = githubToken }, Owner = new Input { Value = "myorg" }, Repository = new Input { Value = "myrepo" }, Title = new Input { Value = "Deployment completed" } }; ``` -------------------------------- ### EvaluatedQuery Usage Example Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/_autodocs/types.md Demonstrates how to instantiate and use the EvaluatedQuery class to define a parameterized SQL query. ```csharp var evaluated = new EvaluatedQuery( "SELECT * FROM users WHERE id = @userId", new Dictionary { { "@userId", 123 } } ); ``` -------------------------------- ### Execute SQL Query Activity Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/_autodocs/api-reference/SQL-Extension.md An example workflow step that executes a SQL query and retrieves results. Ensure the 'Client' and 'ConnectionString' are correctly configured. ```csharp // Workflow that queries users and counts results var userId = context.GetVariable("userId"); // Step 1: Execute query var queryActivity = new SqlQuery { Client = new Input { Value = "DefaultClient" }, ConnectionString = new Input { Value = /* connection string */ }, Query = new Input { Value = "SELECT * FROM users WHERE id = {{ userId }}" } }; await queryActivity.ExecuteAsync(context); var results = context.Get(queryActivity.Results); // Step 2: Get row count var countActivity = new SqlSingleValue { Client = new Input { Value = "DefaultClient" }, Command = new Input { Value = "SELECT COUNT(*) FROM users WHERE status = 'active'" } }; await countActivity.ExecuteAsync(context); var count = context.Get(countActivity.Result); ``` -------------------------------- ### Define Agents using JSON Configuration Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/src/modules/agents/README.md Configure agents, including API keys, services, and agent definitions, within the `appsettings.json` file. This method is suitable for declarative setup. ```json { "Agents": { "ApiKeys": [ { "Name": "OpenAI", "Value": "sk-..." } ], "Services": [ { "Name": "OpenAIChat", "Type": "OpenAIChatCompletion", "ApiKeyName": "OpenAI", "Model": "gpt-4" } ], "Agents": [ { "Name": "CustomerSupport", "Description": "Helpful customer support agent", "Services": ["OpenAIChat"], "FunctionName": "HandleCustomerQuery", "PromptTemplate": "You are a helpful customer support agent. Help the user with their question: {{question}}", "InputVariables": [ { "Name": "question", "Type": "String", "Description": "The customer's question" } ], "OutputVariable": { "Type": "String", "Description": "The agent's response" }, "Plugins": ["WebSearch", "KnowledgeBase"] } ] } } ``` -------------------------------- ### Enable Elsa Extension in Workflows Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/README.md Configure your Elsa Workflows application to use an installed extension by adding its services during startup. ```csharp services.AddElsa(elsa => elsa.AddGmail()); ``` -------------------------------- ### Register Elsa Extensions Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/_autodocs/README.md Configure Elsa services to include various extensions. This example demonstrates registering SQL database providers (MySQL, PostgreSQL, SQLite, SQL Server), Slack, GitHub, LDAP, and CSV data processing. ```csharp services.AddElsa(elsa => { // SQL databases elsa.AddSql(sql => { sql.UseMySql(); sql.UsePostgreSql(); sql.UseSqlite(); sql.UseSqlServer(); }); // Communication elsa.AddSlack(); elsa.AddGitHub(); // Directory elsa.AddLdap(ldap => { ldap.ConfigureConnection("Default", options => { options.ServerAddress = "ldap://ldap.example.com"; options.BaseDn = "dc=example,dc=com"; }); }); // Data processing elsa.UseCsv(); }); ``` -------------------------------- ### Configure LDAP Connection in Program.cs Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/src/modules/ldap/Elsa.Ldap/README.md Register the LDAP extension and configure connection options within your application's startup code. This example shows how to add a default connection using configuration values. ```csharp using Elsa.Extensions; using Elsa.Ldap.Extensions; services.AddElsa(elsa => { elsa.UseLdap(ldap => { ldap.ConfigureOptions = options => { options.AddDefaultConnection(new Elsa.Ldap.Options.LdapConnectionOptions { BindDn = configuration.GetValue("Ldap:BindDn"), BindPassword = configuration.GetValue("Ldap:BindPassword"), Host = configuration.GetValue("Ldap:Host")!, Port = configuration.GetValue("Ldap:Port"), UseSsl = configuration.GetValue("Ldap:UseSsl"), }); }; }); } ``` -------------------------------- ### Register Kafka Feature Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/src/modules/servicebus/Elsa.ServiceBus.Kafka/Documentation.md Call `UseKafka()` on the Elsa feature builder during application startup to enable Kafka integration. All consumers start automatically via a hosted startup task. ```csharp services.AddElsa(elsa => { elsa.UseKafka(kafka => { kafka.ConfigureOptions(options => { // populate consumers, producers, topics, schema registries … }); }); }); ``` -------------------------------- ### Compare LDAP Entry Attribute Example Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/_autodocs/api-reference/LDAP-Extension.md Shows how to compare an attribute's value against a specified value for a given LDAP entry. This is useful for conditional logic based on entry data. The 'Default' connection is used. ```csharp // Check if email address is current var compare = new CompareLdapEntry { ConnectionName = new Input { Value = "Default" }, EntryDn = new Input { Value = "cn=jsmith,ou=Users,dc=example,dc=com" }, AttributeName = new Input { Value = "mail" }, AttributeValue = new Input { Value = "john@example.com" } }; await compare.ExecuteAsync(context); var isMatch = context.Get(compare.Result); ``` -------------------------------- ### SearchScope Usage Example Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/_autodocs/types.md Demonstrates setting the SearchScope property within a SearchLdapEntry object. The Subtree scope is commonly used for comprehensive searches. ```csharp var search = new SearchLdapEntry { BaseDn = new Input { Value = "ou=Users,dc=example,dc=com" }, Filter = new Input { Value = "(objectClass=person)" }, SearchScope = new Input { Value = SearchScope.Subtree } }; ``` -------------------------------- ### Execute SQL Command and Check Row Count Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/_autodocs/api-reference/SQL-Extension.md An example workflow step that executes an SQL command (e.g., UPDATE) and retrieves the number of affected rows. Sets a variable 'updateSuccess' based on the count. ```csharp // Update and check how many rows were affected var updateActivity = new SqlCommand { Client = new Input { Value = "DefaultClient" }, Command = new Input { Value = "UPDATE users SET last_login = GETDATE() WHERE id = {{ userId }}" } }; await updateActivity.ExecuteAsync(context); var affectedRows = context.Get(updateActivity.Result); if (affectedRows > 0) { context.SetVariable("updateSuccess", true); } ``` -------------------------------- ### Connection String Configuration Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/_autodocs/README.md Illustrates how to configure and retrieve database connection strings from `appsettings.json`. ```json { "ConnectionStrings": { "DefaultConnection": "Server=localhost;Database=mydb;User=sa;Password=..." } } ``` ```csharp // Code var connString = configuration.GetConnectionString("DefaultConnection"); ``` -------------------------------- ### DirectoryAttributeOperation Usage Example Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/_autodocs/types.md Shows how to set the DirectoryAttributeOperation for a ModifyLdapEntry object, using Replace to update attributes. ```csharp var modify = new ModifyLdapEntry { Operation = new Input { Value = DirectoryAttributeOperation.Replace }, Attributes = new Input> { Value = newAttributes } }; ``` -------------------------------- ### OpenTelemetry Configuration (MacOS) Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/src/workbench/Elsa.Server.Web/README.md Environment variables for configuring OpenTelemetry auto-instrumentation on MacOS. Ensure these are set before starting the application. ```bash COR_ENABLE_PROFILING=1 COR_PROFILER={918728DD-259F-4A6A-AC2B-B85E1B658318} CORECLR_PROFILER_PATH=$INSTALL_DIR/osx-x64/OpenTelemetry.AutoInstrumentation.Native.dylib DOTNET_ADDITIONAL_DEPS=$INSTALL_DIR/AdditionalDeps DOTNET_EnableDiagnostics=1 DOTNET_SHARED_STORE=$INSTALL_DIR/store DOTNET_STARTUP_HOOKS=OpenTelemetry.AutoInstrumentation.StartupHook OTEL_DOTNET_AUTO_HOME=$INSTALL_DIR OTEL_DOTNET_AUTO_LOGS_CONSOLE_EXPORTER_ENABLED=true OTEL_DOTNET_AUTO_METRICS_CONSOLE_EXPORTER_ENABLED=true OTEL_DOTNET_AUTO_TRACES_ADDITIONAL_SOURCES=Proto.Actor,Elsa.Workflows OTEL_DOTNET_AUTO_TRACES_CONSOLE_EXPORTER_ENABLED=true OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317 OTEL_EXPORTER_OTLP_PROTOCOL=grpc OTEL_RESOURCE_ATTRIBUTES=service.name=Elsa Server,service.version=3.3.0,service.instance.id=instance-123,deployment.environment=development ``` -------------------------------- ### Invoke Agent in New vs. Legacy Mode Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/src/modules/agents/MIGRATION_GUIDE.md Demonstrates how to invoke an agent using the `AgentInvoker`. Shows the default new Agent Framework mode and the option to use the legacy Semantic Kernel mode. ```csharp // New Agent Framework mode (default) await agentInvoker.InvokeAgentAsync(agentName, input, cancellationToken); // Legacy Semantic Kernel mode (if needed) await agentInvoker.InvokeAgentAsync(agentName, input, useAgentFramework: false, cancellationToken); ``` -------------------------------- ### Register SQL client implementations Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/_autodocs/api-reference/SQL-Extension.md Register different SQL client types with the ClientStore. This allows the system to use specific database drivers based on their registered names. ```csharp var store = new ClientStore(); store.Register("MySql"); store.Register("PostgreSql"); store.Register("Sqlite"); store.Register("SqlServer"); ``` -------------------------------- ### Register SQL Extension Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/_autodocs/api-reference/SQL-Extension.md Registers the SQL extension and configures database clients. Use this during application startup. ```csharp services.AddElsa(elsa => { elsa.AddSql(sql => { // Register database clients sql.UseMySql(); sql.UsePostgreSql(); sql.UseSqlite(); sql.UseSqlServer(); }); }); ``` -------------------------------- ### Get Slack Channel Information Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/_autodocs/api-reference/Slack-Extension.md Retrieves details about a specific Slack channel using its ID. Requires a Slack API token. ```csharp var getChannel = new GetChannel { Token = new Input { Value = "xoxb-..." }, ChannelId = new Input { Value = "C12345" } }; await getChannel.ExecuteAsync(context); var channel = context.Get(getChannel.Channel); ``` -------------------------------- ### Health Check Configuration Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/_autodocs/configuration.md Integrate Elsa extension modules with health checks. This example demonstrates how to add a health check for LDAP connections. ```csharp services.AddHealthChecks() .AddCheck("LDAP", async () => { var factory = serviceProvider.GetRequiredService(); try { using var conn = factory.CreateConnection("Default"); return HealthCheckResult.Healthy(); } catch { return HealthCheckResult.Unhealthy(); } }); ``` -------------------------------- ### Create SQL Client Instance Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/_autodocs/api-reference/SQL-Extension.md Utilize ISqlClientFactory to create instances of ISqlClient for various database providers. Specify the provider name (e.g., "MySql", "PostgreSql") and the connection string. ```csharp var factory = serviceProvider.GetRequiredService(); var mysqlClient = factory.CreateClient("MySql", "Server=localhost;Database=mydb"); var postgresClient = factory.CreateClient("PostgreSql", "Host=localhost;Database=mydb"); ``` -------------------------------- ### Untyped CSV Record Example Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/_autodocs/api-reference/CSV-Extension.md When RecordType is null, CSV records are returned as Dictionary. All values are stored as strings unless explicitly converted. ```csharp // Record structure for header row: "Name,Email,Age" { ["Name"] = "John", ["Email"] = "john@example.com", ["Age"] = "30" } ``` -------------------------------- ### SQL Server Query with Expressions Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/src/modules/sql/README.md Demonstrates how a SQL query with Liquid-like expressions is parameterized for SQL Server. ```sql SELECT * FROM [Users] WHERE [Name] = {{Variable.Name}} AND [Age] > {{Input.Age}}; ``` ```sql SELECT * FROM [Users] WHERE [Name] = @p1 AND [Age] > @p2; ``` -------------------------------- ### Logging Configuration via appsettings.json Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/src/modules/diagnostics/Elsa.Logging/README.md Declaratively configure logging sinks in appsettings.json. Elsa discovers and configures these sinks at startup, specifying type, name, and options for each. ```json { "LoggingFramework": { "Defaults": [ "Console", "FilePretty", "FileJson" ], "Sinks": [ { "Type": "Console", "Name": "Console", "Options": { "MinLevel": "Information", "CategoryFilters": { "Process": "Information", "Process.Nested": "Debug", "Process.Nested.Inner": "Information" }, "Formatter": "Default", "TimestampFormat": "HH:mm:ss ", "DisableColors": true } }, { "Type": "Serilog", "Name": "FilePretty", "Options": { "Path": "App_Data/logs/activity-pretty-.log", "RollingInterval": "Day", "Template": "[{Timestamp:HH:mm:ss} {Level:u}] {Message:lj}{NewLine}{Exception}", "MinLevel": "Information" } }, { "Type": "Serilog", "Name": "FileJson", "Options": { "Path": "App_Data/logs/activity-json-.log", "RollingInterval": "Day", "Formatter": "CompactJson", "MinLevel": "Debug" } } ] } } ``` -------------------------------- ### Define Generic Output Parameter Type Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/_autodocs/types.md The Output type is a generic class used for activity outputs. It allows setting and getting values of type T within the activity context. ```csharp public class Output { public T Get(ActivityExecutionContext context); public void Set(ActivityExecutionContext context, T value); } ``` -------------------------------- ### Configure LDAP Activity Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/_autodocs/configuration.md Instantiate an LDAP activity, such as `SearchLdapEntry`, and specify the `ConnectionName` to reference a pre-configured LDAP connection. The `BaseDn` and `Filter` are required for searching. ```csharp var search = new SearchLdapEntry { ConnectionName = new Input { Value = "Default" }, BaseDn = new Input { Value = "ou=Users,dc=example,dc=com" }, Filter = new Input { Value = "(mail=user@example.com)" } }; ``` -------------------------------- ### Register Elsa.Sql Extension in Program.cs Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/src/modules/sql/README.md Register the Elsa.Sql extension and its clients in your Program.cs file. This enables database integration for Elsa Workflows. Client names are optional and used for identification. ```csharp using Elsa.Extensions; using Elsa.Sql.Extensions; using Elsa.Sql.MySql; using Elsa.Sql.PostgreSql; using Elsa.Sql.Sqlite; using Elsa.Sql.SqlServer; services.AddElsa(elsa => { elsa.UseSql(options => { options.Clients = client => { client.Register("MySql"); client.Register("PostgreSql"); client.Register("Sqlite"); client.Register("Sql Server"); }; }) } ``` -------------------------------- ### ISqlClientFactory.CreateClient Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/_autodocs/api-reference/SQL-Extension.md Creates a SQL client instance for a specified database provider and connection string. ```APIDOC ## ISqlClientFactory.CreateClient ### Description Creates a client instance for a specified database provider using the provided connection string. This allows for interaction with different database systems. ### Method `CreateClient` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```csharp var factory = serviceProvider.GetRequiredService(); var mysqlClient = factory.CreateClient("MySql", "Server=localhost;Database=mydb"); var postgresClient = factory.CreateClient("PostgreSql", "Host=localhost;Database=mydb"); ``` ### Response #### Success Response - **ISqlClient** (`ISqlClient`) - An instance of the SQL client implementing database operations. #### Response Example (No specific example provided, but returns an `ISqlClient` instance) ### Throws - `InvalidOperationException` if the specified client name is not registered. ``` -------------------------------- ### Configure Elsa Agents with OpenAI Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/src/modules/agents/README.md Configure Elsa to use the Agents module, including registering service providers like OpenAI and enabling agent activities. ```csharp services.AddElsa(elsa => { elsa.UseAgents(agents => { // Register service providers (OpenAI, Azure OpenAI, etc.) agents.UseOpenAI(); // Enable agent activities elsa.UseAgentActivities(); }); }); ``` -------------------------------- ### Custom Log Sink Factory Implementation Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/src/modules/diagnostics/Elsa.Logging/README.md Implement a custom ILogSinkFactory to create tailored logging sinks. Register the factory in the DI container and reference it in configuration or code. ```csharp public class MyCustomLogSinkFactory : ILogSinkFactory { public string Type => "MyCustom"; public ILogSink Create(string name, MyCustomOptions options) { // Create and return your custom sink. } } // Register in DI: services.AddScoped(); ``` -------------------------------- ### Strongly-Typed CSV Record Example Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/_autodocs/api-reference/CSV-Extension.md When RecordType specifies a .NET class, CsvHelper deserializes each row into an instance of that type. Automatic type conversion is performed, and property names must match CSV header names (case-insensitive by default). ```csharp public class Person { public string Name { get; set; } public string Email { get; set; } public int Age { get; set; } } // Each record is a Person instance var person = (Person)record; var age = person.Age; // int type ``` -------------------------------- ### Handle SQL Expression Evaluation Errors Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/_autodocs/errors.md Catch FormatException when SQL expression evaluation fails due to malformed Elsa syntax or incorrect parameter formatting. This example highlights a scenario where an invalid Elsa expression within a SQL query would trigger this exception. ```csharp // Expression: "SELECT * FROM users WHERE id = {{ complexExpression }}" // If complexExpression is invalid Elsa syntax, throws FormatException ``` -------------------------------- ### SQL Extension Activities Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/_autodocs/MANIFEST.txt Documentation for activities related to SQL operations, including querying and command execution. ```APIDOC ## SqlQuery Activity ### Description Executes SELECT queries against a SQL database and returns results as a DataSet. ### Method Not applicable (Activity) ### Endpoint Not applicable (Activity) ### Parameters - **Connection String** (string) - Required - The connection string for the database. - **Query** (string) - Required - The SQL SELECT query to execute. - **Parameters** (object) - Optional - Parameters to be used in the query. ### Request Example ```json { "type": "Elsa.Extensions.Activities.SqlQuery", "properties": { "connectionString": "Server=myServerAddress;Database=myDataBase;User Id=myUsername;Password=myPassword;", "query": "SELECT * FROM Users WHERE Status = @status", "parameters": { "status": "Active" } } } ``` ### Response #### Success Response (200) - **DataSet** (object) - The result of the SQL query. #### Response Example ```json { "dataSet": { "Tables": [ { "Columns": [ {"ColumnName": "Id", "DataType": "System.Int32"}, {"ColumnName": "Name", "DataType": "System.String"} ], "Rows": [ {"Id": 1, "Name": "Alice"}, {"Id": 2, "Name": "Bob"} ] } ] } } ``` ``` ```APIDOC ## SqlCommand Activity ### Description Executes INSERT, UPDATE, or DELETE SQL commands and returns the number of affected rows. ### Method Not applicable (Activity) ### Endpoint Not applicable (Activity) ### Parameters - **Connection String** (string) - Required - The connection string for the database. - **Command** (string) - Required - The SQL command to execute. - **Parameters** (object) - Optional - Parameters to be used in the command. ### Request Example ```json { "type": "Elsa.Extensions.Activities.SqlCommand", "properties": { "connectionString": "Server=myServerAddress;Database=myDataBase;User Id=myUsername;Password=myPassword;", "command": "INSERT INTO Logs (Message) VALUES (@message)", "parameters": { "message": "An event occurred." } } } ``` ### Response #### Success Response (200) - **RowsAffected** (integer) - The number of rows affected by the command. #### Response Example ```json { "rowsAffected": 1 } ``` ``` ```APIDOC ## SqlSingleValue Activity ### Description Executes a SQL query that is expected to return a single scalar value. ### Method Not applicable (Activity) ### Endpoint Not applicable (Activity) ### Parameters - **Connection String** (string) - Required - The connection string for the database. - **Query** (string) - Required - The SQL query to execute. - **Parameters** (object) - Optional - Parameters to be used in the query. ### Request Example ```json { "type": "Elsa.Extensions.Activities.SqlSingleValue", "properties": { "connectionString": "Server=myServerAddress;Database=myDataBase;User Id=myUsername;Password=myPassword;", "query": "SELECT COUNT(*) FROM Orders WHERE Status = @status", "parameters": { "status": "Pending" } } } ``` ### Response #### Success Response (200) - **Value** (any) - The single scalar value returned by the query. #### Response Example ```json { "value": 15 } ``` ``` -------------------------------- ### Configure CSV Extension in Program.cs Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/src/modules/data/Elsa.Data.Csv/README.md Register the CSV extension in your application's startup configuration to enable its activities. ```csharp using Elsa.Extensions; services.AddElsa(elsa => { elsa.UseCsv(); }); ``` -------------------------------- ### Register Elsa [extension-name] Extension in Program.cs Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/README-TEMPLATE.md Register the [extension-name] extension in your application's startup configuration. This enables the custom activities and features provided by the extension. ```csharp using Elsa.Extensions; using Elsa.[extension-name]; services.AddElsa(elsa => { elsa.Use[extension-name](options => { options.Property1 = "value1" options.Config = options => { options.Property2 = "value2"; }; }) } ``` -------------------------------- ### Configure Multiple LDAP Connections Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/_autodocs/configuration.md Register the LDAP extension and configure multiple named connections for different purposes, such as primary, testing, or archive directories. Optional parameters like Username, Password, and UseSSL can be omitted if not needed for a specific connection. ```csharp services.AddElsa(elsa => { elsa.AddLdap(ldap => { // Primary directory ldap.ConfigureConnection("Default", options => { options.ServerAddress = "ldap://ldap1.example.com"; options.BaseDn = "dc=example,dc=com"; options.Username = "cn=admin,dc=example,dc=com"; options.Password = "password1"; }); // Secondary directory for testing ldap.ConfigureConnection("Test", options => { options.ServerAddress = "ldap://ldap-test.example.com"; options.BaseDn = "dc=test,dc=example,dc=com"; options.UseSSL = true; }); // Archive directory (read-only) ldap.ConfigureConnection("Archive", options => { options.ServerAddress = "ldaps://ldap-archive.example.com:636"; options.BaseDn = "dc=archive,dc=example,dc=com"; }); }); }); ``` -------------------------------- ### Register Elsa.DevOps.GitHub Extension Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/src/modules/devops/Elsa.DevOps.GitHub/README.md Configure the Elsa builder to include the GitHub extension in your application services. ```csharp // Program.cs or Startup.cs services .AddElsa(elsa => { elsa.UseGitHub(); // Other Elsa configurations... }); ``` -------------------------------- ### Configure LDAP Settings in appsettings.json Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/src/modules/ldap/Elsa.Ldap/README.md Alternatively, configure LDAP connection details directly in your appsettings.json file. Ensure these settings match the keys used in your Program.cs configuration. ```json { "Ldap": { "BindDn": "cn=myuser,dc=example,dc=org", "BindPassword": "s3cr3t", "Host": "dc.example.org", "Port": 389, "UseSsl": false } } ``` -------------------------------- ### Implement Custom AI Service Provider Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/src/modules/agents/README.md Implement the IAgentServiceProvider interface to create a custom AI service provider. Register your custom provider using AddAgentServiceProvider. ```csharp public class CustomAIProvider : IAgentServiceProvider { public string Name => "CustomAI"; public void ConfigureKernel(KernelBuilderContext context) { // Configure custom AI service context.Builder.Services.AddCustomAIChatCompletion( context.ServiceConfig.GetSetting("ApiKey") ); } } // Register services.AddElsa(elsa => { elsa.UseAgents(agents => { agents.Services.AddAgentServiceProvider(); }); }); ``` -------------------------------- ### Configure [extension-name] Extension in appsettings.json Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/README-TEMPLATE.md Configure the [extension-name] extension using the appsettings.json file. This is an alternative to programmatic configuration in Program.cs. ```json { "[extension-name]": { "Property1": "value1", "Config": { "Property2": "value2" } } } ``` -------------------------------- ### Execute GraphQL Query with GitHub API Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/_autodocs/api-reference/GitHub-Extension.md Use this activity to execute arbitrary GraphQL queries against the GitHub API. Provide your GitHub token, the GraphQL query string, and optionally, a dictionary of variables. ```csharp var query = @" query ($owner:String!, $name:String!) { repository(owner: $owner, name: $name) { name stargazerCount description } }"; var graphql = new ExecuteGraphQLQuery { Token = new Input { Value = "ghp_..." }, Query = new Input { Value = query }, Variables = new Input?> { Value = new Dictionary { { "owner", "microsoft" }, { "name", "TypeScript" } }} }; await graphql.ExecuteAsync(context); var result = context.Get(graphql.Result); ``` -------------------------------- ### Implement Custom Protobuf Consumer Factory Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/src/modules/servicebus/Elsa.ServiceBus.Kafka/Documentation.md Implement IConsumerFactory to support custom deserialization strategies like Protobuf. The CreateConsumer method builds a Kafka consumer with a specified deserializer and an optional value transformer. ```csharp public class ProtobufConsumerFactory : IConsumerFactory { public IConsumer CreateConsumer(CreateConsumerContext context) { var consumer = new ConsumerBuilder(context.ConsumerDefinition.Config) .SetValueDeserializer(new ProtobufDeserializer()) .Build(); // Optional: transform the value and/or set SchemaFullName on KafkaTransportMessage. // The transformer runs in Worker.ProcessMessageAsync before the message is dispatched. return new ConsumerProxy(consumer, raw => { if (raw is not MyMessage msg) return (raw, null); return (msg, MyMessage.Descriptor.FullName); }); } } ``` -------------------------------- ### ISqlClientFactory Interface Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/_autodocs/types.md Provides a factory for creating SQL clients. ```APIDOC ## ISqlClientFactory Interface ### Description Interface for creating SQL clients. ### Methods - `CreateClient(string clientName, string connectionString)`: Creates and returns an `ISqlClient` instance using the provided client name and connection string. ``` -------------------------------- ### Configure Kafka Topics Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/src/modules/servicebus/Elsa.ServiceBus.Kafka/Documentation.md Declare topics to populate the `Topic` dropdown in the `ProduceMessage` activity. Topics do not need to be pre-declared for consuming with the `MessageReceived` activity. ```csharp kafka.ConfigureOptions(options => { options.Topics.Add(new TopicDefinition { Id = "orders", Name = "orders" }); options.Topics.Add(new TopicDefinition { Id = "events", Name = "events.v1" }); }); ``` -------------------------------- ### Force Legacy Agent Invoker Mode Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/src/modules/agents/README.md Demonstrates how to explicitly use the legacy Semantic Kernel implementation for agent invocation by setting `useAgentFramework` to `false`. ```csharp await agentInvoker.InvokeAgentAsync(agentName, input, useAgentFramework: false, cancellationToken); ``` -------------------------------- ### Register Elsa SQL Extension Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/_autodocs/configuration.md Register the SQL extension and its database providers. Use this to configure multiple database providers. ```csharp services.AddElsa(elsa => { elsa.AddSql(sql => { // Register database providers sql.UseMySql(); sql.UsePostgreSql(); sql.UseSqlite(); sql.UseSqlServer(); }); }); ``` -------------------------------- ### Create GitHub Issue Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/_autodocs/api-reference/GitHub-Extension.md Use this activity to create a new issue in a GitHub repository. Provide authentication token, repository details, and issue content. Optional parameters include labels, milestone ID, and assignees. ```csharp var createIssue = new CreateIssue { Token = new Input { Value = "ghp_..." }, Owner = new Input { Value = "myorg" }, Repository = new Input { Value = "myrepo" }, Title = new Input { Value = "Bug: Dashboard loading slow" }, Body = new Input { Value = "The dashboard takes 10+ seconds to load on slow connections" }, Labels = new Input?> { Value = new[] { "bug", "performance" } } }; await createIssue.ExecuteAsync(context); var issue = context.Get(createIssue.CreatedIssue); ``` -------------------------------- ### Activity Execution Context Reference Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/_autodocs/types.md Provides context during activity execution, including workflow state, service access, variables, and methods for activity completion. ```csharp public class ActivityExecutionContext { // Get/Set values public T Get(Input input); public void Set(Output output, T value); // Service access public T GetRequiredService(); // Variables public T GetVariable(string name); public void SetVariable(string name, object value); // Workflow context public WorkflowExecutionContext GetWorkflowExecutionContext(); public ExpressionExecutionContext GetExpressionExecutionContext(); // Activity completion public Task CompleteActivityAsync(); public Task CompleteActivityWithOutcomesAsync(params string[] outcomes); // Properties public CancellationToken CancellationToken { get; } public Dictionary ActivityState { get; } public Dictionary JournalData { get; } } ``` -------------------------------- ### Execute SQL Query with SqlQuery Activity Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/_autodocs/api-reference/SQL-Extension.md Use the SqlQuery activity to execute a SQL query and retrieve a DataSet. Configure the database client, connection string, and the SQL query itself. The query supports expression interpolation for dynamic values. ```csharp var query = "SELECT * FROM users WHERE id = {{ UserId }}"; var activity = new SqlQuery { Client = new Input { Value = "DefaultClient" }, ConnectionString = new Input { Value = "Server=localhost;Database=mydb" }, Query = new Input { Value = query } }; // After execution, access results: DataSet results = context.Get(activity.Results); ``` -------------------------------- ### ClientStore Service - Register Method Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/_autodocs/api-reference/SQL-Extension.md Registers a database client type with the store. This allows you to manage and switch between different SQL client implementations. ```APIDOC ## ClientStore Service - Register Method Registers a database client type with the store. **Type Parameters:** | Name | Constraint | Description | |------|-----------|-------------| | TClient | `class, ISqlClient` | Client implementation class | **Parameters:** | Name | Type | Description | |------|-----------|-------------| | name | `string?` | Client registration name. If null, defaults to `nameof(TClient)` | **Throws:** - Throws `InvalidOperationException` if a client with the same name is already registered **Example:** ```csharp var store = new ClientStore(); store.Register("MySql"); store.Register("PostgreSql"); store.Register("Sqlite"); store.Register("SqlServer"); ``` ``` -------------------------------- ### Accessing Workflow Data with Expressions Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/src/modules/sql/README.md Shows how to access Input, Output, and Variable values, including nested properties and workflow-related objects, using Liquid-like syntax. ```liquid {{Input.}} {{Output.}} {{Variable.}} ``` ```liquid {{Input.MyObjectArr[0]}} {{Variable.MyObject.User.Id}} {{Variable.MyObject.Users[3].Name}} {{Activity.MyObject.Users[2].Age}} ``` ```liquid {{LastResult}} {{Workflow.Identity.DefinitionId}} {{Activity.WorkflowExecutionContext.Id}} ``` -------------------------------- ### Implement Custom Agent Plugin Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/src/modules/agents/README.md Implement agent plugins by defining methods with the KernelFunction attribute. Register your plugin provider using AddPluginProvider. ```csharp public class WeatherPlugin { [KernelFunction, Description("Gets weather for a location")] public async Task GetWeather( [Description("Location name")] string location) { // Implementation return $"Weather in {location}: Sunny, 72°F"; } } // Register services.AddElsa(elsa => { elsa.UseAgents(agents => { agents.Services.AddPluginProvider(); }); }); ``` -------------------------------- ### Run Agent Module Tests Source: https://github.com/elsa-workflows/elsa-extensions/blob/main/src/modules/agents/MIGRATION_GUIDE.md Execute the comprehensive tests for the Elsa.Agents module using the .NET test runner. ```bash dotnet test test/modules/agents/Elsa.Agents.Tests/ ```