Workflow Plugins
BarakoCMS v2.0 Phase 2 introduces a plugin-based architecture for workflow actions, allowing developers to extend the workflow system without modifying core code.
Architecture
mermaid
graph TB
Event[Content Event] --> Engine[WorkflowEngine]
Engine --> Match{Match Workflow?}
Match -->|Yes| Actions[Execute Actions]
Actions --> DI[DI Container]
DI --> EmailPlugin[EmailAction]
DI --> SmsPlugin[SmsAction]
DI --> CustomPlugin[Your Custom Plugin]Creating a Custom Action Plugin
1. Implement IWorkflowAction
csharp
using barakoCMS.Features.Workflows;
using barakoCMS.Models;
namespace YourApp.Workflows;
public class SlackAction : IWorkflowAction
{
private readonly IHttpClientFactory _httpClientFactory;
public SlackAction(IHttpClientFactory httpClientFactory)
{
_httpClientFactory = httpClientFactory;
}
// Must match the "Type" in workflow definitions
public string Type => "Slack";
public async Task ExecuteAsync(
Dictionary<string, string> parameters,
Content content,
CancellationToken ct)
{
var webhookUrl = parameters.GetValueOrDefault("WebhookUrl");
var message = parameters.GetValueOrDefault("Message", "Workflow triggered");
var client = _httpClientFactory.CreateClient();
await client.PostAsJsonAsync(webhookUrl, new { text = message }, ct);
}
}2. Register the Plugin
In your Program.cs or Startup.cs:
csharp
services.AddScoped<IWorkflowAction, SlackAction>();BarakoCMS will automatically discover and inject all IWorkflowAction implementations into the WorkflowEngine.
3. Use in Workflow Definitions
json
{
"name": "Notify Slack on New Content",
"triggerContentType": "BlogPost",
"triggerEvent": "Created",
"conditions": {
"status": "Published"
},
"actions": [
{
"type": "Slack",
"parameters": {
"WebhookUrl": "https://hooks.slack.com/services/YOUR/WEBHOOK/URL",
"Message": "New blog post published: {{data.Title}}"
}
}
]
}Built-in Actions
BarakoCMS ships with the following workflow actions:
Core Actions
EmailAction (
Type: "Email")- Parameters:
To,Subject,Body - Sends emails via the configured email service
- Parameters:
SmsAction (
Type: "SMS")- Parameters:
To,Message - Sends SMS via the configured SMS service
- Parameters:
WebhookAction (
Type: "Webhook")- Parameters:
Url - Sends HTTP POST requests with content data to external webhooks
- Payload includes:
contentId,contentType,status,data,createdAt,updatedAt
- Parameters:
Advanced Actions
CreateTaskAction (
Type: "CreateTask")- Parameters:
ContentType,Status,Title,Data.* - Auto-generates new content items (tasks, tickets) from workflow triggers
- Tracks relationship to source content
- Parameters:
UpdateFieldAction (
Type: "UpdateField")- Parameters:
Field,Value,TargetId(optional) - Modifies fields on content (supports nested paths like
data.AssignedTo) - Can update triggering content or specify target by ID
- Parameters:
ConditionalAction (
Type: "Conditional")- Parameters:
Condition,ThenActions,ElseActions - Implements if/then/else logic for workflows
- Supports simple expressions:
{ {data.Field} } == "Value",{ {status} } == "Published"
- Parameters:
Action Examples
Email Notification
json
{
"type": "Email",
"parameters": {
"To": "admin@example.com",
"Subject": "New content created",
"Body": "Content {{id}} was created."
}
}Auto-Create Task
json
{
"type": "CreateTask",
"parameters": {
"ContentType": "Task",
"Status": "Draft",
"Title": "Review: {{data.Title}}",
"Data.Priority": "High",
"Data.AssignedTo": "team@example.com"
}
}Update Content Field
json
{
"type": "UpdateField",
"parameters": {
"Field": "data.ReviewStatus",
"Value": "PendingApproval"
}
}Conditional Workflow
json
{
"type": "Conditional",
"parameters": {
"Condition": "{{data.Priority}} == \"High\"",
"ThenActions": "[{\"Type\":\"Email\",\"Parameters\":{\"To\":\"urgent@example.com\",\"Subject\":\"High Priority Alert\"}}]",
"ElseActions": "[{\"Type\":\"SMS\",\"Parameters\":{\"To\":\"+1234567890\",\"Message\":\"Normal priority item\"}}]"
}
}Advanced: Template Variables
Action parameters support template variables using {{variable}} syntax:
| Variable | Description | Example |
|---|---|---|
{{id}} | Content ID | {{id}} |
{{contentType}} | Content type name | {{contentType}} |
{{status}} | Content status | {{status}} |
{ {data.FieldName} } | Value from content data | { {data.Email} } |
Best Practices
- Dependency Injection: Use constructor injection for services (e.g.,
IHttpClientFactory,ILogger) - Error Handling: Wrap risky operations in try-catch to prevent workflow failures
- Logging: Log action execution for debugging
- Validation: Validate required parameters in
ExecuteAsync - Async/Await: Always use async operations for I/O-bound tasks
Example: WebhookAction
csharp
public class WebhookAction : IWorkflowAction
{
private readonly IHttpClientFactory _httpClientFactory;
private readonly ILogger<WebhookAction> _logger;
public WebhookAction(IHttpClientFactory httpClientFactory, ILogger<WebhookAction> logger)
{
_httpClientFactory = httpClientFactory;
_logger = logger;
}
public string Type => "Webhook";
public async Task ExecuteAsync(
Dictionary<string, string> parameters,
Content content,
CancellationToken ct)
{
var url = parameters.GetValueOrDefault("Url");
if (string.IsNullOrEmpty(url))
{
_logger.LogWarning("Webhook URL not provided");
return;
}
try
{
var client = _httpClientFactory.CreateClient();
var payload = new
{
contentId = content.Id,
contentType = content.ContentType,
data = content.Data
};
await client.PostAsJsonAsync(url, payload, ct);
_logger.LogInformation("Webhook sent to {Url}", url);
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to send webhook to {Url}", url);
}
}
}Future Enhancements
Phase 2 roadmap includes:
- Plugin Auto-Discovery: Automatically scan assemblies for
IWorkflowActionimplementations - Visual Workflow Builder: Drag-and-drop UI for creating workflows
- Plugin Marketplace: Share and discover community-built action plugins
- Enhanced Testing Tools: Workflow debugging and testing utilities