I'm adding Mixpanel to my web application and I'm curious about the "process" around what happens when a user transitions from "anonymous" (not logged in/registered) to "identified" (when they register / create an account on the site).
If a user comes in and is new to the site, they get an anonymous UUID (according to the documentation). The documentation also says that Mixpanel can not translate between IDs at this time.
Does this mean Mixpanel is incapable of handling the transition of a non-registered user to a registered user, and keep track of their events from before they became a registered/identified user?
If so, does anyone have experience with working around this? How'd you go about it?
As of December 2012, you can now use the mixpanel.alias method call to alias two ids:
https://mixpanel.com/docs/integration-libraries/using-mixpanel-alias
From the above docs:
John comes to your website, example.com, for the first time. He is
assigned a randomly generated ID (perhaps 123123) by Mixpanel.
Everything he does is associated with that ID.
After clicking through a few pages, he successfully signs up. On the
signup confirmation page, you call mixpanel.alias("john#hotmail.com").
This doesn't actually change his ID - he is still being identified
using the random ID we originally assigned him.
What it does do is add the ID "john#hotmail.com" to a lookup table on
our end. Whenever we see data for "john#hotmail.com", we know to remap
it to 123123, his original ID.
So, you can start calling mixpanel.identify("john#hotmail.com") on all
your pages, and your events, funnels, and retention will all continue
to work perfectly.
There are ways to make this work. But what you are really asking for is a feature called distinct id aliasing, which would allow you to reference one distinct_id ID to another. Unfortunately, we don't offer that right now. This turns out to be a much harder issue than you'd expect due to the unique nature of the data-store we wrote for mixpanel.
In the meantime, I can give you a few strategies to get around this limitation:
When a user first comes to your website, set a distinct id for them which you generate internally. Once they register for an account, reference that distinct_id in your user detail table, and then continue to register subsequent events with that id. Each subsequent time a user auths, use the stored value as the distinct id. Hopefully when they return the cookie will still be around, and you will capture all the events without a hitch.
You could, also, let mixpanel give them an auto-issued distinct_id value, and then grab that at the time of registration by using mixpanel.get_property() then add that to your users table, and use that when you identify them in the future.
But what if they auth from one machine and then come on from another, or a different browser, or from a mobile device? Then the time in between when they hit your site and when they auth they'll be issued a new distinct_id by your site... and there is no way to alias! The solution here is a bit hackier. The only way to get that data is to log those events that were sent before the authentication (maybe server-side) and then send them via HTTP specification to the rest API with the correct distinct_id once the user auths. As long as you keep the correct time stamps, it will all appear correctly, chronologically within mixpanel. If the user never auths, then you can have the logged events time out and send them anyways.
Would either of these work for you?
When a user hits your site, identify them with a unique id and save it in a cookie if they don't already have one, then use the Mixpanel Identify API call to identify them. You can persist the unique id to your database in the user's record once they have registered, so you can re-set it in the case they clear their cookies.
If the user clears their cookies before registering, then you would be out of luck, but that's the nature of this beast and would be an issue anywhere.
Related
Background and Problem
I have a system that has core users augmented by some minor contributors who only need to be able to provide approvals for certain things. To support this, the system reacts to database changes and emails those approvers with a single button in the body of the email. This button is just a link to a unique url - something like https://myapp/response/12345-abcdefg-6789.
That "response" page is listed in the web config as not requiring a log in. Thus, the approver should only have to click on the link in the email, and the system should detect that and mark their response.
In all of our testing, this works great. All we're doing is marking the response via the page's code behind, and then displaying a message on the page that the response was received. On the surface, this seems like about as easy of a task as you can dream up.
However, we're getting false positives in production. The approvers are telling us that things are being marked as approved when they never clicked the link. I assume this has something to do with their browsers checking the links for safety or something - and by performing that safety check, it's triggering the system to record the response. Unfortunately, i haven't been able to reproduce this - even when we have some of the approvers on the phone while we try it.
The question is - what is the best strategy to avoid a false positive with buttons in an email?
Lots of companies do this kind of thing - i'm looking right now at an invitation from a friend via evite. It has Yes, Maybe, and No which appear to have the same kind of setup i described above.
Is there something i should be doing with redirects after x seconds? Is there some other javascript i should be deploying on the page? Is there some other potential cause for this? The IIS logs seem to indicate that the "fake clicks" are coming from the target users computers. Which is a bit of a relief, since it's hard to imagine how some other external machine could end up at a GUID based url that is not represented by a physical file that could be crawled over in some way.
I would like to avoid having another button for the user to click, where they would click "Approve" in the email, and then when they get to the page they have click the same thing again.
Thanks!
From my understanding there are two ways to go about it. But both methods assume the current "response" page is just an intermediary.
Add another button on the page (#
https://myapp/response/12345-abcdefg-6789 for instance) that actually
submits the response (or redirects to the actual response page). It would add an extra step for your approvers but
it should work. (You can even add a captcha there if paranoid)
Once the page is loaded, redirect to the actual response page via
javascript. The idea being if the link is automatically opened by
some kind of bot it's unlikely it runs the script.
I have some code that does a jQuery post to my API, does some magic, and then uses Pusher to push data back to the browser.
Currently I am using Sinatra, pulling the session id, and putting it in a hidden value on the html. And then when my JS function is triggered by my button push, it pulls this value, and passes it to the API. Then my code just remembers and sets this as the channel ID and pushes data back.
It works quite well...except if I have more than one browser open, both have the same session id. So triggering my API on one pushes data to all open instances I have. My question is: is there a "best practice" way to do this and differentiate between tabs?
I could of course just generate a random number with JS and use that as my value, but for some reason it just seems wrong. Thoughts?
SETUP:
Having a few different information sites/domains about my products and one single site/domain shop-site where you the purchase, checkout and so on happens, I'm having troubles to find a proper solution for a comprehensive tracking of all the pages including the conversion tracking.
IDEAL:
What I want is to get reports seperated for each site (shop-site as well as information-sites), but add some conversion tracking. Ideal would be to be able to track a conversion when the user gets to the checkout process, so that I can see it in the statistics of the shop-site as well as on the site that referred to this sale/conversion and maybe even a funnel visualisation for the whole action.
WHAT I ALREADY GOT:
I already set up statistics for each site/domain. I do have set events for a referal to the shop-site as well as an event when the user checks out.
WHAT I TRIED:
I set up cross domain tracking for one of my information-sites and the shop-site, so now the events show up in that single property.
Unfortunately thats not the statistic I intend to get, as the whole data got consolidated from those 2 properties. Also it made the tracking goal/conversion only accessible for that single property, while I can't distinguish between a conversion made originally from this site or one of the others.
Is it possible to achieve what I actually intend to do or what's the proper way to track such a setup??
You can either use an additional tracker (so you have one UA id that goes in your "normal" domain, one that goes in your shpooing site and one that is placed on both sites) - you'd still have both pages tracked in separate properties, but you'd have one rollup property that tracks all your sites. This might however unwanted complexity if you use event tracking etc (since you'd have to see to it that events are always pushed to the correct tracker).
An easier solutions is via views/profiles - use the same UA id for both sites; create views based on domain name (filter in the admin section) to track each site separately; for the common data view that display data from both sites create a filter that includes the hostname in the reports so you can tell both sites apart in the report.
I've looked at a couple different analytics programs (like Google Analytics) that will tell me what URL my users have entered my site from, and which URL they are going to when they exit.
It certainly must be possible to gather this data somehow, I just can't find any code examples of how to do it. I would imagine that it involves the javascript function onBeforeLoad, I just don't know how to get the URL from that point on. This is a pretty important feature, as it will help me to tailer my website more towards my users specific needs.
I appreciate the help,
Sorry, I think I was unclear originally.
One of my other sites uses a service called StatCounter, and they have a section called "Came From". This shows where users were at directly before they visited your page. So, for instance, if someone google'd "Inside Out Ministry", and found the link to my site www.insideoutministry.com, my stats page would show that the user Came From www.google.com .
What would be the code to do this?
A simple approach would be to have a db with ip, time, lasturl and firsturl fields. Every time someone calls a page, it get's checked if his IP is already in the db. if not, a new entry gets written with firsturl as the actual url and i with his ip. Every time now he loads a new page on your site, the lastpage field gets updated. I don't know how exactly to determine that he's left the page, e.G. if he hasn't accessed any page on your sithe within 10min.
To track the first/last page your users visit, you just track all pages the user visits, and the one with the earliest timestamp is the first, and the one with the latest timestamp is the last.
In my web app, when a user logs in, I add his Id to a vector of valid Ids in the servlet, when he logs out, I remove his Id from the vector, so I can see how many current users are active, if a user forgets to log out, my servelt generated html has :
<meta http-equiv="Refresh" content="30; url=My_Servlet?User_Action=logout&User_Id=1111">
in the tag to automatically log him out.
But I've noticed many users are there for ever, never logged out. I found out why, by closing their browsers, they never manually or automatically logged out, so their user Ids will never be removed from the valid user Ids vector.
So, my question is : how do I detect users closing their browsers, so my servlet can remove their Ids from the vector ?
I see some light at the end of the tunnel, but there is still a problem, my program has something like this :
Active User List :
User_1 : Machine_1 [ IP_1 address ]
User_2 : Machine_2 [ IP_2 address ]
User_3 : Machine_3 [ IP_3 address ]
...
How do I know, from the session listener, which user's session has ended and therefore remove him from my list?
I was hoping when the session ends, the HttpServlet's destroy() method would be called and I can remove the user Id in there, but it never gets called when user closes his browser, why? And is there any other method in the HttpServlet that gets called when a session closes?
There is no way to know on the server-side (unless you are using some JavaScript to send a message to the server) that the browser has closed. How could there be? Think of how HTTP works - everything is request and response.
However, the application server will track when Sessions are active and will even tell you when a Session has been destroyed (such as due to time-out). Take a look at this page to see how to configure a HttpSessionListener to receive these events. Then you can simply keep track of the number of active sessions.
The number of active sessions will lag behind the actual number of current users, since some period of (configurable) time has to elapse before a session is timed out; however, this should be somewhat close (you can lower the session-timeout to increase the accuracy) and it is a lot cleaner and easier than 1) tracking Sessions yourself or 2) sending some asynchronous JavaScript to the server when a browser is closed (which is not guaranteed to be sent).
I suggest you remove the ID when the Servlet engine destroys the session. Register a HttpSessionListener that removes the user's ID when sessionDestroyed() is called.
Diodeus's idea will only help you detect that the session is over more immediately.
in JavaScript you can use the onbeforeclose event to pass a call back to the server when the user closes the browser.
I typically use a synchronous Ajax call to do this.
I had to do that recently, and after some searches, I found some solutions on the Net... all of them non working universally!
onbeforeclose and onclose events are used for this task. But there are two catches: they are fired when the user reload the page or even just change the current page. There are tricks to see if the event is actually a window/page/tab closing (looking at some Dom properties going haywire on closing event), but:
They are browser dependent
The tricks are undocumented, thus brittle
And actually they vary along the browser version/update...
And worst of all, these events are now ignored by most modern browsers, because they have been abused by rogue ads popping out windows when browser was closing. They are not fired in Safari, Opera, IE7, etc.
As pointed out, most Web applications with login destroy the user session after a while, eg. half an hour. I was asked to logout on browser closing to free faster a precious resource: licenses. Because users often forget to log out...
The solution I gave was to ping with an Ajax request (sending the user ID) the server on regular intervals (say 1 minute). If the server receives no ping for, say, 3 minutes, it disconnect the user.
There is no foolproof way to do what you're trying to do, but both sblundy and Diodeus have plans that will cover most circumstances. There is nothing you can do about someone who turns off Javascript in their browser, or their internet connection goes down, or their power goes out. You should just cull sessions after a certain period of inactivity (which I think is what sblundy's suggestion of listening for session destruction will do).