add options to filter events and provide extra data if necessary
This commit is contained in:
parent
4182cf566d
commit
abff71d312
|
@ -9,7 +9,8 @@
|
|||
[status-im.utils.http :as http]
|
||||
[status-im.utils.platform :as platform]
|
||||
[status-im.utils.types :as types]
|
||||
[taoensso.timbre :as log]))
|
||||
[taoensso.timbre :as log]
|
||||
[status-im.utils.mixpanel-events :as mixpanel-events]))
|
||||
|
||||
(def base-url "http://api.mixpanel.com/")
|
||||
(def base-track-url (str base-url "track/"))
|
||||
|
@ -61,8 +62,8 @@
|
|||
(recur (conj accumulator event))
|
||||
accumulator))]
|
||||
(async/go
|
||||
(doseq [batch (partition-all max-batch-size events)]
|
||||
(async/<! (callback batch)))))))
|
||||
(doseq [batch (partition-all max-batch-size events)]
|
||||
(async/<! (callback batch)))))))
|
||||
|
||||
(defn track
|
||||
"Track or accumulate an event"
|
||||
|
@ -75,20 +76,52 @@
|
|||
(when-not offline?
|
||||
(async/go (async/<! (drain-events-queue!))))))
|
||||
|
||||
(def event-tag "events")
|
||||
|
||||
;; Mixpanel events definition
|
||||
(def events (reader/read-string (slurp/slurp "./src/status_im/utils/mixpanel_events.edn")))
|
||||
(def event-by-trigger (reduce-kv #(assoc %1 (:trigger %3) %3) {} events))
|
||||
(defn event->triggers
|
||||
"Transform definitions vector into map which will be used for matching later
|
||||
|
||||
(defn matches? [event trigger]
|
||||
(cond (= 1 (count trigger))
|
||||
(= (first event) (first trigger))
|
||||
(= 2 (count trigger))
|
||||
(and
|
||||
(= (first event) (first trigger))
|
||||
(= (second event) (second trigger)))
|
||||
:else
|
||||
(= event trigger)))
|
||||
[{:trigger [:en1]}
|
||||
{:trigger [:en1 :p1]}
|
||||
{:trigger [:en2 :p1]}
|
||||
{:trigger [:en3 :p1 :p2 :p3]}]
|
||||
|
||||
(defn matching-events [event definitions]
|
||||
(reduce-kv #(if (matches? event %2) (conj %1 %3) %1) [] definitions))
|
||||
will be transformed into
|
||||
|
||||
{:en1 {events ({:trigger [:en1]})
|
||||
:p1 {events ({:trigger [:en1 :p1]})}}
|
||||
:en2 {:p1 {events ({:trigger [:en2 :p1]})}}
|
||||
:en3 {:p1 {:p2 {:p3 {events ({:trigger [:en3 :p1 :p2 :p3]})}}}}}"
|
||||
[events]
|
||||
(reduce (fn [m {:keys [trigger] :as event}]
|
||||
(update-in m (conj trigger event-tag) conj event))
|
||||
{}
|
||||
events))
|
||||
|
||||
(def event-by-trigger
|
||||
(event->triggers mixpanel-events/events))
|
||||
|
||||
(defn matching-events [[event-name first-arg :as event] triggers]
|
||||
(let [cnt (count event)
|
||||
triggers (cond->
|
||||
;; first we get all events which are triggered by event name
|
||||
;; (the case when :trigger contains only one element)
|
||||
;; {:trigger [:only-event-name-here]}
|
||||
(get-in triggers [event-name event-tag])
|
||||
|
||||
;; when event contains two or more elements we are trying
|
||||
;; to match by first two elements of :trigger
|
||||
;; {:trigger [:event-name :one-parameter]}
|
||||
(>= cnt 2)
|
||||
(concat (get-in triggers [event-name first-arg event-tag]))
|
||||
|
||||
;; also if event contains more than one parameter (more than
|
||||
;; two elements) we are trying to match it with equal :trigger
|
||||
;; {:trigger [:e-name :p1 :p2 :p3]}
|
||||
;; will match only with [:e-name :p1 :p2 :p3] event
|
||||
(> cnt 2)
|
||||
(concat (get-in triggers (conj event event-tag))))]
|
||||
(filter (fn [{:keys [filter-fn]}]
|
||||
(or (not filter-fn) (filter-fn {:event event})))
|
||||
triggers)))
|
||||
|
|
|
@ -0,0 +1,195 @@
|
|||
(ns status-im.utils.mixpanel-events)
|
||||
;; This file is supposed to be edited by Chad.
|
||||
;; Chad loves mixpanel. When Chad was a child he dreamed of being a mixpanel tamer.
|
||||
|
||||
;; To add a new event definition, add a new map to this vector
|
||||
;; :label is a free string that is displayed in mixpanel
|
||||
;; :trigger is the re-frame style event that when matched will generate the emission of a mixpanel event
|
||||
;; :properties is a map of key / value pair that will be added to the mixpanel event to provide more context
|
||||
(def events
|
||||
[;; Account creation
|
||||
|
||||
{:label "Account created"
|
||||
:trigger [:account-finalized]}
|
||||
{:label "Account restored"
|
||||
:trigger [:account-recovered]}
|
||||
|
||||
;; Account lifecycle
|
||||
|
||||
{:label "Login"
|
||||
:trigger [:initialize-account]}
|
||||
|
||||
{:label "Logout"
|
||||
:trigger [:navigate-to :accounts]}
|
||||
|
||||
; Push notification settings
|
||||
|
||||
{:label "Granted push notifications"
|
||||
:trigger [:request-notifications-granted]}
|
||||
|
||||
{:label "Denied push notifications"
|
||||
:trigger [:request-notifications-denied]}
|
||||
|
||||
;; Tab navigation
|
||||
|
||||
{:label "Tap"
|
||||
:trigger [:navigate-to-clean :home]
|
||||
:properties {:target :home}}
|
||||
{:label "Tap"
|
||||
:trigger [:navigate-to-tab :home]
|
||||
:properties {:target :home}}
|
||||
{:label "Tap"
|
||||
:trigger [:navigate-to-tab :my-profile]
|
||||
:properties {:target :my-profile}}
|
||||
{:label "Tap"
|
||||
:trigger [:navigate-to-clean :wallet]
|
||||
:properties {:target :wallet}}
|
||||
{:label "Tap"
|
||||
:trigger [:navigate-to-tab :wallet]
|
||||
:properties {:target :wallet}}
|
||||
|
||||
;; New
|
||||
{:label "Tap"
|
||||
:trigger [:navigate-to-tab :new]
|
||||
:properties {:target :new}}
|
||||
{:label "Tap"
|
||||
:trigger [:navigate-to :new-chat]
|
||||
:properties {:target :new-chat}}
|
||||
{:label "Tap"
|
||||
:trigger [:scan-qr-code]
|
||||
:properties {:target :new-chat-qr-code}}
|
||||
{:label "Tap"
|
||||
:trigger [:show-profile]
|
||||
:properties {:target :show-profile}}
|
||||
{:label "Tap"
|
||||
:trigger [:open-contact-toggle-list :chat-group]
|
||||
:properties {:target :new-group-chat}}
|
||||
{:label "Tap"
|
||||
:trigger [:navigate-to :new-public-chat]
|
||||
:properties {:target :new-public-chat}}
|
||||
{:label "Tap"
|
||||
:trigger [:navigate-to :open-dapp]
|
||||
:properties {:target :open-dapp}}
|
||||
{:label "Tap"
|
||||
:trigger [:navigate-to :dapp-description]
|
||||
:properties {:target :open-dapp-description}}
|
||||
{:label "Tap"
|
||||
:trigger [:open-dapp-in-browser]
|
||||
:properties {:target :open-selected-dapp}}
|
||||
{:label "Tap"
|
||||
:trigger [:navigate-to :new-group]
|
||||
:properties {:target :start-group-chat-next}}
|
||||
{:label "Tap"
|
||||
:trigger [:create-new-public-chat]
|
||||
:properties {:target :create-public-chat}}
|
||||
{:label "Tap"
|
||||
:trigger [:navigate-to :new-public-chat]
|
||||
:properties {:target :join-public-chat}}
|
||||
|
||||
;; Chat
|
||||
|
||||
{:label "Tap"
|
||||
:trigger [:navigate-to-chat]
|
||||
:properties {:target :open-existing-chat}}
|
||||
{:label "Tap"
|
||||
:trigger [:navigate-to :browser]
|
||||
:properties {:target :open-existing-dapp}}
|
||||
{:label "Tap"
|
||||
:trigger [:start-chat]
|
||||
:properties {:target :start-chat}}
|
||||
{:label "Tap"
|
||||
:trigger [:send-current-message]
|
||||
:properties {:target :send-current-message}}
|
||||
|
||||
;; Wallet
|
||||
{:label "Tap"
|
||||
:trigger [:navigate-to :wallet-send-transaction]
|
||||
:properties {:target :wallet-send-transaction}}
|
||||
{:label "Tap"
|
||||
:trigger [:navigate-to :wallet-request-transaction]
|
||||
:properties {:target :wallet-request-transaction}}
|
||||
{:label "Tap"
|
||||
:trigger [:navigate-to :transactions-history]
|
||||
:properties {:target :transactions-history}}
|
||||
{:label "Tap"
|
||||
:trigger [:navigate-to :recent-recipients]
|
||||
:properties {:target :select-recipient
|
||||
:type :recent-recipients}}
|
||||
{:label "Tap"
|
||||
:trigger [:navigate-to :recipient-qr-code]
|
||||
:properties {:target :select-recipient
|
||||
:type :recipient-qr-code}}
|
||||
{:label "Tap"
|
||||
:trigger [:navigate-to :contact-code]
|
||||
:properties {:target :select-recipient
|
||||
:type :contact-code}}
|
||||
{:label "Tap"
|
||||
:trigger [:navigate-to :wallet-send-assets]
|
||||
:properties {:target :wallet-send-assets}}
|
||||
{:label "Tap"
|
||||
:trigger [:wallet.send/toggle-advanced]
|
||||
:properties {:target :wallet-advanced}}
|
||||
{:label "Tap"
|
||||
:trigger [:wallet.send/set-signing?]
|
||||
:properties {:target :wallet-open-sign-transaction}}
|
||||
{:label "Tap"
|
||||
:trigger [:wallet/sign-transaction]
|
||||
:properties {:target :wallet-sign-transaction}}
|
||||
{:label "Tap"
|
||||
:trigger [:navigate-to-clean :wallet]
|
||||
:properties {:target :wallet-got-it}}
|
||||
{:label "Tap"
|
||||
:trigger [:navigate-to :wallet-transaction-sent]
|
||||
:properties {:target :wallet-transaction-sent}}
|
||||
|
||||
|
||||
;;Profile
|
||||
{:label "Tap"
|
||||
:trigger [:my-profile/start-editing-profile]
|
||||
:properties {:target :edit-profile}}
|
||||
{:label "Tap"
|
||||
:trigger [:my-profile/update-picture]
|
||||
:properties {:target :edit-image
|
||||
:type :gallery}}
|
||||
{:label "Tap"
|
||||
:trigger [:navigate-to :profile-photo-capture]
|
||||
:properties {:target :edit-image
|
||||
:type :capture}}
|
||||
{:label "Tap"
|
||||
:trigger [:navigate-to :profile-qr-viewer]
|
||||
:properties {:target :share-contact-code}}
|
||||
{:label "Tap"
|
||||
:trigger [:set :my-profile/advanced? true]
|
||||
:properties {:target :profile-advanced
|
||||
:type :open}}
|
||||
{:label "Tap"
|
||||
:trigger [:set :my-profile/advanced? false]
|
||||
:properties {:target :profile-advanced
|
||||
:type :closed}}
|
||||
{:label "Tap"
|
||||
:trigger [:switch-dev-mode true]
|
||||
:properties {:target :profile-dev-mode
|
||||
:type :on}}
|
||||
{:label "Tap"
|
||||
:trigger [:switch-dev-mode false]
|
||||
:properties {:target :profile-dev-mode
|
||||
:type :off}}
|
||||
{:label "Tap"
|
||||
:trigger [:navigate-to :backup-seed]
|
||||
:properties {:target :backup-your-seed-phrase}}
|
||||
{:label "Tap"
|
||||
:trigger [:set-in [:my-profile/seed :step] :12-words]
|
||||
:properties {:target :seed-phrase
|
||||
:type :welcome-ok}}
|
||||
{:label "Tap"
|
||||
:trigger [:my-profile/enter-two-random-words]
|
||||
:properties {:target :seed-phrase
|
||||
:type :step1-next}}
|
||||
{:label "Tap"
|
||||
:trigger [:my-profile/set-step :second-word]
|
||||
:properties {:target :seed-phrase
|
||||
:type :step2-next}}
|
||||
{:label "Tap"
|
||||
:trigger [:my-profile/finish]
|
||||
:properties {:target :seed-phrase
|
||||
:type :step3-done}}])
|
|
@ -1,194 +0,0 @@
|
|||
;; This file is supposed to be edited by Chad.
|
||||
;; Chad loves mixpanel. When Chad was a child he dreamed of being a mixpanel tamer.
|
||||
|
||||
;; To add a new event definition, add a new map to this vector
|
||||
;; :label is a free string that is displayed in mixpanel
|
||||
;; :trigger is the re-frame style event that when matched will generate the emission of a mixpanel event
|
||||
;; :properties is a map of key / value pair that will be added to the mixpanel event to provide more context
|
||||
|
||||
[;; Account creation
|
||||
|
||||
{:label "Account created"
|
||||
:trigger [:account-finalized]}
|
||||
{:label "Account restored"
|
||||
:trigger [:account-recovered]}
|
||||
|
||||
;; Account lifecycle
|
||||
|
||||
{:label "Login"
|
||||
:trigger [:initialize-account]}
|
||||
|
||||
{:label "Logout"
|
||||
:trigger [:navigate-to :accounts]}
|
||||
|
||||
; Push notification settings
|
||||
|
||||
{:label "Granted push notifications"
|
||||
:trigger [:request-notifications-granted]}
|
||||
|
||||
{:label "Denied push notifications"
|
||||
:trigger [:request-notifications-denied]}
|
||||
|
||||
;; Tab navigation
|
||||
|
||||
{:label "Tap"
|
||||
:trigger [:navigate-to-clean :home]
|
||||
:properties {:target :home}}
|
||||
{:label "Tap"
|
||||
:trigger [:navigate-to-tab :home]
|
||||
:properties {:target :home}}
|
||||
{:label "Tap"
|
||||
:trigger [:navigate-to-tab :my-profile]
|
||||
:properties {:target :my-profile}}
|
||||
{:label "Tap"
|
||||
:trigger [:navigate-to-clean :wallet]
|
||||
:properties {:target :wallet}}
|
||||
{:label "Tap"
|
||||
:trigger [:navigate-to-tab :wallet]
|
||||
:properties {:target :wallet}}
|
||||
|
||||
;; New
|
||||
{:label "Tap"
|
||||
:trigger [:navigate-to-tab :new]
|
||||
:properties {:target :new}}
|
||||
{:label "Tap"
|
||||
:trigger [:navigate-to :new-chat]
|
||||
:properties {:target :new-chat}}
|
||||
{:label "Tap"
|
||||
:trigger [:scan-qr-code]
|
||||
:properties {:target :new-chat-qr-code}}
|
||||
{:label "Tap"
|
||||
:trigger [:show-profile]
|
||||
:properties {:target :show-profile}}
|
||||
{:label "Tap"
|
||||
:trigger [:open-contact-toggle-list :chat-group]
|
||||
:properties {:target :new-group-chat}}
|
||||
{:label "Tap"
|
||||
:trigger [:navigate-to :new-public-chat]
|
||||
:properties {:target :new-public-chat}}
|
||||
{:label "Tap"
|
||||
:trigger [:navigate-to :open-dapp]
|
||||
:properties {:target :open-dapp}}
|
||||
{:label "Tap"
|
||||
:trigger [:navigate-to :dapp-description]
|
||||
:properties {:target :open-dapp-description}}
|
||||
{:label "Tap"
|
||||
:trigger [:open-dapp-in-browser]
|
||||
:properties {:target :open-selected-dapp}}
|
||||
{:label "Tap"
|
||||
:trigger [:navigate-to :new-group]
|
||||
:properties {:target :start-group-chat-next}}
|
||||
{:label "Tap"
|
||||
:trigger [:create-new-public-chat]
|
||||
:properties {:target :create-public-chat}}
|
||||
{:label "Tap"
|
||||
:trigger [:navigate-to :new-public-chat]
|
||||
:properties {:target :join-public-chat}}
|
||||
|
||||
;; Chat
|
||||
|
||||
{:label "Tap"
|
||||
:trigger [:navigate-to-chat]
|
||||
:properties {:target :open-existing-chat}}
|
||||
{:label "Tap"
|
||||
:trigger [:navigate-to :browser]
|
||||
:properties {:target :open-existing-dapp}}
|
||||
{:label "Tap"
|
||||
:trigger [:start-chat]
|
||||
:properties {:target :start-chat}}
|
||||
{:label "Tap"
|
||||
:trigger [:send-current-message]
|
||||
:properties {:target :send-current-message}}
|
||||
|
||||
;; Wallet
|
||||
{:label "Tap"
|
||||
:trigger [:navigate-to :wallet-send-transaction]
|
||||
:properties {:target :wallet-send-transaction}}
|
||||
{:label "Tap"
|
||||
:trigger [:navigate-to :wallet-request-transaction]
|
||||
:properties {:target :wallet-request-transaction}}
|
||||
{:label "Tap"
|
||||
:trigger [:navigate-to :transactions-history]
|
||||
:properties {:target :transactions-history}}
|
||||
{:label "Tap"
|
||||
:trigger [:navigate-to :recent-recipients]
|
||||
:properties {:target :select-recipient
|
||||
:type :recent-recipients}}
|
||||
{:label "Tap"
|
||||
:trigger [:navigate-to :recipient-qr-code]
|
||||
:properties {:target :select-recipient
|
||||
:type :recipient-qr-code}}
|
||||
{:label "Tap"
|
||||
:trigger [:navigate-to :contact-code]
|
||||
:properties {:target :select-recipient
|
||||
:type :contact-code}}
|
||||
{:label "Tap"
|
||||
:trigger [:navigate-to :wallet-send-assets]
|
||||
:properties {:target :wallet-send-assets}}
|
||||
{:label "Tap"
|
||||
:trigger [:wallet.send/toggle-advanced]
|
||||
:properties {:target :wallet-advanced}}
|
||||
{:label "Tap"
|
||||
:trigger [:wallet.send/set-signing?]
|
||||
:properties {:target :wallet-open-sign-transaction}}
|
||||
{:label "Tap"
|
||||
:trigger [:wallet/sign-transaction]
|
||||
:properties {:target :wallet-sign-transaction}}
|
||||
{:label "Tap"
|
||||
:trigger [:navigate-to-clean :wallet]
|
||||
:properties {:target :wallet-got-it}}
|
||||
{:label "Tap"
|
||||
:trigger [:navigate-to :wallet-transaction-sent]
|
||||
:properties {:target :wallet-transaction-sent}}
|
||||
|
||||
|
||||
;;Profile
|
||||
{:label "Tap"
|
||||
:trigger [:my-profile/start-editing-profile]
|
||||
:properties {:target :edit-profile}}
|
||||
{:label "Tap"
|
||||
:trigger [:my-profile/update-picture]
|
||||
:properties {:target :edit-image
|
||||
:type :gallery}}
|
||||
{:label "Tap"
|
||||
:trigger [:navigate-to :profile-photo-capture]
|
||||
:properties {:target :edit-image
|
||||
:type :capture}}
|
||||
{:label "Tap"
|
||||
:trigger [:navigate-to :profile-qr-viewer]
|
||||
:properties {:target :share-contact-code}}
|
||||
{:label "Tap"
|
||||
:trigger [:set :my-profile/advanced? true]
|
||||
:properties {:target :profile-advanced
|
||||
:type :open}}
|
||||
{:label "Tap"
|
||||
:trigger [:set :my-profile/advanced? false]
|
||||
:properties {:target :profile-advanced
|
||||
:type :closed}}
|
||||
{:label "Tap"
|
||||
:trigger [:switch-dev-mode true]
|
||||
:properties {:target :profile-dev-mode
|
||||
:type :on}}
|
||||
{:label "Tap"
|
||||
:trigger [:switch-dev-mode false]
|
||||
:properties {:target :profile-dev-mode
|
||||
:type :off}}
|
||||
{:label "Tap"
|
||||
:trigger [:navigate-to :backup-seed]
|
||||
:properties {:target :backup-your-seed-phrase}}
|
||||
{:label "Tap"
|
||||
:trigger [:set-in [:my-profile/seed :step] :12-words]
|
||||
:properties {:target :seed-phrase
|
||||
:type :welcome-ok}}
|
||||
{:label "Tap"
|
||||
:trigger [:my-profile/enter-two-random-words]
|
||||
:properties {:target :seed-phrase
|
||||
:type :step1-next}}
|
||||
{:label "Tap"
|
||||
:trigger [:my-profile/set-step :second-word]
|
||||
:properties {:target :seed-phrase
|
||||
:type :step2-next}}
|
||||
{:label "Tap"
|
||||
:trigger [:my-profile/finish]
|
||||
:properties {:target :seed-phrase
|
||||
:type :step3-done}}]
|
|
@ -3,29 +3,32 @@
|
|||
[status-im.utils.mixpanel :as mixpanel]
|
||||
[cljs.core.async :as async]))
|
||||
|
||||
(deftest events
|
||||
(is (not (nil? mixpanel/events))))
|
||||
(def definitions
|
||||
(mixpanel/event->triggers
|
||||
[{:trigger [:key]}
|
||||
{:trigger [:key :subkey]}
|
||||
{:trigger [:key2]
|
||||
:filter-fn (fn [{[_ first-parameter] :event}]
|
||||
(true? first-parameter))}
|
||||
{:trigger [:key3 :p1 :p2 :p3]}]))
|
||||
|
||||
(deftest matches?
|
||||
(is (true? (mixpanel/matches? [:key] [:key])))
|
||||
(is (false? (mixpanel/matches? [:key1] [:key2])))
|
||||
(is (true? (mixpanel/matches? [:key :subkey] [:key])))
|
||||
(is (false? (mixpanel/matches? [:key] [:key :subkey]))))
|
||||
|
||||
(def definitions {[:key] {:trigger [:key]} [:key :subkey] {:trigger [:key :subkey]}})
|
||||
|
||||
(deftest matching-event
|
||||
(is (empty? (mixpanel/matching-events [:non-existing] definitions)))
|
||||
(is (= 1 (count (mixpanel/matching-events [:key] definitions))))
|
||||
(is (= 2 (count (mixpanel/matching-events [:key :subkey] definitions))))
|
||||
(is (= 1 (count (mixpanel/matching-events [:key2 true] definitions))))
|
||||
(is (= 1 (count (mixpanel/matching-events [:key3 :p1 :p2 :p3] definitions))))
|
||||
(is (empty? (mixpanel/matching-events [:key3 :p1 :p2 :p4] definitions)))
|
||||
(is (empty? (mixpanel/matching-events [:key2 false] definitions)))
|
||||
(is (empty? (mixpanel/matching-events [:key1 :another-subkey] definitions))))
|
||||
|
||||
(deftest drain-events-queue!-test
|
||||
(async
|
||||
done
|
||||
(let [queue (async/chan (async/sliding-buffer 2000))
|
||||
results (atom [])]
|
||||
(async/go
|
||||
(let [queue (async/chan (async/sliding-buffer 2000))
|
||||
results (atom [])]
|
||||
(async/go
|
||||
(async/<! (async/onto-chan queue (range 123) false))
|
||||
(async/<!
|
||||
(mixpanel/drain-events-queue!
|
||||
|
|
Loading…
Reference in New Issue