Adobe Campaign JavaScript SDK

CRUD operations (xkt:persist)

There are several possibillities to create objects in Campaign.

Create from scratch

This first method is to create an object from scratch. It's a multi-step operation which contains the following steps

    const delivery = client.NLWS.nmsDelivery.create({ 
      label: "Test #1", 
      messageType: "0" 
    });
    await delivery.newInstance();
    delivery.$desc = "My description";
    await client.NLWS.xtkSession.write(delivery); // or await delivery.save();

You'll notice that this method does not return anything. You may have expected this method to return the created object or some id of this object, but Campaign does not. Campaign works the other way round. You first get call NewInstance which will give the id before the object is actually saved in the database.

    const delivery = client.NLWS.nmsDelivery.create({ 
      label: "Test #1", 
      messageType: "0" 
    });
    await delivery.newInstance();
    // delivery.entity.id is the future id of the object in the database

If you need to modify the object again after it's been created, you can use xtk:session#Write or save again, but you must tell Campaign to perform an update operation instead of an insert, or the call will probably fail or create a duplicate in the database. Make sure to read the section about the xtk:session#Write method below to understand how exactly objects are updated

    delivery._operation = "update";
    delivery.$desc = "My updated description";
    await delivery.save();

Finally, to delete the object, use xtk:session#Write or save again, this time passing it the "_operation=delete" attribute

    delivery._operation = "delete";
    await delivery.save();

Create by duplicating an existing object

Sometimes, you do not want to create objects from scratch. Instead you can copy an existing object. Campaign has a sophisticated mechanism to duplicate object and ensures that only the relevant attributes are actually set. For instance, when you dupliate a delivery which is finished, you probably want the new delivery to be in the edition state rather than in the finished state. Schema attributes having the "defOnDuplicate" property will be reset to their defaults in the duplicated object.

Just like the NewInstance API, the xtk:persist#Duplicate will automatically set the primary key for you. And again, it is a multi-step process.

    const operator = client.NLWS.xtkOperator.create();
    await operator.duplicate("xtk:operator|1610");
    operator.name = "Alex";
    await operator.save();

The primary key format is described in the data types section of this document.

Updating entities

Entities can be updated using the xtk:session#Write API. This API is very flexible and also can be used to create or delete entities or to modify multiple entites at once.

More examples of the xtk:session#Write API here.

This method takes an unique argument which is a patch to apply. A patch has the same structure as an entity, but only contains the attributes or elements that need to be modified, created, or deleted. In addition to the value, the patch can also use the _operation property to indicate if a particular set of data needs to be inserted, updated or deleted. The patch object also must have the xtkschema property set to the schema id of the entity to modify.

For instance, one can update the email of a recipient with the following code which clearly shows the xtkschema property, the id and _operation properties to indicate that it is an update and which entity to update, and finally, the email attribute which is the only modified attribute.

    client.NLWS.xtkSession.write({ xtkschema: "nms:recipient", 
                                   id: "1234", _operation:"update", 
                                   email: "amorin@adobe.com"
                                });

It's of course possible to pass the whole entity to an update, but this is strongly discouraged as it can have unwanted side effects in complex scenario when passed nested documents with linked objects. It's also less performant, and may overwrite data. Passing a patch (sometimes called a diff) containing only the actually modified attributes is the best practice. It also has the benefit to allow some sort of concurrent modifications as each update will onlly update the attributes actually changed.

Setting foreign keys

It's pretty common to have to set foreign keys. For instance one want to set the folder in which a recipient is stored. The first possibility is to set the folder-id attribute directly. It's also the most efficient, but it assumes you know the foreign key in the first place.

    client.NLWS.xtkSession.write({ xtkschema: "nms:recipient", 
                                    xtkschema:"nms:recipient", 
                                    id: 2020, _operation:"update", 
                                    "folder-id": 6040
                                });

If you do not know the primary key of the folder but know its name, you can use the following syntax. It works for all collections, where items can be identified with their keys (as defined in the schemas).

    client.NLWS.xtkSession.write({ xtkschema: "nms:recipient", 
                                    xtkschema:"nms:recipient", 
                                    id: 1990, _operation:"update", 
                                    folder: {
                                        _operation: "none",
                                        name: "test"
                                    }
                                });

Note the operation="none" attribute on the folder element which tells Campaign that we should not actually update the folder object itself, but to set the recipient folder instead. If you omit the _operation: "none" property, Campaign will modify both the recipient, but also the folder. It is useful in some cases, but does not make sense in this scenario.

Identifying entities

We've had a glimpse of it but the xtk:session#Write API has several strategies to identify entities, both the top level entity but also linked entities as we've seen with the recipient folder example above.

For instance, folders are an autopk entity and have the id attribute. They also have 2 keys: name and fullName. All 3 can be used as identifiers to update a folder label as the 3 examples below show

    // Update folder by id
    await client.NLWS.xtkSession.write({ 
        xtkschema: "xtk:folder", 
          _operation: "update", id: 1234,
          label: "Hello World",
        });
    });

    // Update folder by name
    await client.NLWS.xtkSession.write({ 
        xtkschema: "xtk:folder", 
          _operation: "update", name: "test",
          label: "Hello World",
        });
    });

    // Update folder by full name
    // This is just for example, do not use this method as the folder full name is the concatenation
    // of the folder label and it's parent folders labels. Changing the label will create an
    // inconsistency between the folder full name and its label. You can update other attributes though.
    await client.NLWS.xtkSession.write({ 
        xtkschema: "xtk:folder", 
          _operation: "update", fullName: "/Profiles and Targets/Recipients/Hello/",
          label: "Hello World",
        });
    });

Deleting data

The xtkSession#write API can also be used to delete data using the "_operation=delete" attribute. For a delete operation, the patch should contain the xtkschema attribute, the _operation=delete attribute and an identifier of the entity.

For insance, a folder can be delete with

    await client.NLWS.xtkSession.write({ 
        xtkschema: "xtk:folder", 
          _operation: "delete", name: "test",
        });
    });

Owned entities which are also autopk will also be deleted

Setting ids

In the previous examples we showed how to create or update object and let Campaign generate the ids. In some cases, you'll want to explictiely set the ids upfront. To ensure uniqueness of the ids, Campaign provides an API to "reserve" ids in advane that you can use afterwards: xtk:session#GetNewIdsEx.

In this example, we're getting an id and creating a recipient. The id can be re-used in subsequent calls as a foreign key

    const idList = XtkCaster.asArray(await client.NLWS.xtkSession.GetNewIdsEx(1, "XtkNewId"));
    await client.NLWS.xtkSession.write({ xtkschema:"nms:recipient", id: idList[0], email: 'amorin@adobe.com' });

Note that