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

[ps_googleanalytics]: add_to_cart event in realtime #37661

Open
2 tasks done
kreare opened this issue Dec 13, 2024 · 14 comments · May be fixed by PrestaShop/ps_googleanalytics#170
Open
2 tasks done

[ps_googleanalytics]: add_to_cart event in realtime #37661

kreare opened this issue Dec 13, 2024 · 14 comments · May be fixed by PrestaShop/ps_googleanalytics#170
Labels
Bug Type: Bug New New issue not yet processed by QA

Comments

@kreare
Copy link

kreare commented Dec 13, 2024

Prerequisites

Describe the bug and add attachments

Currently, the ps_googleanalytics module doesn't send events when they occurs (like the add to cart even) but add them on a queue, flushed on the next page load/change

This could be good for some events, but it loose a lot of add_to_cart events especially if you use a theme with an ajax add to cart button or if you have the redirect to cart disabled (default, I think).

In this case, the event is scheduled, but never sent to google if customer leave the website. I can see a lot of events still stored in the table, and they are never flushed, probably because the customer has left the website just after pressing the add to cart button.

Expected behavior

Events sent as soon as they occurs, not only queued for later flush

Steps to reproduce

  1. press 'add to cart' button
  2. close the website without changing the page

PrestaShop version(s) where the bug happened

8.1

PHP version(s) where the bug happened

No response

If your bug is related to a module, specify its name and its version

ps_googleanalytics

Your company or customer's name goes here (if applicable).

No response

@kreare kreare added Bug Type: Bug New New issue not yet processed by QA labels Dec 13, 2024
@kreare
Copy link
Author

kreare commented Dec 13, 2024

This also breaks the time of the event and the webpage that triggered the event itself, in example: on the homepage you add a product to cart, then, after 5 minutes, you change the page, in example to a category.

The flush is sending the add_to_cart event, but at the new time (5 minutes after the real event) and from the new page (ie the category page) and not from the homepage.

@Hlavtox
Copy link
Contributor

Hlavtox commented Dec 13, 2024

@kreare Yep, that's how I did it at the time. There is definitely a room for improvement, are you willing to rework it?

@kreare
Copy link
Author

kreare commented Dec 13, 2024

@kreare Yep, that's how I did it at the time. There is definitely a room for improvement, are you willing to rework it?

maybe yes, maybe not.
Honestly I don't have an idea how to call a javascript from the event code that is PHP

I did a quick check and ended opening the issue :-D

@panariga
Copy link
Contributor

panariga commented Dec 15, 2024

Something like this in .tpl:

    $('body').on('click', '[data-button-action="add-to-cart"]', function() {
      gtag('event',
        'add_to_cart', {
          "send_to": '[[[[[',
          "currency": 'xxx',
          "value":  xxx
        });
    });

But it will lose conversions on custom modules that use their own calls for adding to the cart.

@Codencode
Copy link
Contributor

Codencode commented Dec 16, 2024

To solve the problem without having to "overhaul" the current behavior, after adding to the cart, we could make an AJAX call to retrieve the code to be executed and run it?

For example:

# JS code
prestashop.on('updateCart', function (event) {
  $.ajax({
    type: "POST",
    url: ajaxUrl,
    dataType: "json",
    data: {
        ajax: true,
        op: "getData",
    },
    success: function (response) {
      response.forEach(code => {
        const fn = new Function(code);
        fn();
      });
    }
  });
});
# PHP code
 if (Tools::getValue('op') == 'getData'){
    $output = $this->module->getDataHandler()->readData();
    $this->module->getDataHandler()->deleteData();

    die(json_encode($output));
 }

If the idea works, I can create a PR.

@kreare
Copy link
Author

kreare commented Dec 16, 2024

Probably an even better workaround would be to retrieve the queue and run it after each actions, not only with add to cart.

In this way, all events are sent almost in real-time , relying on page changes only as fallback (load failure, javascript errors and so on)

Pseudo workflow:

  • add any event to the queue
  • immediatly fetch & flush the queue via ajax
  • run the queue

@Hlavtox
Copy link
Contributor

Hlavtox commented Dec 16, 2024

I like all of the ideas guys. I did it this way mostly because of reliability reasons. I wanted to avoid as much hassle with 3rd party themes as I could (example - some theme author decides to change data-button-action="add-to-cart" to something else.

And it seems to work. There have been virtually zero complains or tickets since v5 of ps_googleanalytics module. :-) Yep, it can be done better, maybe there are some things where we could are more data, but let's try to be as much reliable as possible.

@Hlavtox
Copy link
Contributor

Hlavtox commented Dec 16, 2024

And now when I am thinking about it. I think there could maybe be even more generic hook for these JS events?

Because apart from add to cart, we have for example product listing and changing a page. We only list products on first page load, but not after filters change. I think it should trigger the event for GA also.

Exactly as you said, after certain actions in FO - call to the core to get JS events in queue and execute them.

@kreare
Copy link
Author

kreare commented Dec 16, 2024

with my proposal you don't rely to theme customization, as the module still works the same.

the difference is only in queue flush, that is flushed always as soon as possible

@Codencode
Copy link
Contributor

I would still start by addressing the issue raised in this problem. So, if you think my idea could work, I’ll create the PR.
Of course, your ideas are great too. For updating products (on the category page), the updateProductList JS event could be used.

@kreare
Copy link
Author

kreare commented Dec 16, 2024

i think that the effort to listen a single event or all events tracked by the module is the same as the action to do is still the same for all events: just flush and execute the queue. so why not listen for almost everything and dump the queue?

@Codencode
Copy link
Contributor

Codencode commented Dec 16, 2024

The issue is that the JS events currently available in Prestashop are as follows:

  • updateCart
  • updatedCart
  • updatedAddressForm
  • updateDeliveryForm
  • changedCheckoutStep
  • updateProductList
  • clickQuickView
  • updateProduct
  • updatedProduct
  • handleError
  • updateFacets
  • responsive update

These are documented at the following link: https://devdocs.prestashop-project.org/8/themes/reference/javascript-events/

Based on what I’ve considered, clearing the queue without waiting for the page "change" can be achieved by using the existing events and executing the AJAX call.

Unless you have something different in mind, for example, triggering the AJAX call on DOM changes.

@kreare
Copy link
Author

kreare commented Dec 16, 2024

I think the queue dump could be done in:

updateCart
updatedCart
changedCheckoutStep
updateProductList
clickQuickView
updateProduct
updatedProduct

@Codencode Codencode linked a pull request Dec 17, 2024 that will close this issue
@Codencode
Copy link
Contributor

I have created a PR: PrestaShop/ps_googleanalytics#170.
I considered the following JS events:

  • updateCart
  • changedCheckoutStep
  • updatedProduct
  • updateProductList
  • clickQuickView

I did not consider updatedCart because it is triggered immediately after updateCart and
updateProduc" because it runs just before updatedProduct.

Let me know what you think and if there's anything to improve.

I also thought about creating an additional PR to handle the product list update using the JavaScript event updateProductList but I would like to get feedback on this code first.

Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Type: Bug New New issue not yet processed by QA
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants