Git Product home page Git Product logo

solidus_tracking's People

Contributors

aldesantis avatar cpfergus1 avatar kennyadsl avatar nirebu avatar seand7565 avatar waiting-for-dev avatar

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

solidus_tracking's Issues

Check if an order has an email before sending an event

If I have a guest user who is attempting to check out, solidus_tracking + Klaviyo will error out on the event "started_checkout" since the order does not have an email attached to it yet, since adding an email happens during checkout.

Klaviyo::KlaviyoError: You must identify a user by email or ID

Can we add a check to see if the order has an email attached before triggering the event? Or, ideally, some method that can be overritten to check for eligibility. We only submit orders to Klaviyo when a user is signed in, so we'd like to suppress all tracking for guest users, which would include all of the order lifecycle events.

Allow specifying global context

In many cases, it's useful to send some global context along with an event, such as the request's IP or user agent.

This is usually done via a before_action in a controller, e.g.:

before_action :set_tracking_context

def set_tracking_context
  SolidusTracking.set_context(user_ip: request.remote_ip)
end

We should support this to allow for integrating additional plugins, such as Segment.

Allow disabling certain events

It should be possible to disable the tracking of certain events, in case the user doesn't want to track them or wants to override them with their own.

Fix race conditions in job scheduling

We are currently scheduling the tracking of certain events before the corresponding ActiveRecord instances have been saved to the DB. This causes the background jobs to fail deserialization and to be retried.

It's not a huge problem, but it unnecessarily pollutes ActiveJob queues and error monitoring systems.

Contribute event hooks back to Solidus

This extension implements some custom events on top of the Solidus event bus for hooking into the right places in the order/user lifecycle. These events should live in solidus_core, and we should contribute them upstream ASAP so that other extensions/apps can also leverage them for other purposes, and we don't have to maintain them here.

Remove disable_builtin_emails

The disable_builtin_emails option was a mistake. ๐Ÿ˜… Event tracking services should be used for tracking events. Using them for sending emails is not reliable in the vast majority of cases, it's terribly complex in certain scenarios (think about resending an order receipt) and is something each app should code on its own.

Event ID generation

Using numeric IDs for Klaviyo event IDs is not handy, because they can repeat themselves when DBs are reset and cause the event not to be received by Klaviyo.

Instead, we should create an ActiveRecord module that automatically generates and persists a random event ID. This can be attached to the standard events and any additional events the user wishes to send to Klaviyo.

Make data structures tracker-agnostic

The biggest problem with this extension's architecture, in its current state, is that the format of the Event class, as well as the names of the events and the property names in the serializers, are all specific to Klaviyo, because it was originally extracted from the source code of solidus_klaviyo.

However, the entire idea behind the extension is that it can be used with multiple trackers, not just Klaviyo.

There are two potential solutions here:

  1. Simply provide the hooks for trackers to subscribe to and fire their own events. In this scenario, each tracker provides its own event and serializer classes. While this allows maximum flexibility, it also means that there's very little reusable logic across the different trackers. If we add support for an event in solidus_tracking, each tracker will have to implement it on its own. The same goes for serializer properties. It kind of defeats the purpose of having the extension in the first place.
  2. Make the serializer and event classes more tracker-agnostic by returning more idiomatic Ruby hashes, and allow each tracker to transform the data according to the format for that tracking service. While a bit more complicated to pull off, this feels like the right path.

order serializer fails on certain versions of solidus

https://github.com/solidusio-contrib/solidus_tracking/blob/master/lib/solidus_tracking/serializer/order.rb#L17

in Solidus 2.9.x, the line linked above fails with the following error message:

NoMethodError: undefined method 'code' for #<Spree::OrderPromotion:0x...>

the line:

'DiscountCode' => order.order_promotions.map { |op| op.code.value }.join(', '),

should be to:

'DiscountCode' => order.order_promotions.map { |op| op.promotion_code.value }.join(', '),

I'm not sure which versions of solidus use code vs promotion_code, but I'm guessing there should be something to handle pre and post refactor of the promotion codes.

Indicate which events are customer-originated

This extension tracks events at the lowest possible level, i.e. in model methods and state machine transitions.

This is good because it means that the event tracking won't be affected by user-facing customizations, but it may also cause some events to be tracked that are not of interest. For example, if an admin places an order from the backend, we may not want to track an "Order Completed" event, which is the current behavior.

Since we don't know whether these events should be tracked or not and we want to give users as much flexibility as possible, we should find an elegant way to clearly indicate whether an event originated from the customer or not. An example could be a global flag that indicates whether we're part of a request that was customer-initiated:

before_action :set_customer_originated

def set_customer_originated
  SolidusTracking.customer_originated = true
end

(This could also just be part of the global context, see #22.)

The user could then decide whether they want to enable/disable tracking of these events, either in a global configuration flag or on a per-event/per-plugin basis.

config.variant_url_builder bug

Defaults as:

# A proc that accepts a variant and returns the URL of that variant's PDP.
  config.variant_url_builder = proc do |variant|
    Spree::Core::Engine.routes.url_helpers.edit_password_url(
      variant.product,
      protocol: 'https',
      host: Spree::Store.default.url,
    )
  end

note: Spree::Core::Engine.routes.url_helpers.edit_password_url

Does not work if a checkout step is removed

Spent some time trying to figure out why this gem wasn't working for it. It turns out that if you remove some checkout steps the events stop firing.

      remove_checkout_step :address
      remove_checkout_step :delivery

^^ adding this will cause the events to be skipped.

Is there any suggestion on a different way I could pass over these checkout steps and keep the events occurring?

Make background job queue configurable

We should allow users to configure the name of the ActiveJob queue that will be used for scheduling event tracking jobs. This way, users can use a lower-priority queue for tracking.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.