Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

  • The Sanity ID for the live offers document, for the most part, will be feature-loyalty-offers-ui-singleton, however, some markets have drifted from this convention.

  • An offer is open only if it has the ruleset RequiresAuthentication = False. If the ruleset RequiresAuthentication is not present in the offer OR if the ruleset RequiresAuthentication = True, then the offer is closed and should only show for guests that are signed into the kiosk.

  • Sample query:

Code Block
languagegraphql
query getSanityOffers {
  	LoyaltyOffersUI(id: "feature-loyalty-offers-ui-singleton") {
    	# Available for all users.
    	# You can use these to lookup assets from global.
    sortedSystemwideOffers {
      _id
      loyaltyEngineId
      name {
        enRaw
      }
    }  rules {
 # These are config. offers (templates).  # Returns the #value Youof shouldthe useAuthenticationRequired theserule
only to display content (images, names, etc).  ... on RequiresAuthentication #{
You can use these to lookup assets from the actual PersonalizedrequiresAuthentication
offers.     liveConfigOffers {  }
    _id    # Add  loyaltyEngineIdmore rules as needed here (e.g. FirstOrderOnly, LoyaltyBetweenDates, etc)
      name}
{    }
    enRaw# These are config. offers (templates).
 }   # You }should use these }
}

Example reward query

  • The _id is subject to the dataset you are using. For the most part it will be reward-list-singleton, however, some markets have drifted from this convention

  • Sample query:

Code Block
query getSanityRewards {
  RewardList(id: "reward-list-singleton") {
    rewardCategories {
      _id
      label only to display content (images, names, etc).
    # You can use these to lookup assets from the actual Personalized offers.
    liveConfigOffers {
       _id
en      loyaltyEngineId
}      name rewards {
        ...enRaw
on Reward {    }
    }
 # Sanity}
ID of the reward
          _id
          # Loyalty Engine ID to be used in the Loyalty Engine query if needed
 }

Example reward query

  • The _id is subject to the dataset you are using. For the most part it will be reward-list-singleton, however, some markets have drifted from this convention

  • Sample query:

Code Block
query getSanityRewards {
  RewardList(id: "reward-list-singleton") {
    rewardCategories {
      _id
      label {
loyaltyEngineId        en
  # Reward content to display}
to the user (name, image, description...) rewards {
        name... {on Reward {
          en# Sanity ID of the reward
     }     _id
     image {    # Loyalty Engine ID to be used in the enLoyalty {Engine query if needed
          loyaltyEngineId
asset {         # Reward content to display to the user url(name, image, description...)
          name  }{
            }en
          }
          descriptionimage {
            enRawen {
         }     asset {
    # Here we add the rules we want to check for the rewardsurl
          # e.g., LoyaltyPoints (reward points}
cost), RewardPrice (reward money price),        }
  #  SubtotalSpend (minimum subototal to spend for redeeming}
the reward)         description {
ruleSet {           enRaw
 ... on LoyaltyPoints {      }
        points  # Here we add the rules we want to check for }the rewards
          # e.g.., onLoyaltyPoints RewardPrice(reward {points cost), RewardPrice (reward money price),
         price # SubtotalSpend (minimum subototal to spend for redeeming the reward)
        }  ruleSet {
            ... on SubtotalSpendLoyaltyPoints {
              minimumSpendpoints
            }
            #... Addon moreRewardPrice ruleSets{
as needed here (e.g. FirstOrderOnly, LoyaltyBetweenDates, etc)        price
    # See the screenshot below for how get the}
list of available ruleSet from GraphQL Playground      ... on SubtotalSpend {
 }           # Benefit ofminimumSpend
the reward, it can be either a Combo, Item, OfferDiscount   }
       # or Picker   # Add more ruleSets as needed here  # (e.g. FirstOrderOnly, OfferDiscount (It can be a discount for the whole cart orLoyaltyBetweenDates, etc)
            # See the screenshot below for how get #the alist discountof foravailable aruleSet specificfrom product)GraphQL Playground
         incentives {}
          # Benefit ...of onthe OfferDiscountreward, {it can be either a Combo, Item, OfferDiscount
       discountType   # or Picker
         discountValue # e.g., OfferDiscount (It can be a discount for the whole cart or 
discountProduct {         # a discount for a specific product)
 ... on Item {      incentives {
           name {... on OfferDiscount {
               discountType
 en             discountValue
     }         discountProduct   {
    }                 ... on ComboItem {
                  name {
                    en
                  }
                }
              }  ... on Combo {
       }           }name {
         # Reward redemption method available       en
   redemptionMethod           # Here we can get}
the needed PLUs by looking for a specific vendor        }
  # e.g., Partner constant PLU        }
  vendorConfigs {         }
   partner {      }
        _type  # Reward redemption method available
        constantPlu  redemptionMethod
          # Here pluTypewe can get the needed PLUs by looking for a specific vendor
 }         # e.g., }Partner constant PLU
      }    vendorConfigs {
 }     }   }
}

Expand
titleGetting the list of ruleSets from GraphQL Playground

To get list of ruleSet available, navigate to https://czqk28jt.apicdn.sanity.io/v1/graphql/dev_bk_aq/default, and search for “ruleSet” in the Schema explorer as seen here:

image-20240813-035328.pngImage Removed

Querying the Loyalty Platform

Info

GraphQL URL (Playground Available):

https://euc1-dev-bk-loyalty-middleware.rbictg.com/graphql

...

   partner {
              _type
              constantPlu
              pluType
            }
          }
        }
      }
    }
  }
}

Expand
titleGetting the list of ruleSets from GraphQL Playground

To get list of ruleSet available, navigate to https://czqk28jt.apicdn.sanity.io/v1/graphql/dev_bk_aq/default, and search for “ruleSet” in the Schema explorer as seen here:

image-20240813-035328.pngImage Added

Querying the Loyalty Platform

Info

GraphQL URL (Playground Available):

https://euc1-dev-bk-loyalty-middleware.rbictg.com/graphql

  • Replace euc1 with the AWS Short Region that your market belongs to. Please communicate with RBI reps to know which region your market is hosted.

  • Replace dev-bk with the {{stage}}-{{brand}} that you desire to query. You will need to prefix the URL with the AWS region that your market lives in. Please communicate with RBI reps to know which region your market is hosted.

  • When querying the loyalty platform, please make sure to set the x-ui-region header to the country code you want to query, in uppercase, for example:

...

Code Block
query getLoyaltyRewards {
  loyaltyRewards(loyaltyId: "<USER_LOYALTY_ID>", where: { omitInvalids: false }) {
    id
    name
    errors {
      code
      ruleId
    }
  }
}

Example rewards query response

Code Block
{
  "data": {
    "loyaltyRewardsV2": [
      {
        "id": "3b5bdddc-c7c9-42d8-9332-b0c3f36c8e1c",
        "name": "Value Powerade Zero",
        "errors": null
      },
      { }
}

Example rewards query response

Code Block
{
  "data": {
    "loyaltyRewardsV2": [
      {
        "id": "3b5bdddc-c7c9-42d8-9332-b0c3f36c8e1c",
        "name": "Value Powerade Zero",
        "errors": null
      },
      {
        "id": "728aaedd-3234-4eae-89af-35cd5672adcb",
        "name": "Large Dr. Pepper",
        "errors": null
      },
      {
        "id": "480122d7-86ff-4db0-965c-7dbb72bb5179",
        "name": "Value Soft Drinks",
        "errors": null
      }
    ]
  }
}

 

Mapping loyalty offers between Sanity and the Loyalty Engine

After retrieving all the available offers from both sources, you need to map this data to get a complete list of offers available to the user. Below there is a simple example in JavaScript demonstrating how to perform this mapping:

Note

This example focuses on the basic data mapping process. It does not include logic related to offer rules, authentication requirements, or error handling. Each implementation should incorporate the necessary logic based on its specific needs.

Code Block
const { liveConfigOffers, sortedSystemwideOffers } = sanityOffers;
const { loyaltyOffersV2 } = loyaltyEngineOffers;

const allAvailableUserOffers = loyaltyOffersV2
  .map(loyaltyOffer => {
    let sanityOffer;

    if (loyaltyOffer.type === 'GLOBAL') {
      sanityOffer = sortedSystemwideOffers.find(
        

...

offer => offer.loyaltyEngineId === loyaltyOffer.id
      

...

);
    } else if (loyaltyOffer.type === 'PERSONALIZED') {
      sanityOffer 

...

= liveConfigOffers.find(
      

...

  offer => offer.loyaltyEngineId === loyaltyOffer.id
  

...

 

...

   );
    }

...


...

 

...

 

...

  if (sanityOffer) {
    

...

 

...

 return sanityOffer;
    }
  })
 

...

 .filter(offer => 

...

offer 

...

 

!== undefined);

In this example 💡:

  • sanityOffers contains the offers retrieved from Sanity, destructured into liveConfigOffers (personalized offer templates) and sortedSystemwideOffers (system-wide offers).

  • loyaltyEngineOffers contains the offers retrieved from the Loyalty Engine, specifically the loyaltyOffersV2 array.

  • allAvailableUserOffers contains all the available offers for the user.