Skip to content

✏️ Earn 6 months of Premium for your first approved article. Register.

How to Create a Custom Workflow Activity in Adobe Campaign Classic
> 999 views

How to Create a Custom Workflow Activity in Adobe Campaign Classic

View favourites

Adobe Campaign Classic offers a powerful set of workflow activities out of the box – from data queries to email deliveries. But what if your business logic requires something Adobe didn’t anticipate? That’s where custom workflow activities come into play.

Custom activities allow developers to extend the platform with their own logic – whether it’s calling external APIs, integrating with tools like Slack or Discord, implementing complex data operations, or even adding a custom push notification service. These activities behave like any native activity, appearing in the workflow palette with a custom icon, configurable UI, and support for inputs and outputs.

In this guide, you’ll learn how to build your own custom workflow activity in Adobe Campaign Classic – step by step. We’ll cover everything from setting up the XML definition and writing your own JS logic, to adding a custom icon and testing/debugging the activity.

Unfortunately, there aren’t many resources available online on how to create custom activities. In fact, the only example widely shared is a PowerPoint presentation on the Adobe Community forums. Surprisingly, it connects the dots, showing how all the pieces come together in a real use case. This article builds on that foundation and takes it further with a hands-on, step-by-step guide.

To create a custom activity, we need to extend the xtk:workflow schema, modify the xtk:workflow form, and implement a JavaScript library to host the custom activity logic.

Extension of xtk:workflow schema

<srcSchema label="workflows">
  <element img="nms:activities/delivery.png" label="Custom Activity" name="customActivity" template="xtk:workflow:activity">
    <attribute default="nms:activities/delivery.png" name="img"/>
    <attribute default="cus:customActivityLibrary.js" name="library"/>

    <!-- attributes used by your activity -->
    <attribute label="Label" name="label" type="string"/>
    ..
    <!-- define transitions -->
    <element name="transitions">
      <element name="done" template="xtk:workflow:transition">
        <attribute name="label" translatedDefault="'Ok'"/>
      </element>
      <element name="error" template="xtk:workflow:transition">
        <attribute name="label" translatedDefault="'Error'"/>
      </element>
    </element>
  </element>
  
   <element desc="Workflows definitions" img="xtk:workflow.png" label="Workflows"
           labelSingular="Workflow" name="workflow">

	<!-- register activity under activities -->
    <element name="activities">
      <element name="customActivity" ref="customActivity" unbound="true"/>
    </element>
  </element>
</srcSchema>

Changing the xtk:workflow form

<!-- add activity in the coresponding activity section -->
<container applicableIf="$(entityPath)=='/operation'" codepage="1252" img="nms:miniatures/mini-delivery.png"
                 label="Deliveries" name="delivery">
  <input img="cus:customActivity-mini.png" label="customActivity" xpath="customActivity"/>
  
 </container
 <!-- add activity's form -->
  <form name="customActivity" type="notebook">
    <container img="cus:customActivity-mini.png">
      <input required="true" xpath="@label"/>
      ..
    </container>
  </form>
  ..
</container>

Implementing library cus:customActivityLibrary.js

//entry point for activation
function customActivity_call(){
  //do something for the first time
  return 0
}

//entry point for reactivation
function customActivity_recall() 
{

  //do something for consecutive times
  try {

    task.postEvent(task.doneTransition()) //we decide that a single call by the scheduler is enough, we activate the normal output transition
    task.setCompleted()
    
  }
  catch(e)
  {
    logError(JSON.stringify(e))
    task.postEvent(task.errorTransition()) //enable error transition
    task.setCompleted()
  }
  return 0
}

In the next section, I’ll dive deep into building custom activities, with a full step-by-step explanation on how to create one.

The simplest way to enhance Adobe Campaign Classic’s marketing capabilities is by integrating a Discord webhook, which allows you to send messages to…

🔒 Premium Subscriber Content

What you can learn with Premium

Unlock the full article to explore these topics in detail.

  • How to Extend the xtk:workflow Schema to Define a Custom Activity in Adobe Campaign Classic
  • How to Modify the xtk:workflow Form to Make Your Custom Activity Appear in the Workflow Pallete
  • How to Implement the JavaScript Library for Your Custom Workflow Activity Logic in Adobe Campaign
    • discordWebhook_call()
    • discordWebhook_recall()
  • Use recipients data for personalization

Already a Premium subscriber? Log in to continue reading, or register to create your account.

You must log in and have a Premium Subscriber account to read the full article.

When upgrading, please use the same email address as your WordPress account so we can correctly link your Premium membership.

Please allow us a little time to process and upgrade your account after the purchase. If you need faster access or encounter any issues, feel free to contact us at info@martechnotes.com or through any other available channel.

To join the Discord community, please also provide your Discord username after subscribing, or reach out to us directly for access.

You can subscribe even before creating a WordPress account — your subscription will be linked to the email address used during checkout.

Premium Subscriber

29,99 € / Year

  • Free e-book with all revisions - 101 Adobe Campaign Classic (SFMC 101 in progress)
  • All Premium Subscriber Benefits - Exclusive blog content, weekly insights, and Discord community access
  • Lock in Your Price for a Full Year - Avoid future price increases
  • Limited Seats at This Price - Lock in early before it goes up
  • Monthly 15-Minute Call - Discuss any topic directly

Oh hi there 👋
I have a SSJS skill for you.

Sign up now to get an SSJS skill that can be used with your AI companion

We don’t spam! Read our privacy policy for more info.

Share With Others

The author
Marcel Szimonisz Platinum

Marcel Szimonisz

Marketing Automation Consultant

I specialize in solving marketing technology challenges, automating processes, and turning ideas into practical solutions with Salesforce Marketing Cloud and Adobe Campaign. Through MarTechNotes, I share technical guides and insights that make complex topics easier to understand

Latest badges
Weekend Regular Weekend Regular Profile Complete Profile Complete Simple Start Simple Start 5 Day Streak 5 Day Streak First Comment First Comment

Your email address will not be published. Required fields are marked *

Get exclusive tips, scripts and news

Choose your topics

We don’t spam! Read our privacy policy for more info.

Similar posts

Add to this article

Share your experience

Your contribution

Article history

What changed