Issue with hasAnyTag input variable for Shopify Discount Function

Issue with hasAnyTag input variable for Shopify Discount Function

gjohnstonTT
Shopify Partner
5 1 5

Hi, 

I'm currently trying to build a Shopify Discount Function that will target products based off a tag. If I hardcode the tag value into the input query the function works however I would like this to be dynamic, along with the percentage off. I followed along with the using input variable documentation and my input query currently looks like this:  

query RunInput ($tags: [String!]) {
  cart {
    lines {
      quantity
merchandise { __typename ...on ProductVariant { id product { hasAnyTag(tags: $tags), } } } } } discountNode { metafield(namespace: "$app:product-discount", key: "function-configuration"){ value } } }

I also have updated my shopify.extension.toml to include the input variable and the function-configuration metafield, however after I use the Shopify GraphQL app to create my discount using the function id and passing through the json data for the metafield, upon running the function the product is not discounted even if it is tagged correctly and the value field in my discountNode  show as null. Here is the log for further context: 

{
  "cart": {
    "lines": [
      {
        "quantity": 1,
        "merchandise": {
          "__typename": "ProductVariant",
          "id": "gid://shopify/ProductVariant/47070228152616",
          "product": {
            "hasAnyTag": false
          }
        }
      }
    ]
  },
  "discountNode": {
    "metafield": null
  }
}


Any insight into what the issue with my code may be or what I may be missing would be beyond appreciated. 

 

Thank you! 

 

PS: Here is the run function as well 

* @Anonymous {RunInput} input
* @returns {FunctionRunResult}
*/
export function run(input) {
  /** 
  * @type {{
  *   percentage: number
  * }}
  */
  
  const configuration = JSON.parse(
    input?.discountNode?.metafield?.value ?? "{}"
  );

  if(!configuration.percentage){
    return EMPTY_DISCOUNT;
  }



  const targets = input.cart.lines

  // Only include cart lines with a quantity of two or more
  // and a targetable product variant
  .filter(line =>
    line.merchandise.__typename == "ProductVariant" && line.merchandise.product.hasAnyTag)
  .map(line => {
    const variant = /** @type {ProductVariant} */ (line.merchandise);
    return /** @type {Target} */ ({
      // Use the variant ID to create a discount target
      productVariant: {
        id: variant.id
      }
    });
  });

  if (!targets.length) {
    // You can use STDERR for debug logs in your function
    console.error("No cart lines qualify for product discount.");
    return EMPTY_DISCOUNT;
  }

  
  

  // The @Shopify/shopify_function package applies JSON.stringify() to your function result
  // and writes it to STDOUT
  return {
    discounts: [
      {
        // Apply the discount to the collected targets
        targets,
        // Define a percentage-based discount
        value: {
          percentage: {
            value: configuration.percentage.toString()
          }
        }
      }
    ],
    discountApplicationStrategy: DiscountApplicationStrategy.First
  };
};
Replies 5 (5)

Nick_Wesselman
Shopify Staff
167 42 65

Things to double check:

  • The namespace and key in your extension.toml matches the namespace and key of the metafield you set on the discount
  • The metafield on the discount is a JSON document with a key of `tags` that contains a string array of the tags
  • That you used the correct TOML location for the variable configuration (see guidance here on `[extensions.input.variables]` vs `[input.variables]`. 

Nick Wesselman | Shopify 
 - Was my reply helpful? Click Like to let me know! 
 - Was your question answered? Mark it as an Accepted Solution
 - To learn more visit the Shopify Help Center or the Shopify Blog

gjohnstonTT
Shopify Partner
5 1 5

Hey Nick thanks for the reply! 

Both the namespace and key match what is inside of my toml and I used the extensions.input.variables  

In terms of metafield on the discount I assume you mean within the input variable which in my case I had as such 

"metafields": [
      {
        "namespace": "$app:product-discount",
        "key": "function-configuration",
        "type": "json",
        "value": "{\"tags\":[\"testing\",\"testtest\"], \"percentage\": 25.0}"
      }

 

 

Nick_Wesselman
Shopify Staff
167 42 65

Are you sure you are setting the metafield on the discount you are creating? The one associated with your function id? Your metafield is null on your input json as well, so I suspect you are not properly saving the metafield on the discount. You can query the discounts on your shop w/ GraphiQL to confirm.

Nick Wesselman | Shopify 
 - Was my reply helpful? Click Like to let me know! 
 - Was your question answered? Mark it as an Accepted Solution
 - To learn more visit the Shopify Help Center or the Shopify Blog

gjohnstonTT
Shopify Partner
5 1 5

Hey Nick, it appears that does seem to be the issue so my question then becomes do the namespace and key need to be different for each metafield, and could that have something to do with why it's not updating? For example in my extension.toml for my input variable does that metafeild need to differ from the function-configuration metafield I have for changing the percentage within the discountNode, or would it more likely be how I'm triggering my creation mutation within the GraphQL app? Sorry if this is not super clear, but I really appreciate the help and insight so far.  

 

Editing this as I was able to figure a way to change the metafields and update their values, but it only happens if I do an update to the function, if I pass the metafield values through on the create mutation the fields keep setting to null, not sure why it's working on update but not creation?   

Nick_Wesselman
Shopify Staff
167 42 65

I'd suggest opening a new discussion in the Metafields and Custom Data board, with the mutation you are executing.

Nick Wesselman | Shopify 
 - Was my reply helpful? Click Like to let me know! 
 - Was your question answered? Mark it as an Accepted Solution
 - To learn more visit the Shopify Help Center or the Shopify Blog