Skip to content

08. Metadata specific settings & options

Jörn Berkefeld edited this page Aug 31, 2023 · 15 revisions

Automation (automation)

E-Mail Notifications

Relevant code to add / update notifications in your automation's JSON:

    "notifications": [
        {
            "type": "Complete",
            "email": "automation-completed@demo.accenture.com",
            "message": "optional COMPLETION note that will be included in the email notification"
        },
        {
            "type": "Error",
            "email": ["automation-errors@demo.accenture.com","qa-team@demo.accenture.com"]
            "message": "optional ERROR note that will be included in the email notification"
        }
    ],

Only setting a notification for one type / removing notifications:

    "notifications": [
        {
            "type": "Error",
            "email": ["automation-errors@demo.accenture.com"]
            "message": "optional ERROR note that will be included in the email notification"
        }
    ],

Only setting a notification for one type / removing notifications without a custom message:

    "notifications": [
        {
            "type": "Error",
            "email": ["automation-errors@demo.accenture.com"]
            "message": ""
        }
    ],

To delete notifications, simply remove them from notifications or remove the notifications attribute all together. The above example would effectively remove existing notifications for type Complete and add/update the notification for Error.

Full example for adding notifications for Complete and Error:

{
    "name": "Automation_with_notification",
    "description": "",
    "key": "Automation_with_notification",
    "type": "scheduled",
    "status": "PausedSchedule",
    "schedule": {
        "typeId": 3,
        "startDate": "2023-05-31T00:00:00",
        "endDate": "2023-05-31T00:00:00",
        "icalRecur": "FREQ=DAILY;COUNT=1;INTERVAL=1",
        "timezoneName": "W. Europe Standard Time"
    },
    "steps": [
        {
            "name": "",
            "activities": [
                {
                    "name": "myWonderfulscript",
                    "r__type": "script"
                }
            ]
        }
    ],
    "notifications": [
        {
            "type": "Complete",
            "email": "automation-completed@demo.accenture.com",
            "message": "optional COMPLETION note that will be included in the email notification"
        },
        {
            "type": "Error",
            "email": ["automation-errors@demo.accenture.com","qa-team@demo.accenture.com"]
            "message": "optional ERROR note that will be included in the email notification"
        }
    ],
    "r__folder_Path": "my automations"
}

Adding Verification Activities

When Verifications are created, they automatically get a new ID assigned. That same field also acts as key as there is no other field. This comes with the unique challenge of not being able to use the templating system nor pre-defined keys during deployments to ensure the automation can a) work and b) be deployed. To circumvent the issue, make sure to deploy verifications and automations at the same time. That way, the key as seen in the deploy folder is auto-replaced with the newly generated one in all automations that you are trying to deploy.

How does the mapping work? The system tracks the key in the deploy folder vs the new key on a per-BU basis. That way, the mapping even works in massive multi-BU deployments.

Data Extension (dataExtension)

Retention Policy fields in Data Extensions

The way the retention policy is saved is misleading, and hence we wanted to provide guidance if you ever need to do a deep dive here.

Field Description Values
DataRetentionPeriod -
DataRetentionPeriodUnitOfMeasure represents drop-down for "period after" selection 6: years
5: months
4: weeks
2: days
DataRetentionPeriodLength represents number field for "period after" selection min: 1
max: 999
RowBasedRetention only true if "delete individual records" is selected, otherwise false true, false
ResetRetentionPeriodOnImport true if "Reset period on import" is checked. This option is always false if "delete individual records" is selected true, false
DeleteAtEndOfRetentionPeriod true if "delete all records" is selected, otherwise false true, false
RetainUntil Normally, this should only be filled if a date, rather than a period, was set.

This is empty for "delete individual records", but filled with a (calculated) date for the other 2 delete options even if "period after" was used.
Warning: trying to update a DE is denied when "period after" fields & this is provided
""
or date in US format (m/d/Y H:m:s) "12/6/2021 12:00:00 AM")

To disable retention completely, ensure that you have the 3 booleans set to false, RetainUntil set to an empty string and no DataRetentionPeriod set (=those 2 attributes not present in file).

To enable "delete All records and data extensions" you have to set RowBasedRetention:false and DeleteAtEndOfRetentionPeriod:false while at the same time providing a date in RetainUntil field or a DataRetentionPeriod via the 2 associated fields.

It seems the 2 other modes were added on top later and hence "all records and data extension" is the default retention mode.

Adding/Updating Fields on existing Data Extensions

There are a few rules to keep in mind when playing with Data Extensions fields:

  • The FieldType cannot be changed on existing fields; the API returns in error is the attribute is even provided unchanged during an update
  • MaxLength can be increased or kept on the same value but never decreased during an update
  • A Non-Required/Nullable field cannot be set to be required during an UPDATE
  • When new fields are added, they can be required, but then also have to have a DefaultValue set
  • The value for IsRequired should be 'true' or 'false'
  • The value for IsPrimary should be 'true' or 'false'

Renaming fields of a Data Extensions

With a small addition to the Data Extension's JSON, it is possible to rename fields via MC DevTools. Imagine the following Data Extension:

{
    "CustomerKey": "Account",
    "Name": "Account",
    "Description": "",
    "IsSendable": "false",
    "IsTestable": "false",
    "Fields": [
        {
            "Name": "BillingCity",
            "Scale": "0",
            "DefaultValue": "",
            "MaxLength": "40",
            "IsRequired": "false",
            "IsPrimaryKey": "true",
            "FieldType": "Text"
        },
        {
            "Name": "BillingCountry",
            "Scale": "0",
            "DefaultValue": "",
            "MaxLength": "80",
            "IsRequired": "false",
            "IsPrimaryKey": "false",
            "FieldType": "Text"
        }
    ],
    "r__folder_Path": "Data Extensions"
}

Imagine you wanted to rename BillingCountry to BillingZip for some reason. Previously, you could either go into the GUI or delete & recreate the field. Now, MC DevTools allows you to specify Name_new on the field and the tool will take care of the rest during deployment:

{
    "CustomerKey": "Account",
    "Name": "Account",
    "Description": "",
    "IsSendable": "false",
    "IsTestable": "false",
    "Fields": [
        {
            "Name": "BillingCity",
            "Scale": "0",
            "DefaultValue": "",
            "MaxLength": "40",
            "IsRequired": "false",
            "IsPrimaryKey": "true",
            "FieldType": "Text"
        },
        {
            "Name": "BillingCountry" /* old name, keep here for reference during the update! */,
            "Name_new": "BillingZip" /* new name */,
            "Scale": "0",
            "DefaultValue": "",
            "MaxLength": "80",
            "IsRequired": "false",
            "IsPrimaryKey": "false",
            "FieldType": "Text"
        }
    ],
    "r__folder_Path": "Data Extensions"
}

All you have to do is deploy the data extension again with Name_new specified for each field that needs to be renamed.

Mobile Push Application (transactionalPush)

When creating / updating transactionalPush you will notice a field for the Mobile Application ID (applicationId). This cannot be found in your downloaded BUs but only in SFMC Setup > Mobile Push. Mobile Applications can be created and maintained solely via GUI and not via API.

If you plan to deploy transactionalPush messages to another BU, ensure that as a pre-deployment step, you created the respective Mobile App on the target BU and that you replaced the application ID in your deployment package with that new ID. In a CI/CD environment where the deployment would happen automatically based on your development version, you will have to create a new variable in your source & target market, which stores the application Id for the respective BUs.

Journey (journey)

Retrieve & delete by ID

Journey is the only type that supports ids for retrieve and delete. The reason is that the key is not exposed in the interface. Meanwhile, the ID is directly visible in the URL (together with the version). To use this, prefix your ID with id: like in the following example, in which 'afjdskfsafkldsafklf' is the ID you found in the URL:

mcdev retrieve cred/bu journey id:afjdskfsafkldsafklf

Deploying from one BU to another BU

When deploying a Journey to a different BU, you will notice that not all IDs are automatically replaced, and the server might return error messages. This is because the Journey is not a standalone object but rather a collection of other objects. The current state of the mcdev only checks for triggeredSends and eventDefinitions and replaces those IDs. If you encounter other objects that are not replaced, please try to replace the IDs/Keys on your own.

Creating a new Draft version

When creating a new Journey, you will notice that its version is set to 1 and the status is set to Draft. Deploying changes to this Journey will update this particular version until you publish it via the GUI.

If you want to create a new draft version of a journey after publishing it, simply deploy it again. The tool will automatically create a new version based on the JSON you are deploying and set the status of that new version to Draft again. Note that the values in the version and status fields are automatically overridden during this deployment.

Note: Please make sure you retrieve the Journey again before creating a new draft version to ensure you are working off the latest version. Otherwise, mcdev might create a new version based on an outdated version of the Journey.

Roles (role)

Analyzing differences between roles

This one is a hack, but it works nicely nonetheless. We support document for roles; that method takes all roles downloaded in the retrieve/ folder and creates the md file for it. If you want to create such a report for chosen roles you need to make sure you downloaded a recent copy of them, then delete all other roles in your retrieve folder (this will not affect the server!) and afterwards run mcdev document cred/_ParentBU_ role. It will create a report just for the remaining roles! You can then go in and either check the rendered md file directly or copy it into an excel file for further analysis.

Users (user)

You can create/update most fields in the user JSONs, except for User Permissions. Roles and Business Units can be assigned and removed at will simply by adding or removing the role name or the MID, respectively.

Roles associated with Business Units

While the user interface of SFMC allows setting up roles that will be automatically assigned in the background to any user with access to that BU, we cannot access that information via API at this point (or at least we do not know how).

Roles associated with users only for a specific Business Unit

SFMC DevTools cannot show which roles were assigned to users just for given Business Units, nor can it update such an assignment.

Standard "Marketing Cloud *" roles

Due to a bug in SFMC's APIs, whenever we try to update a user that has one of these standard Marketing Cloud roles assigned, these roles will be unassigned. This means if you had such a role assigned to a user, and then you try to update that user, even if it does not concern the roles, these default roles will be removed afterwards. If, on the other hand, you try to add such a role, this attempt will be ignored.

Warning: To avoid issues, whenever you try to update a user with the expectation of that user (still) having such a role afterward, the update is blocked with an error. You can only update that user if you remove the role in question from your to-be-deployed JSON.

Unlock user account

Depending on your security settings, you might choose to automatically block access to unused user accounts or after several failed attempts to log in. In these cases you will notice that c__IsLocked_readOnly is set to true. To unlock them, you cannot just change this value (hence the custom "readOnly" suffix) but instead you need to use the field Unlock and set that to true. To make things easy, mcdev adds this particular field automatically whenever IsLocked is true. All you need to do is change it from false to true and then re-deploy that user to unlock him/her.

SSO & FederationID

While this information currently cannot be retrieved via API (that still worked back in 2019...), it can still be set. Therefore, if you use not only an external SSO provider but also a provisioning system, you can enable/disable the SSO checkbox and set the federation ID (your external user ID) in Marketing Cloud.

You have to add this to the end of your user-JSON file and run deploy:

    "SsoIdentity": {
        "IsActive": true, // true enables SSO, false disables SSO
        "FederatedID": "test-mcdev" // make sure to replace test-mcdev with the actual value from your SSO provider for this user
    }

Full example:

{
    "CreatedDate": "2021-06-22T14:49:02.99",
    "ModifiedDate": "2021-06-22T14:54:07.45",
    "CustomerKey": "0cea7619-8ea9-41e2-97a3-d9a33dc0847a",
    "UserID": "test-mcdev@accenture.com",
    "Name": "NameOfTheUser",
    "Email": "test-mcdev@accenture.com",
    "MustChangePassword": true,
    "ActiveFlag": true,
    "UserPermissions": [],
    "LastSuccessfulLogin": "2021-06-22T14:49:02.99",
    "IsAPIUser": true,
    "NotificationEmailAddress": "test-mcdev@accenture.com",
    "DefaultBusinessUnit": 7281698,
    "c__type": "User",
    "c__AccountUserID": 717142520,
    "c__IsLocked_readOnly": false,
    "c__AssociatedBusinessUnits": [
        7281698
    ],
    "c__RoleNamesGlobal": [
        "My super role",
    ],
    "c__TimeZoneName": "(GMT+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna *",
    "c__LocaleCode": "en-GB",
    "SsoIdentity": {
        "IsActive": true,
        "FederatedID": "test-mcdev"
    }
}

Verification Activity (verification)

See details above: Adding Verification Activities