Example Project: Custom Workflow Step
Outline
This project will guide you through building a C# Opal tool that acts as a custom workflow step within Optimizely CMP. This tool will validate content based on specific criteria (e.g., minimum word count, presence of required keywords) before allowing the workflow to proceed.
By the end of this module, you will be able to:
- Develop robust validation logic using parameter models
- Understand deployment considerations for C# Opal tools.
- Create a custom workflow step or a multilingual content manager.
Project Goal: To create a C# Opal tool that can be integrated into a CMP workflow to enforce content quality standards.
Scenario: A content marketing team wants to ensure that all articles published through CMP meet certain editorial guidelines, specifically a minimum word count and the inclusion of predefined SEO keywords. If an article does not meet these criteria, the workflow should be blocked, and the author should receive a clear message.
Key Steps and Implementation Details
Project Setup:
- Create a new ASP.NET Core Web API project ( Core Concepts & APIs lesson)
- Install
OptimizelyOpal.OpalToolsSDK
. - Configure
Program.cs
to useAddOpalToolsService()
andUseOpalToolsService()
. - Install
System.ComponentModel.DataAnnotations
if not already present
Define Tool Parameters (Input Model):
- Create a C# class
ContentValidationParams
to represent the input from CMP. This will include theContentGuid
of the article being validated, theMinimumWordCount
, and a list ofRequiredKeywords
.
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
public class ContentValidationParams
{
[Required(ErrorMessage = "Content GUID is required.")]
public string ContentGuid { get; set; }
[Range(100, 5000, ErrorMessage = "Minimum word count must be between 100 and 5000.")]
public int MinimumWordCount { get; set; }
public List RequiredKeywords { get; set; } = new List();
}
Implement Content Fetching (Simulated or Real):
- For this example, we'll simulate fetching content. In a real scenario, you would use Optimizely's Content Delivery API or CMP's internal APIs to retrieve the actual article text.
- Create a mock
IContentService
andContentService
(as shown in Lesson 3.4) that returns a dummy article text based on theContentGuid
.
Implement Validation Logic:
- Create a static method for your tool, applying the
[Tool]
attribute. - Inside the method, use
Validator.TryValidateObject
for basic data annotation validation. - Implement custom logic to:
- Get the article text (from your simulated service).
- Calculate the word count of the article.
- Check for the presence of each required keyword in the article text.
- Return a success status or throw an
ArgumentException
with a clear error message if validation fails.
using OptimizelyOpal.OpalToolsSDK.Attributes;
using System.ComponentModel.DataAnnotations;
using System.Text.RegularExpressions; // For word count and keyword check
using System.Linq; // For LINQ operations
using System.Threading.Tasks;
// Assume IContentService and ContentService are defined as in Lesson 3.4
// and registered in Program.cs: builder.Services.AddScoped();
public static class WorkflowTools
{
[Tool(name: "validate_article_for_workflow", description: "Validates an article's content for workflow progression.")]
public static async Task
Register the Tool: Ensure your WorkflowTools
class (or the class containing your tool method) is registered with the OpalToolsService
in Program.cs
.
Testing:
Run your ASP.NET Core application locally: dotnet run
Access the Discovery Endpoint: Navigate to <a href="http://localhost:5000/discovery">http://localhost:5000/discovery</a>
(or your application's port) in your browser to verify the tool manifest is correctly exposed.
Test with an API Client (Postman/Insomnia):
- Send
POST
requests to<a href="http://localhost:5000/tools/validate_article_for_workflow">http://localhost:5000/tools/validate_article_for_workflow</a>
. - Test Case 1 (Success):
{
"contentGuid": "some-article-guid-123",
"minimumWordCount": 50,
"requiredKeywords": ["marketing", "strategy"]
}
(Ensure your mock IContentService
returns content that satisfies these criteria).
- Test Case 2 (Fails - Low Word Count)
{
"contentGuid": "some-article-guid-123",
"minimumWordCount": 500,
"requiredKeywords": ["marketing"]
}
- Test Case 3 (Fails - Missing Keyword):
{
"contentGuid": "some-article-guid-123",
"minimumWordCount": 50,
"requiredKeywords": ["marketing", "nonexistent_keyword"]
}
- Test Case 4 (Invalid Input)
{
"contentGuid": null,
"minimumWordCount": 50,
"requiredKeywords": []
}
Integrate into CMP Workflow (Conceptual):
- In CMP, navigate to Workflow settings.
- Add a new "External Step" to your content workflow.
- Configure the external step to call your deployed C# Opal tool's endpoint (
<a href="http://your-deployed-url/tools/validate_article_for_workflow)">http://your-deployed-url/tools/validate_article_for_workflow)</a>
. - Map the necessary CMP content fields (e.g., article body, word count field) to the parameters expected by your tool (
ContentGuid
,MinimumWordCount
,RequiredKeywords
). - Test the workflow by submitting an article that meets/fails the criteria.
By completing this project, you will have developed a robust C# Opal tool that integrates seamlessly with CMP workflows, demonstrating how to enforce business rules and automate content governance.