Skip to content
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

(R2.1f) Google tag enhanced conversion #2258

Conversation

ankitrox
Copy link
Collaborator

@ankitrox ankitrox commented Feb 15, 2024

Changes proposed in this Pull Request:

Related to #2216.

  1. If the enhanced conversion is enabled add the { 'allow_enhanced_conversions': true } to the global site tag config (see this article).
  2. When the enhanced conversion is disabled, remove the above config from global site tag.
  3. When the enhanced conversion is enabled, add the hashed user data on order received page so that it can be sent to analytics. The formatting for hashed data can be found in this article.
  4. When the enhanced conversion is disabled, do not add user data on order received page.

Screenshots:

See testing screenshots in this QA report.

Detailed test instructions:

Steps (when enabled):

  1. If the Enhanced Conversion setting is not already enabled, navigate to WP Dashboard > Marketing > Google Listing & Ads > Settings and enable it.
  2. Add a product to the cart and proceed to complete the checkout process.
  3. Verify that the order is successfully placed and the thank you page is displayed to the customer.
  4. View the source code of the thank you page.

Expected Result:

  1. The configuration 'allow_enhanced_conversions:true' should be present in the Global Site Tag within the source code of the thank you page.
  2. User data should be present in encrypted form on the thank you page. As shown in the screenshot.

Additional details:

Changelog entry

Update - Set the "allow_enhanced_conversions" flag to Google tag when Enhanced Conversions is enabled.

@github-actions github-actions bot added the changelog: update Big changes to something that wasn't broken. label Feb 15, 2024
Copy link

codecov bot commented Feb 15, 2024

Codecov Report

Attention: Patch coverage is 0% with 62 lines in your changes are missing coverage. Please review.

Project coverage is 62.0%. Comparing base (d896b88) to head (c2d73c2).
Report is 31 commits behind head on feature/2239-enhanced-conversions-panel.

Additional details and impacted files

Impacted file tree graph

@@                             Coverage Diff                             @@
##             feature/2239-enhanced-conversions-panel   #2258     +/-   ##
===========================================================================
- Coverage                                       62.2%   62.0%   -0.1%     
- Complexity                                      4220    4239     +19     
===========================================================================
  Files                                            767     767             
  Lines                                          21848   21913     +65     
  Branches                                         554     552      -2     
===========================================================================
+ Hits                                           13587   13595      +8     
- Misses                                          7797    7854     +57     
  Partials                                         464     464             
Flag Coverage Δ
js-unit-tests 54.7% <ø> (+0.1%) ⬆️
php-unit-tests 63.6% <0.0%> (-0.2%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files Coverage Δ
src/Google/GlobalSiteTag.php 0.0% <0.0%> (ø)

... and 26 files with indirect coverage changes

@ankitrox ankitrox marked this pull request as ready for review February 16, 2024 11:16
@ankitrox ankitrox self-assigned this Feb 16, 2024
Copy link
Collaborator

@joemcgill joemcgill left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @ankitrox. Left some feedback inline. I don't see any existing unit tests covering this maybe_display_conversion_and_purchase_event_snippets() function, but there are some E2E tests at /tests/e2e/specs/gtag-events/gtag-events.test.js that could be updated to make sure EC data is added.

src/Google/GlobalSiteTag.php Outdated Show resolved Hide resolved
src/Google/GlobalSiteTag.php Outdated Show resolved Hide resolved
@joemcgill joemcgill changed the title Update/52310672 google tag enhanced conversion (R2.1f) Google tag enhanced conversion Feb 16, 2024
@joemcgill joemcgill linked an issue Feb 16, 2024 that may be closed by this pull request
6 tasks
@ankitrox ankitrox changed the base branch from feature/2239-enhanced-conversions-panel-e2e to feature/2239-enhanced-conversions-panel February 26, 2024 14:48
@joemcgill joemcgill self-assigned this Mar 4, 2024
Copy link
Collaborator

@joemcgill joemcgill left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the updates, @ankitrox. Left a bit of feedback that needs to be addressed. I'm looking into the E2E tests to see why those are failing as well.

src/Google/GlobalSiteTag.php Outdated Show resolved Hide resolved
src/Google/GlobalSiteTag.php Outdated Show resolved Hide resolved
@ankitguptaindia
Copy link
Member

QA/Test Report-

Testing Environment -

  • WordPress: 6.4.3
  • Theme: Storefront Version: 4.5.4
  • WooCommerce - Version 8.6.1
  • PHP: 8.0.22
  • Web Server: Nginx
  • Browser: Chrome - Version 121
  • OS: macOS Sonoma 14.3
  • Git Branch: update/52310672-google-tag-enhanced-conversion

Test Results -

  • When Enhance Conversation Tracking is enabled from the setting. Tag ' allow_enhanced_conversions':true } is appearing and tag gtag("set", "user_data", ..) shows user info in encrypted form.

  • When Enhance Conversation Tracking is disabled. Above information does not appear on the order received page.

Functional Demo / Screencast -

When Enhanced Conversion Tracking is Enabled
Screenshot 2024-03-12 at 8 07 16 PM Screenshot 2024-03-12 at 8 08 38 PM
Screenshot 2024-03-12 at 8 10 45 PM
When Enhanced Conversion Tracking is Disabled
Screenshot 2024-03-12 at 8 14 41 PM Screenshot 2024-03-12 at 8 15 23 PM

@joemcgill joemcgill force-pushed the update/52310672-google-tag-enhanced-conversion branch from c5a40fd to 1afe1d5 Compare March 15, 2024 20:02
Copy link
Collaborator

@joemcgill joemcgill left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mikkamp This PR is ready for an initial review. This only adds the enhanced conversion data to the gtag data during checkouts, which will be integrated into the rest of #2242.

I've updated the testing instructions in the PR details.

We've been able to confirm this is working the way we think it's supposed to work while testing locally during QA, but I'm having trouble getting the E2E tests working and am finding them difficult to debug since the test environment doesn't seem to be set up locally the same way they are set up for the CI Workflow. If you have any advice, I can work on getting those fixed up.

@joemcgill joemcgill dismissed their stale review March 17, 2024 20:49

Out of date

@joemcgill joemcgill requested a review from mikkamp March 17, 2024 20:49
Copy link
Contributor

@mikkamp mikkamp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for implementing the code, it works as outlined in the PR description. However I think it's important that it works for Guest orders as well.

Also I'm not able to actually confirm that the data gets sent with the conversion event. What else am I missing to get the data to be sent? It's something we should validate in the E2E test as well.

Comment on lines 355 to 364
$customer = new WC_Customer( $order->get_customer_id() );
$email = $customer->get_billing_email();
$fname = $customer->get_billing_first_name();
$lname = $customer->get_billing_last_name();
$phone = $customer->get_billing_phone();
$billing_address = $customer->get_billing_address();
$postcode = $customer->get_billing_postcode();
$city = $customer->get_billing_city();
$region = $customer->get_billing_state();
$country = $customer->get_billing_country();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you clarify why we need to get this from the customer directly. I just tested this with a guest user and since in those cases the customer_id is 0 it doesn't get any details. The billing details can also be fetched directly from the order. Since the order details are about the actual purchase and not the ones stored on the customer account, I think it would be more accurate to get them from the order anyway.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you. I have changed this to use $order object instead of customer to add the data which would be more accurate as you mentioned.


$purchase_user_data_gtag = sprintf( 'gtag("set", "user_data", %s)', wp_json_encode( $ec_data ) );

$this->add_inline_event_script( $purchase_user_data_gtag );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is working, as in it's adding the snippet to the page:

gtag( "set", "user_data", {
	"sha256_email_address": "2eb9d564b813d572e4ed03bb5a58459a93caa71b7b227338b682fd038b291a3d",
	"sha256_phone_number": "422ce82c6fc1724ac878042f7d055653ab5e983d186e616826a72d4384b68af8",
	"address": {
		"sha256_first_name": "96d9632f363564cc3032521409cf22a852f2032eec099ed5967c0d000cec607a",
		"sha256_last_name": "799ef92a11af918e3fb741df42934f3b568ed2d93ac1df74f1b8d41a27932a6f",
		"sha256_postal_code": "ea4ffb75adc0903ab5ff284da63b2abe9f3591415e97226a77751b93acfd5d3e",
		"sha256_country": "292c1980ba2805512acfef5d0cf8f43fba5c7b9b73a5a7afad1c37cfacad3c98",
		"sha256_street": "6008c26f4452392acb19374bc12a5ec0c360ae17356bce8b786fb128c8720951",
		"sha256_city": "11a62c23412b77477a71481aa2dc7323bcc61d076c8449076c4c58a8356c1bb1",
		"sha256_region": "18ac3e7343f016890c510e93f935261169d9e3f565436429830faf0934f4f8e4"
	}
} )

But when I look at the tracking data sent to Google I'm not seeing the valid data being sent. I'm following the instructions: Validate your implementation using Chrome Developer Tools

I can see the regular data about the event:

data: event=conversion

But this part I'm not seeing:

Look for a parameter “em” with a hashed string as the value. The value should start with “tv.1~em” followed by a long string of characters. If you see the "em" parameter, this means that the enhanced conversions tag is picking up and hashing the enhanced_conversion_data object.

How can I confirm it is actually including the data? It seems the E2E tests are also just checking for the user_data being sent in the page, and not for the data being sent in the tracking request. That would make it closer to a unit test if it confirms the data is output in the page, seeing expected data appear in the tracking request like is done for the other tests would be more of an E2E test.

The other way to validate the data is to check the Ads account, but it says I have to wait 48hours for that, so I'll have to get back to you if it ever appears.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right, I can't see the em property as mentioned in the document, but I think if its possible we should wait to check if it is being reflected in ads account after 48 hours as we did all the steps according to the documentation.

Comment on lines 383 to 384
$ec_data['address']['sha256_postal_code'] = $this->normalize_and_hash( $postcode );
$ec_data['address']['sha256_country'] = $this->normalize_and_hash( $country );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The documentation shows there is only a hashed field available for the first_name / last_name. Do the other address fields just not have updated documentation?

This documentation specifically mentions not to hash it: https://developers.google.com/google-ads/api/docs/conversions/enhanced-conversions/web#prepare-data

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mikkamp Thank you for catching that. As per documentation, it seems that we need to normalize and has

  1. First name
  2. Last name
  3. Phone number
  4. Email address

Rest of the fields have been changed to the raw format (without hash).

*
* @return string
*/
private function normalize_and_hash( string $value, $algo = 'sha256' ): string {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this function apply all the hashing rules? Looking at this documentation: https://developers.google.com/google-ads/api/docs/conversions/enhanced-conversions/web#php

This one would be missing:

Remove all periods (.) that precede the domain name in gmail.com and googlemail.com email addresses

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added the normalization to remove any periods in the email address if has domain gmail.com or googlemail.com

@joemcgill
Copy link
Collaborator

@ankitrox and @mikkamp, I gave this another test and noticed a few things that got messed up during the previous merge conflict resolution, which I've resolved in c2d73c2.

From what I can tell, all of the data is being hashed correctly now, per the docs, but I am also not able to verify the presence of an em param so far. I'm not sure if this is due to me testing on a local environment or if there is something else that needs to be updated before this will work, but I'm not seeing any functional errors at this point.

One of the assumptions that this implementation is based on is that Google will automatically enable enhanced conversions if the Data Terms and Conditions has been accepted and a conversion tag is sent that includes { 'allow_enhanced_conversions': true } in the config along with hashed PII, so that's part of what we're trying to validate during UAT. If the code looks good, I'd suggest we merge this into the rest of the feature and continue testing there.

@joemcgill joemcgill requested a review from mikkamp March 21, 2024 01:24
Copy link
Contributor

@mikkamp mikkamp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the additional changes. I agree that everything is now working as intended, the code is working as expected.

The only minor comment I had left is that the function maybe_display_conversion_and_purchase_event_snippets is now over a 150 lines long. To add the enhanced conversion data we really only need the order object, so all that code can easily be moved to a separate function (including the call to add_inline_event_script). That would also allow returning early from the function if ( ! $this->is_enhanced_conversion_enabled() ), which would save a whole lot of indenting and make the code a bit easier to grasp (as well as unit test if we'd resort to that).

That's not a blocker for this PR though so I'll go ahead and approve it.

I did manage to get the enhanced conversion data to show up in the end, but to do so I must enable it in the Ads account (the method I choose doesn't seem to matter, but as soon as I disable it, the data is missing again).
image

With it enabled I can confirm that the hashes match and the additional address fields are also sent without hashes:

gtag( "set", "user_data", {
	"sha256_email_address": "2eb9d564b813d572e4ed03bb5a58459a93caa71b7b227338b682fd038b291a3d",
	"sha256_phone_number": "422ce82c6fc1724ac878042f7d055653ab5e983d186e616826a72d4384b68af8",
	"address": {
		"sha256_first_name": "96d9632f363564cc3032521409cf22a852f2032eec099ed5967c0d000cec607a",
		"sha256_last_name": "799ef92a11af918e3fb741df42934f3b568ed2d93ac1df74f1b8d41a27932a6f",
		"postal_code": "D02 AF30",
		"country": "IE",
		"street": "Street",
		"city": "City",
		"region":"D"
	}
} )
data: event=conversion
em: tv.1~
  em.2eb9d564b813d572e4ed03bb5a58459a93caa71b7b227338b682fd038b291a3d~
  pn.422ce82c6fc1724ac878042f7d055653ab5e983d186e616826a72d4384b68af8~
  fn0.96d9632f363564cc3032521409cf22a852f2032eec099ed5967c0d000cec607a~
  ln0.799ef92a11af918e3fb741df42934f3b568ed2d93ac1df74f1b8d41a27932a6f~
  sa0.YAjCb0RSOSrLGTdLwSpewMNgrhc1a86LeG-xKMhyCVE~
  ct0.city~
  pc0.D02 AF30~
  rg0.d~
  co0.IE

That seems to show that we are still missing hashing the street, which the documentation isn't consistent about. I'm also curious why the hashes look very different, as far as I can see we are following the documentation to the T, so we might need to ask Google why that's happening.

While that's not a blocker for this PR, it is something that needs to be addressed in #2242 As there it's the expectation that users only accept the terms and conditions. They aren't required to enable the Enhanced Conversions in the Ad account. I also believe Google mentioned there isn't a way to automatically enable it through the API. So that needs to be discussed a bit more otherwise it still won't track anything for users that don't enable it.

@joemcgill
Copy link
Collaborator

@mikkamp thank you for double checking the em data. I can confirm that I'm seeing the same behavior that you are describing where the data is only passed if I've manually enabled EC in the Ads account. I'll bring this up with folks at Google since it's not working as we were advised.

I also agree with you about the potential code cleanup for the maybe_display_conversion_and_purchase_event_snippets() snippet, so moved that code to a private method for now and added hashing to the street value, which isn't specified in this article but is recommended here and I'd rather be overly cautious about PII.

I'm going to go ahead and merge this and then we can address any follow-up tasks related to the EC values not being passed in follow-up PRs.

@joemcgill joemcgill merged commit ed9b948 into feature/2239-enhanced-conversions-panel Mar 21, 2024
14 checks passed
@joemcgill joemcgill deleted the update/52310672-google-tag-enhanced-conversion branch March 21, 2024 15:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
changelog: update Big changes to something that wasn't broken.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[R-2] Enable Enhanced Conversions (EC) for GL&A
4 participants