javatransformjolt

How to properly transform a JSON input using JOLT when handling both accepts_marketing and email_marketing_consent fields?


I am working with a JOLT transformation that takes an input JSON object and converts it into a new structure, but I need to handle the cases where both accepts_marketing and email_marketing_consent exist in the input or when only one of them is available.

Input JSON Example:

{
  "email": "john.calvert@nm.com",
  "first_name": "John",
  "accepts_marketing": false,
  "email_marketing_consent": {
    "state": "not_subscribed",
    "opt_in_level": "single_opt_in",
    "consent_updated_at": null
  }
}

Expected Output:

{
  "optin_newsletter": false,
  "email": "john.calvert@nm.com",
  "first_name": "John"
}

Current JOLT Transformation:

[
  {
    "operation": "shift",
    "spec": {
      "accepts_marketing": "optin_newsletter",
      "email_marketing_consent": {
        "state": {
          "subscribed": {
            "#true": "optin_newsletter"
          },
          "*": {
            "#false": "optin_newsletter"
          }
        }
      },
      "email": "email",
      "first_name": "first_name"
    }
  },
  {
    "operation": "modify-overwrite-beta",
    "spec": {
      "subscribed": "=toBoolean"
    }
  }
]

Problem:

  1. When both accepts_marketing and email_marketing_consent are present in the input, the output for optin_newsletter is becoming an array: [ false, "false" ], but I want it to be a simple false value.

  2. When only one of the fields (accepts_marketing or email_marketing_consent) is present in the input, I want the output to reflect just that value without duplication or errors.

Questions:

1. How can I handle the case where both accepts_marketing and email_marketing_consent are present, and I only want a single boolean value for optin_newsletter (not an array of values)?

2. If only accepts_marketing or only email_marketing_consent is present, how can I ensure the transformation produces the correct value for optin_newsletter?

3. How can I modify my JOLT spec to conditionally use one of these fields or prioritize one over the other if both are available?

Additional Details:

The goal is for the optin_newsletter field to always be a boolean value (either true or false), even when both fields (accepts_marketing and email_marketing_consent) are present.

I am trying to convert email_marketing_consent.state values like "subscribed" and "not_subscribed" into booleans (true and false, respectively) for consistency.


Solution

  • See if the following spec will work:

    [
      {
        "operation": "shift",
        "spec": {
          "email": "&",
          "first_name": "&",
          "email_marketing_consent": {
            "state": {
              "subscribed": {
                "#true": "option_newsletter"
              },
              "*": {
                "#false": "option_newsletter"
              }
            }
          },
          "accepts_marketing": "option_newsletter"
        }
      },
      {
        "operation": "cardinality",
        "spec": {
          "option_newsletter": "ONE"
        }
      },
    
      {
        "operation": "modify-overwrite-beta",
        "spec": {
          "option_newsletter": "=toBoolean"
        }
      }
    
    ]