Expand my Community achievements bar.

We are excited to introduce our latest innovation to enhance the Adobe Campaign user experience — the Adobe Campaign v8 Web User Interface!
SOLVED

Splitting up a large workflow using External Signal

Avatar

Level 3

Hi,

I have a large complicated workflow which runs at the end of each campaign which summarises findings and then emails this to stakeholders.

Ideally I want to split this into two parts, the simply delivery part and the complicated summarisation part. The simple part will allow the operators to select their data and delivery templates and send the email. The complicated part does a ton of analysis work and delivers some files. The operators should never touch any of the complicated part.

I was thinking to put a signal at the end of the simple part which after X amount of time will trigger the complicated part, passing through the required variables to enable it to determine the campaign it needs to analyse and deliver the automated reports for.

How best to do this? I looked at signals and I think this is the best way, however I'm unsure of exactly how to trigger a signal from a workflow. 

 

Appreciate your input!

1 Accepted Solution

Avatar

Correct answer by
Employee Advisor

Hi Alistair,

Signal seems to best suit your requirement. 

Each signal activity has an internal name and this is something which helps trigger the signal.

So at the end of simple part you can put a JS code activity.

Use the following code

xtk.workflow.PostEvent('Identifier or internal name of the workflow which contains signal activity', 'The name of the activity from which the event starts', 'The name of the transition to activate. If this name is empty, the event will be issued on the first valid transition', 'The parameters of the event in the form of an XML element. The name of the element must be variables.', 0)

Hope this helps.

Regards,

Vipul

View solution in original post

22 Replies

Avatar

Correct answer by
Employee Advisor

Hi Alistair,

Signal seems to best suit your requirement. 

Each signal activity has an internal name and this is something which helps trigger the signal.

So at the end of simple part you can put a JS code activity.

Use the following code

xtk.workflow.PostEvent('Identifier or internal name of the workflow which contains signal activity', 'The name of the activity from which the event starts', 'The name of the transition to activate. If this name is empty, the event will be issued on the first valid transition', 'The parameters of the event in the form of an XML element. The name of the element must be variables.', 0)

Hope this helps.

Regards,

Vipul

Avatar

Level 3

Hi Vipul,

Would you be so kind as to show an actual example where a variable (such as a delivery Id) is being passed through?

 

Thanks!

Avatar

Employee Advisor

alistairk16183831 wrote...

Hi Vipul,

Would you be so kind as to show an actual example where a variable (such as a delivery Id) is being passed through?

 

Thanks!

 

Hi Alistair,

Hope this helps.

xtk.workflow.PostEvent('calledWorkflow','signal','', <variables varName= {vars.myName} />,false)

Regards,

Vipul

Avatar

Employee Advisor

alistairk16183831 wrote...

That looks really good Vipul, I'll test that today. One final question from my head before I am able to test - lets say this was the variable I was creating;

  1. vars.myVar = instance.vars.deliveryId

and there were three records each with a different delivery ID in the data at that point, would all three be passed through to the signal?

 

Hi Alistair,

I'm not sure if I understood it correctly. If the requirement is to pass three deliveryIds in one go through signal you can do something like this.

vars.deliveryid1 = instance.vars.deliveryId1; vars.deliveryid2 = instance.vars.deliveryId2; vars.deliveryid3 = instance.vars.deliveryId3; xtk.workflow.PostEvent('calledWorkflow','signal','', <variables varName1= {vars.deliveryid1} varName2= {vars.deliveryid2} varName3= {vars.deliveryid3} />,false)

Hope this helps.

Regards,

Vipul

Avatar

Level 3

This is working for a single delivery so thank you for those details!

My final requirement is for a multi delivery campaign such as an AB Test.

This is the code;

// Define Delivery Variable vars.myVar = vars.deliveryId; //Pass through Variable xtk.workflow.PostEvent('WKF129','signal','', <variables varName= {vars.myVar} />,false)

And this is the delivery scenario (code is in the END icon);

The above code only brings through a single delivery ID whereas I would need it to bring through all three. Furthermore I would want to devise a way to scale this up - so if an operator decides to do an ABCD test they can just add in the extra deliveries and not have to worry about additional variables.

Avatar

Employee Advisor

Hi Alistair, why not use queryDef inside end activity. Get all deliveries associated with current workflow by querying on nms:delivery where [workflow-id] = instance.id

Avatar

Level 3

Something along these lines (although my where clause is currently failing);

// Define Delivery Variable var query = xtk.queryDef.create( <queryDef schema="nms:delivery" operation="select"> <select> <node expr="@id"/> </select> <where> <condition expr=[workflow-id] = instance.id/> </where> </queryDef>); var resultSet = query.ExecuteQuery(); for each (var row in resultSet) { vars.myVar = row.@id; logInfo(vars.myVar); } //Pass through Variable xtk.workflow.PostEvent('WKF129','signal','', <variables varName= {vars.myVar} />,false)

Avatar

Employee Advisor

Yes you are close. Just that the loop will generate multiple deliveryids you can create a comma separated  string and pass that in PostEvent. In the called workflow perform a JS split function to regenerate the deliveryids from passed variable.

The where clause will be expr={"[workflow-id]=" + instance.id}

Hope this helps 

Avatar

Level 3

That is helpful.

I haven't come across a JS split function in Campaign yet. Is there an example I can reference?

That where clause still seems to be failing

Avatar

Employee Advisor

Split is a function part of JavaScript language. You will find a lot of examples on the internet.

As I don't have my laptop, can check the expression next week.

Avatar

Employee Advisor

It is unable to understand attribute workflow-id in delivery schema. Please check the name of foreign key link to xtk:workflow and use that here. It will work then

Avatar

Employee Advisor

Hi Alistair,

Made a small mistake, forgot the @ symbol

Use this as expression for where clause

expr={"[@workflow-id]=" + instance.id}

Split is a JS fundtion which will take string like this as input1 "deliveryid1,deliveryid2,deliveryid3" and a delimiter as input 2 i.e. ','

It will output an array [deliveryid1, deliveryid2, deliveryid3]

You can then loop through this array to perform your logic.

This link should help http://stackoverflow.com/questions/3245088/how-to-split-a-comma-separated-string-and-process-in-a-lo...

Regards,

Vipul

Avatar

Level 3

Hi Vipul,

Thanks for your patience here. That code is working (apart from one thing I will mention at the end);

// Define Delivery Variable var query = xtk.queryDef.create( <queryDef schema="nms:delivery" operation="select"> <select> <node expr="@id"/> </select> <where> <condition expr={"[@workflow-id]=" + instance.id}/> </where> </queryDef>); var resultSet = query.ExecuteQuery(); for each (var row in resultSet) { vars.myVar = row.@id; logInfo(vars.myVar); } //Pass through Variable xtk.workflow.PostEvent('WKF129','signal','', <variables varName= {vars.myVar} />,false)

It logs the following two Delivery IDs. These are correct.

 

In my signal workflow I have the JS script;

//  Split Variable var myArray = vars.varName.split(','); //  Define in vars vars.delId1 = myArray[0]; vars.delId2 = myArray[1]; vars.delId2 = myArray[2]; //  logInfo(vars.varName); logInfo(vars.delId1); logInfo(vars.delId2); logInfo(vars.delId3);

This logs the following delivery ID variables;

As you can see it takes only a single value instead of the two listed in the previous logs.

At what point are the delivery IDs parsed into a comma separated string? If I log the vars.varName variable it only has a single Delivery ID in it - the value I'm placing into vars.del1.

 

Final thing to mention, as you may remember my test workflow consisted of an AB test and a winning delivery, so I would expect to see three Delivery IDs, instead there only seem to be two present. The winning Delivery is not being picked up with that script. I suspect this is due to the way it is being generated and that perhaps it is not correctly assigning itself to this workflow. The script used for this winning Delivery is taken from the Adobe Campaign Use Case documentation. Would it be possible to take a look and see if this is the case?

Avatar

Employee Advisor

Hi Alistair,

There are few missing points and hence you are facing this issue.

  1. The Campaign documentation explaining the script for selecting winner delivery just duplicates one of the A or B delivery and assigns the operation-id to it. In other words, the winner delivery is only being linked with the campaign.You'll have to add another line to this code so that attribute [@workflow-id] is populated with instance.id and then it will get picked by your queryDef.
  2. In you script towards the build up to PostEvent, when you are looping through the deliveryIds, it is required to develop a comma separated string of deliveryIds there itself. At present, it is not being done and hence only the last delivery is being passed to signal. Following code
    var resultSet = query.ExecuteQuery(); for each (var row in resultSet) { vars.myVar = row.@id; logInfo(vars.myVar); }
      should be changed to 
    var resultSet = query.ExecuteQuery(); var commaSeparatedDeliveryIds; for each (var row in resultSet) { commaSeparatedDeliveryIds = commaSeparatedDeliveryIds + row.@id + ","; //Generate comma separated list of deliveryIds logInfo(commaSeparatedDeliveryIds); } vars.myVar = commaSeparatedDeliveryIds.replace(/,\s*$/, ""); //Replace last comma and trailing whitespaces with blankspace

     

Avatar

Level 3

Hi Vipul,

Thanks for your pointers on amending the bits of code. As I'm sure you are not surprised by I have a couple of questions;

Amending the 'Winner' JS script. I think I may have got this backwards?

// link the delivery to the operation to make sure it will be displayed in // the campaign dashboard. This attribute needs to be set manually here since // the Duplicate() method has reset it to its default value => 0 delivery.operation_id = winner.@["operation-id"] delivery.workflow_id = winner.@["instance-id"]

Concatenating the delivery ids.The updated code you supplied displays this (I'm displaying the final output with the end comma removed) so this appears to be working (I assume the lack of the delivery ID from the winning delivery is causing the undefined/lack of comma result).

Ignore my previous split questions - user error. I was overwriting [1] with [2].

I really do appreciate your help on this!

Avatar

Level 3

Hi Vipul,

The first part of the problem is the circular logic in this piece of code.

{ commaSeparatedDeliveryIds = commaSeparatedDeliveryIds + row.@id + ","; //Generate comma separated list of deliveryIds }

The commaSeperatedDeliveryIds variable is being used to define itself when it doesn't actually contain any info yet, therefore always returns 'undefined'. It also doesn't comma between itself and row.id. For example it returns 'undefined4242971,4241831'. If you move the commaSeperatedDeliveryIds variable about in the code then the 'undefined' value moves around too.
 

Avatar

Employee Advisor

alistairk39680404 wrote...

Hi Vipul,

The first part of the problem is the circular logic in this piece of code.

  1. {
  2. commaSeparatedDeliveryIds = commaSeparatedDeliveryIds + row.@id + ","; //Generate comma separated list of deliveryIds
  3. }

The commaSeperatedDeliveryIds variable is being used to define itself when it doesn't actually contain any info yet, therefore always returns 'undefined'. It also doesn't comma between itself and row.id. For example it returns 'undefined4242971,4241831'. If you move the commaSeperatedDeliveryIds variable about in the code then the 'undefined' value moves around too.
 

 

Hi Alistair,

The variable commaSeparatedDeliveryIds is initially undefined and hence the keyword is getting appended with your deliveryIds.

When defining the variable we can initialize it 

var commaSeparatedDeliveryIds = "";

This will fix the problem.

For the workflow id problem, as stated above you can use instance.id directly. I believe you have already figured it out on the related thread.

Please let me know if you have any queries.

Regards,

Vipul

Avatar

Level 3

Hi Vipul,

That's all fine thanks. I actually used my brain and solved it :). I did have another question on how best to interrogate the received split array but I've put together an inelegant solution which does the trick.

Appreciate all your help.

Avatar

Level 1

Hi,

Can you please help me with the following scenario:

I need to create an Engagement Split for an email. Engagers of Email 1 get mobile alert while non-engagers of Email 1 get Email 2.

Cab you please guide me how to implement this scenario in workflow?

Thanks,

Richa

Avatar

Employee

Hello Richa,

The split will be based on what you consider to be responders (open/clicks) for email1

Taking email clicks as responders for example , you can create a workflow like this

1>. External signal from previous workflow

2>. Query activity targeting the recipients of the delivery EMAIL1

3>. Split activity connected to the query with Generate complement option selected from the general tab . On the Subsets tab click on "add a filtering condition to the inbound population , click on Edit and select the filtering dimension as a temporary schema and select the query result as source.

Then add a filtering condition like shown in the screenshot here : TrackingLogRcp exists such as url/@type=email-click.forum1.JPG

4>. Add the subset to the SMS delivery and add the complement to the Email2 to send SMS to responders and email2 to non-responders.

Hope this helps.

Regards,

Adhiyan