Solved

Shopify Functions Input Variables

nelumoraru
Shopify Partner
8 1 2

Hey everyone, I'm trying to apply some discount using shopify functions on customers with certain tags. Passing static strings in the graphql query, into the field "hasAnyTags", seems to work, but using input variables I can't seem to make it work. Below I have attached some screenshots with the query, metafields and the result I'm getting. Am I missing something?

 

Screenshot 2024-04-04 at 16.42.36.png

Screenshot 2024-04-04 at 16.42.41.png

Screenshot 2024-04-04 at 16.43.09.png

Screenshot 2024-04-04 at 16.43.22.png

    

Accepted Solution (1)

nelumoraru
Shopify Partner
8 1 2

This is an accepted solution.

Found a solution, apparently the metafield type cannot be "json_string", it has to be "json". Maybe someone will find this useful

View solution in original post

Replies 13 (13)

nelumoraru
Shopify Partner
8 1 2

This is an accepted solution.

Found a solution, apparently the metafield type cannot be "json_string", it has to be "json". Maybe someone will find this useful

Hamza_Hussain
Shopify Partner
37 3 7

I had the same problem but in the end I had to drop the idea of adding tags to customer 😣 instead I just made admin settings to select customers and then passed the customer data and and discounted products data into a Shopify discount Note Metafield and then continued the function from there.  I would like to know one thing that you used a parameter like in the code below $customerTag. how did you add customer get this on functions and how did you passed the tags ?

 

 

query RunInput($customerTag: [String!]) {
  cart {
    buyerIdentity {
      customer {
        amountSpent {
          amount
        }
        metafield(namespace: "custom", key: "customerDiscount") {
          value
        }
        hasTags(tags: $customerTag) {
          hasTag
          tag
        }
      }
    }
  }
}

 

Honey G Hamza
nelumoraru
Shopify Partner
8 1 2

If I understood the question correctly, you are asking how I'm getting the customer tags to search for as a variable in the query?

You can see in the last screenshot that the discount node function has a metafield of type "json" and a value  as an object with a key "customerTag". To use this key in the graphql query, the names of the variable and the name of the metafield's object key need to match.

 

So because I have in the metafield a key:

customerTag: ["EXM: Vip"]

 and the variable in the graphql is also "customerTag", the shopify function passes the value in the variable.

 

Hope this helps.)

Hamza_Hussain
Shopify Partner
37 3 7

I am stuck in one more place can you help me with that ? I added the metafield as you said. the query is okay and when I send the data that works fine too 

 

Hamza_Hussain_5-1713527182486.png

 

Hamza_Hussain_4-1713524982873.png

 

 

but customer tag is missing from my response

 

Hamza_Hussain_1-1713524642717.png

 

I have added the the tag to customer 

Hamza_Hussain_2-1713524819517.png

 

I also received a positive response from the admin when I called the setMetafield API

 

Hamza_Hussain_3-1713524925267.png

 

Here's how I send my data 

Hamza_Hussain_6-1713527520454.png

 

can you tell me what went wrong here ?

Honey G Hamza
Nick_Wesselman
Shopify Staff
156 39 60

It appears that the value of your customerTag metafield is ["customerTag"], which when passed into hasTags is asking the question, "does this customer have the tag customerTag'? The screenshot shows the only tag on the customer is actually customerDiscount. So the value of your metafield should be ["customerDiscount"].

 

You can find the docs for input query variables here.

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

Hamza_Hussain
Shopify Partner
37 3 7

I fixed the confusion of customer tags and customer discounts but the problem remains the same I have updated the code Can you please have a look and tell me what's going wrong here.

 

Here is the Query I am using now 

Hamza_Hussain_0-1714660293675.png

 

and here is the toml file 

Hamza_Hussain_1-1714660522803.png

After updating the toml file I deployed the app and ran npm run dev and made a Discount using my app  

Hamza_Hussain_2-1714660984812.png

The metafield was created no errors came but this time no discount was given 

below is a copy of my response

{
  "discountNode": {
    "metafield": {
      "value": "{\"discount_title\":\"CQ Discount \",\"customerObj\":{\"customer_discount_amount\":150,\"customer_amount_type\":\"value\",\"customerDiscountMessage\":\"Customer Gets $150 discount\",\"customerDiscountProducts\":[{\"handle\":\"the-collection-snowboard-hydrogen\",\"id\":\"gid://shopify/Product/6947630973062\",\"optionId\":\"gid://shopify/ProductOption/9030156288134\"},{\"handle\":\"the-collection-snowboard-liquid\",\"id\":\"gid://shopify/Product/6947631300742\",\"optionId\":\"gid://shopify/ProductOption/8965429821574\"},{\"handle\":\"the-collection-snowboard-oxygen\",\"id\":\"gid://shopify/Product/6947631235206\",\"optionId\":\"gid://shopify/ProductOption/8965429723270\"}]},\"productsObj\":{\"product_discount_amount\":10,\"product_amount_type\":\"percentage\",\"productDiscountMessage\":\"pr\",\"discountProducts\":[]}}"
    }
  },
  "cart": {
    "buyerIdentity": {
      "customer": {
        "id": "gid://shopify/Customer/6618661027974",
        "email": "hamza.mujahid.hussain@gmail.com",
        "hasTags": []
      }
    },
    "lines": [
      {
        "merchandise": {
          "id": "gid://shopify/ProductVariant/40359002505350",
          "product": {
            "id": "gid://shopify/Product/6947631300742",
            "handle": "the-collection-snowboard-liquid"
          }
        }
      },
      {
        "merchandise": {
          "id": "gid://shopify/ProductVariant/40359002275974",
          "product": {
            "id": "gid://shopify/Product/6947631136902",
            "handle": "the-multi-managed-snowboard"
          }
        }
      }
    ]
  }
}

  

And below is the code that sets my metafield 

 

  const addDataToFunction = async (ownerId, metafieldKey, metaFieldNameSpace, metafieldValue, metafieldType) => {
        const jsonField = JSON.stringify(metafieldValue)
        const response = await admin.graphql(
            `#graphql
            mutation MetafieldsSet($metafields: [MetafieldsSetInput!]!) {
              metafieldsSet(metafields: $metafields) {
                metafields {
                  key
                  namespace
                  value
                  createdAt
                  updatedAt
                }
                userErrors {
                  field
                  message
                  code
                }
              }
            }`,
            {
                variables: {
                    metafields: [
                        {
                            key: metafieldKey,
                            namespace: metaFieldNameSpace,
                            ownerId: ownerId,
                            type: metafieldType,
                            value: jsonField
                        },
                    ]
                },
            },
        );

        const data = await response.json();
        console.log("---------------------------metaField Responce---------------------------");
        console.log("metaField Responce", JSON.stringify(data));
        return json({ data });

    }

Now can you tell what is going wrong because I'm going in circles here 😢

Honey G Hamza
Nick_Wesselman
Shopify Staff
156 39 60

Based on your previous post, it looks like you are setting the customerDataTags metafield on the AppInstallation. It needs to be set on the function owner -- in this case, the discount.

 

Also, app-owned metafields should be prefixed $app:, not app:.

 

You can find the docs for input query variables here.

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

Hamza_Hussain
Shopify Partner
37 3 7

Based on your reply

I used "gid://shopify/DiscountAutomaticNode/123" to set the Metafield.

Is this the correct Id to set discount metafeild?

I also changed the nameSpace to $app:customerNameSpace in my code and in my toml file

 

 

    const addDataToFunction = async (ownerId, metafieldKey, metaFieldNameSpace, metafieldValue, metafieldType) => {
        const jsonField = JSON.stringify(metafieldValue)
        const response = await admin.graphql(
            `#graphql
            mutation MetafieldsSet($metafields: [MetafieldsSetInput!]!) {
              metafieldsSet(metafields: $metafields) {
                metafields {
                  key
                  namespace
                  value
                  createdAt
                  updatedAt
                }
                userErrors {
                  field
                  message
                  code
                }
              }
            }`,
            {
                variables: {
                    metafields: [
                        {
                            key: metafieldKey,
                            namespace: metaFieldNameSpace,
                            ownerId: ownerId,
                            type: metafieldType,
                            value: jsonField
                        },
                    ]
                },
            },
        );

        const data = await response.json();
        console.log("---------------------------metaField Responce---------------------------");
        console.log("metaField Responce", JSON.stringify(data));
        return json({ data });

    }

   addDataToFunction("gid://shopify/DiscountAutomaticNode/123", "customerDataTags", "$app:customerNameSpace", { "customerTag": ["customerDiscount", "customerDiscount2", "customerTag"] }, "json")

 

 

Hamza_Hussain_0-1715070813536.png

 

But the main output is the same I think the problem is with the Global Id now I am giving it Can you please tell me where am I going to get the gid to set my metafield. 

 

 

Honey G Hamza
Nick_Wesselman
Shopify Staff
156 39 60

The GID of the discount looks correct. This JavaScript you are using to set the value, is it part of the same app as your function? Otherwise the function wouldn't be able to see the metafield. I'd recommend using the GraphiQL built into 'shopify app dev' in the latest Shopify's CLI (not the GraphiQL app) to confirm that the metafield was set correctly on the discount.

 

Are you sure the metafield value is not making it into the function variable now? Are you getting any errors about unset variables? hasTags is still empty in your Function input? You can try temporarily adding the metafield to your input query to debug its value as well.

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

Hamza_Hussain
Shopify Partner
37 3 7

Finally found the answer I was making a mistake by using mutation MetafieldSet the problem was, I needed to set metafield value to my Shopify Function and I was already sending a metafield value to my function but I also wanted to send another at the same time let me show you what I did because even I could not understand what I did 😅 so this is what happened

 

 

 const response = await admin.graphql(
        `#graphql
        mutation discountAutomaticAppCreate($automaticAppDiscount: DiscountAutomaticAppInput!) {
          discountAutomaticAppCreate(automaticAppDiscount: $automaticAppDiscount) {
            userErrors {
              field
              message
            }
            automaticAppDiscount {
              discountId
              title
              startsAt
              endsAt
              status
              appDiscountType {
                appKey
                functionId
              }
            }
          },
        }`,
        {
            variables: {
                automaticAppDiscount: {
                    title: discount_title,
                    functionId: process.env.FUNCTIONID,
                    startsAt: getTodayDateString(),
                    endsAt: null,
                    metafields: [
                        {
                            namespace: "$app:customerNameSpace",
                            key: "customerDataTags",
                            type: "json",
                            value: customJson,
                        }
                    ]
                }
            },
        },
    );

 

 

Now I am simply doing this and now I don't need the owner ID

 

 const response = await admin.graphql(
        `#graphql
        mutation discountAutomaticAppCreate($automaticAppDiscount: DiscountAutomaticAppInput!) {
          discountAutomaticAppCreate(automaticAppDiscount: $automaticAppDiscount) {
            userErrors {
              field
              message
            }
            automaticAppDiscount {
              discountId
              title
              startsAt
              endsAt
              status
              appDiscountType {
                appKey
                functionId
              }
            }
          },
        }`,
        {
            variables: {
                automaticAppDiscount: {
                    title: discount_title,
                    functionId: process.env.FUNCTIONID,
                    startsAt: getTodayDateString(),
                    endsAt: null,
                    metafields: [
                        {
                            namespace: "$app:customerNameSpace",
                            key: "customerDataTags",
                            type: "json",
                            value: customJson,
                        },
                        {
                            namespace: "custom",
                            key: "discountOBJ",
                            type: "json",
                            value: resultJson,
                        }
                    ]
                }
            },
        },
    );

 

This way I am sending 2 metafields and now everything seems to works fine ☺

Honey G Hamza

Ahsan-ah-med
Shopify Partner
10 1 1
You missing this tags return an array and variable calling code like ${} dollar sign $ and parentheses write inside parentheses your variable name 
(
tags: ["${customerTag}"])
Ahsan Ahmed
Shopify Developer | 2 Years of Experience
Transforming Websites into Shopify
 Converting Existing Websites (WooCommerce, Figma, Magento, etc.) to Shopify
️ Developing Custom Shopify Apps for Unique Client Needs
 Enhancing Shopify Functions with Checkout Extensions for Plus Users
Let's Build Your Dream Store Together!
nelumoraru
Shopify Partner
8 1 2

No, it doesn't work like that). The variable is already an array of strings:

$customerTags: [String!]

 

And you can not pass variables like you showed in graphql.

Ahsan-ah-med
Shopify Partner
10 1 1

Yes you are right
Thanks

Ahsan Ahmed
Shopify Developer | 2 Years of Experience
Transforming Websites into Shopify
 Converting Existing Websites (WooCommerce, Figma, Magento, etc.) to Shopify
️ Developing Custom Shopify Apps for Unique Client Needs
 Enhancing Shopify Functions with Checkout Extensions for Plus Users
Let's Build Your Dream Store Together!