-
Notifications
You must be signed in to change notification settings - Fork 30
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Tag parsing wrong contents array? #37
Comments
event parameter should be "x-fb-cd-contents" rather than
"contents" 👍 (also change 'price' to 'item_price' in your custom JS
variable)
—
Kevin O'Connor, Digital Marketing Analyst
www.iDimension.com <http://www.idimension.com/?utm_id=VwkC>
+1 (866) 524.3733
…On Thu, Jun 23, 2022 at 12:31 PM billboyles ***@***.***> wrote:
We are using a server-side tag setup for GTM where the data is passed to
the server as a GA4 Purchase event and then sent along to FB CAPI using
this Facebook Incubator tag template.
I've written a custom Javascript variable in GTM to parse a Google
Analytics ecommerce "products" array and return it in the format FB CAPI
wants for "contents":
[image: image]
<https://user-images.githubusercontent.com/38093848/175348408-c14f6bf4-f3e4-461c-85c4-369788e19fe1.png>
[image: image]
<https://user-images.githubusercontent.com/38093848/175345596-5fc99162-c084-4412-bd70-bcac52219ea8.png>
As you can see, it takes the price, quantity, and sku for each item and
saves them in the correct format. I am explicitly passing this array as
"contents":
[image: image]
<https://user-images.githubusercontent.com/38093848/175346312-16a19d99-9991-452a-82f0-3fdfc78a3420.png>
However, trying to pass the purchase events to the server is failing with
code 400 and receives the following response:
{"error":{"message":"Invalid
parameter","type":"OAuthException","code":100,"error_subcode":2804008,"is_transient":false,"error_user_title":"Invalid
Contents Parameter","error_user_msg":"The contents parameter you entered
doesn\u2019t contain a list of JSON objects. Enter a list of JSON objects
that contain the product IDs associated with the event plus information
about the products. For example: [{ 'id' : 'ABC123', 'quantity' : '2',
'item_price' : 5.99}, { 'id' : 'XYZ789' , 'quantity' : 2, 'item_price' :
9.99}]","fbtrace_id":"ASsXl7dWNIzLxh8RdCpOp45"}}
Digging in, it seems like the tag is somehow creating its own "content"
array and ignoring the one I'm sending. In the process, it seems to be
grabbing the wrong field, using "name" instead of "sku". This is the
request body it is sending (some data anonymized):
{"data":[{"event_name":"Purchase","event_time":1656000012,"event_source_url":"
https://www.customer.com/order/checkout","action_source":"website","user_data":{"client_ip_address":"111.111.111.111","client_user_agent":"Mozilla/5.0
(Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/
102.0.0.0
Safari/537.36","ph":"a1b2c3d4e5f6...abcdef","fbp":"fb.1.1111...1111"},"custom_data":{"currency":"USD","value":7.94,"order_id":"4f719af2-3637-42ee-8e8a-28e8f3783858","contents":[{"title":"Homestyle
Huddle
Wrap","item_price":7.49,"quantity":1}]}}],"partner_agent":"gtmss-1.0.0-0.0.5"}
Specifically, note the contents array:
"contents":[
{
"title":" Homestyle Huddle Wrap",
"item_price":7.49,
"quantity":1
}
]
This is not what's being passed, and it actually doesn't match any of our
objects- we don't use "title" anywhere in our objects, so this object in
this format has to be coming from this tag template.
However, that seems to be making it fail, since FB is expecting "id" but
getting "title"? In other words, FB's tag seems to be ignoring the provided
"contents" array and instead building its own, but FB CAPI seems to be
rejecting the "contents" array built by FB's own tag.
Any thoughts on why this is happening and how to fix it? Why isn't the tag
using the "contents" array I have already built and am sending to it, and
why is the one it appears to be building failing?
—
Reply to this email directly, view it on GitHub
<#37>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AE3LD7GITTZSHNPS2UHFYQDVQSGO7ANCNFSM5ZU7BZCQ>
.
You are receiving this because you are subscribed to this thread.Message
ID: <facebookincubator/ConversionsAPI-Tag-for-GoogleTagManager/issues/37@
github.com>
|
I can definitely change that. However, it was working fine for months earlier this year and last year with this exact setup, That also still does not really explain where "title" is coming from. |
This does not appear to have resolved the issue. This is the GA4 client side tag sent to server: Note contents array:
Server side FB CAPI tag is sending this:
Note the contents array:
It definitely is an array unless it is being transformed by the FB CAPI tag somehow. It's showing as an object, unless "[Object object]" is a string, and I'm unsure how that would be happening. However, I'm now getting this response from FB CAPI:
The "title" stuff is gone but this just created a new issue. This was all working as recently as a month or two ago, even without renaming the "contents" array to "x-fb-cd-contents" or "price" parameter to "item_price". I'm unclear what's changed. I could try sending the parameters in the client side GA4 tag as something like: x-fb-cd-contents.id: 41263689 For other customers using user data for deduplication, I'm basically doing that with user_data- sending each of user_data.first_name, user_data.last_name, user_data.phone, and user_data.email as individual parameters in the client side GA4 tag. But I'm not sure how an array of multiple items could be sent that way, especially when I have no way to predict how many items a customer might be ordering. |
Removing the contents array entirely just gets me back to the original issue. It's not required, so I was hoping I could at least get purchase tracking back by sending only "value", "currency", and "order_id". I do this for other customers whose setup does not make detailed purchase information available and it works fine. Here's an example from another customer that is currently working: So I took off "x-fb-cd-contents" and tried this instead: I can't remove the "items" array if I want that data in GA4. But it seems like the FB CAPI tag is grabbing that and trying to convert it to a "contents" array, but we're back to the "title" parameter being put in and not having an "id" parameter. This gets sent to server: As you can see, no contents array at all. But the CAPI tag sends this:
Here we are with a "contents" array again, and again it weirdly contains a parameter called "title" that is definitely not coming from any of the data sent from the browser side tags, since as you can see none of those tags contain a "title" parameter for any item, even in "items" array intended for GA4's use. And we're back to the server replying with:
Why is the FB CAPI tag doing this, and how can I avoid it? I don't see how I can include items for GA4 without FB CAPI doing this. Removing the "items" array from the GA4 request entirely isn't a viable option. |
Ultimately, the issue seems to be that the FB CAPI tag is taking this:
and turning it into:
But it should be turning it into this:
or at least this (which would be fine):
|
the issue is that your items array doesn't have the item_id field, which GA4 requires BTW. That's what is supposed to get mapped to 'id' in the contents array by this commit back in March 2021: 767618f
|
In this case, "sku" is a carryover from older UA ecommerce, where it was a required field. From the Google side, GA4 definitely doesn't require "item_id". After all, it's working fine without it. So it's actually a bit more complicated than saying "item_id" is required. Regardless, the FB CAPI tag could (and I would argue, should) be handling the issue a lot more gracefully. For instance, the CAPI could accept a request without "id"- while the error response lists "id", "item_price", and "quantity" as required fields (and I seem to remember them as listed required fields in the dev documentation back before they did everything with the change to "Meta"), I can't find anything in the current documentation saying any of parameters are required. I see this: Note that "title" isn't even a listed as an available field (incidentally, neither are "brand" or "category"). However, even if "id" is required (as seems to be the case), "title" is not (as noted above, it doesn't even to seem to be a documented parameter). So it makes sense to prioritize "id". It could look for "id" first, then if not found, it could look for "sku" or "name" and use that as "id" instead, only including "name" if it already has "id". Barring either of the above, It could simply not send the "contents" array if it can't match required fields, instead of failing out the entire request, since only "currency" and "value" are required. It seems like this is the kind of basic check that good code would make. I'm sure Facebook would rather accept the request in some form and get some data rather than getting nothing and having it fail entirely. This would work fine for my agency, and be preferable to not being able to send purchase requests at all. Right now, despite GA4 handling the requests fine, the FB requests using the same array are failing. I have no way to send the "items" array as it currently exists to GA4 (which again, handles it fine) without also sending it to FB and having everything fail. The only solution on my end is to stop sending an "items" array to GA4 entirely, or to have my code team rewrite code across a number of websites. Neither are particularly tenable. |
🤔 It does look like you're partially correct. Per Facebook pixel events
reference
<https://developers.facebook.com/docs/meta-pixel/reference#object-properties>,
id is required in the contents array:
[image: image.png]
that's in the pixel-specific docs rather than the conversions API docs, but
it's the same entity receiving the events, Facebook just has bad
documentation. The conversions API docs in your screenshot don't explicitly
say "required", but it is implied by the definition that ID is required
("list of JSON objects that contain product IDs"):
[image: image.png]
I'll grant you, however, that the GA4 e-commerce documentation
<https://developers.google.com/analytics/devguides/collection/ga4/reference/events#purchase_item>
does say either item_id *or* item_name are required, so it would make sense
to have the tag fall back to using the SKU or item_name as the id in the
contents array if not available. So I see your point and I encourage you to
submit a PR for it.
[image: image.png]
In the meantime, for your use case, since you're already generating the
items array with a custom JS variable why not just *add* the item_id as a
copy of SKU? e.g.:
"items": [
{
"name": "Sausage Biscuit Combo",
"price": 5,
"quantity": 1,
"sku": 41263689
}
]
*becomes:*
"items": [
{
"name": "Sausage Biscuit Combo",
"price": 5,
"quantity": 1,
"sku": 41263689,
"item_id": 41263689
}
]
That shouldn't cause any issues in GA4 but would solve your problem without
waiting indefinitely for Facebook to merge a PR (I've had once since August
2021, and there are open PRs fixing issues since March 2021 without so much
as a comment from FB/Meta... so I wouldn't hold your breath)
… Message ID:
<facebookincubator/ConversionsAPI-Tag-for-GoogleTagManager/issues/37/1165979578
@github.com>
|
That's actually not a bad suggestion. Thanks! |
Summary: Fixing issue #37 of the Issues@ Github repository #37 References Phase 1 fixes : https://docs.google.com/spreadsheets/d/1hNyHkqfdeWO_qkIfix2Gilriz28D_xkMCmk3nbnhVgM/edit#gid=0/ Parameters in the contents array changed which is causing issue in parsing. Removed title, brand and category. Earlier parsing items array [{"item_name" : 'Homestyle Huddle Wrap', "item_price" : 7.49, "quantity" : 1}] resulted in this: "contents":[{ "title" : "Homestyle Huddle Wrap","item_price" : 7.49,"quantity" : 1}] Now corrected "contents":[{ "id" : "Homestyle Huddle Wrap","item_price" : 7.49,"quantity" : 1}] Differential Revision: D44417088 fbshipit-source-id: 190d12ba6fc51ce753cf5881779c4d9303cc02b5
Hi, what would be the correct code today to get the correct values? |
We are using a server-side tag setup for GTM where the data is passed to the server as a GA4 Purchase event and then sent along to FB CAPI using this Facebook Incubator tag template.
I've written a custom Javascript variable in GTM to parse a Google Analytics ecommerce "products" array and return it in the format FB CAPI wants for "contents":
As you can see, it takes the price, quantity, and sku for each item and saves them in the correct format. I am explicitly passing this array as "contents":
However, trying to pass the purchase events to the server is failing with code 400 and receives the following response:
Digging in, it seems like the tag is somehow creating its own "content" array and ignoring the one I'm sending. In the process, it seems to be grabbing the wrong field, using "name" instead of "sku". This is the request body it is sending (some data anonymized):
Specifically, note the contents array:
This is not what's being passed, and it actually doesn't match any of our objects- we don't use "title" anywhere in our objects, so this object in this format has to be coming from this tag template.
However, that seems to be making it fail, since FB is expecting "id" but getting "title"? In other words, FB's tag seems to be ignoring the provided "contents" array and instead building its own, but FB CAPI seems to be rejecting the "contents" array built by FB's own tag.
Any thoughts on why this is happening and how to fix it? Why isn't the tag using the "contents" array I have already built and am sending to it, and why is the one it appears to be building failing?
The text was updated successfully, but these errors were encountered: