Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I use mixpanel API?

I'm not able to connect to mixpanel.

I have tried with a correct api_key and api_secret, like this:

<html>
<head>
    <script type="text/javascript" src="http://code.jquery.com/jquery-1.8.2.min.js" />
    </script>
    <script type="text/javascript" src="faulty-labs-md5.js" />
    </script>
</head>
<body>
    <script type="text/javascript">
$(document).ready(function() {
    $("#btnTest").click(function() {

        var api_key = 'BigSecret';
        var api_secret = 'BigSecret2';
        var expire = new Date('2012', '12', '24').getTime() / 1000 + 3600;
        var from_date = $("#date1").val();
        var to_date = $("#date2").val();
        var sig = faultylabs.MD5("api_key=" + api_key + "expire=" + expire + "from_date=" + from_date + "to_date=" + to_date + api_secret);
        //var path = 'https://data.mixpanel.com/api/2.0/export?api_key=' + api_key + "&expire=" + expire + "&from_date=" + from_date + "&to_date=" + to_date;
        var path = 'https://data.mixpanel.com/api/2.0/export?api_key=' + api_key + "&expire=" + expire + "&from_date=" + from_date;
        path = path + "&sig=" + sig.toLowerCase();
        $.jsonp({
            type: 'GET',
            url: path,
            async: false,
            callback: to_date,  // sneaky bogus shenanigans
            callbackParameter: 'to_date', // more of same
            contentType: "application/json",
            dataType: 'jsonp',
            cache: true,
            success: function(json) {
                alert(json);
            },
            error: function(e) {
                console.log(e.message);
            }
        });
    });
});
    </script>
    <input type="text" id="date1" value="2012-10-29" />
    <input type="text" id="date2" value="2012-10-29" />
    <button onclick="return false" id="btnTest">Test</button>
</body>
</html>

As you can see, I try to use this API with JSONP, but I'm lost in the woods. Is there anybody who has knowledge about mixpanel and JSONP?

Thank you in advance.

EDIT: I've added the new version of the page.

like image 880
Lajos Arpad Avatar asked Oct 30 '12 13:10

Lajos Arpad


2 Answers

Here a few things I realized. I was able to get it working with all other end points I tried but "export". I'm tempted to believe it's something peculiar to just the raw data export endpoint. Reading through their docs, the raw data end point is the only end point that isn't part of the main API and therefore requires a different base URI "https://data.mixpanel.com/api/2.0". All other endpoints "events", "segmentation" etc. use "https://mixpanel.com/api/2.0". I've put down the steps I went through below. I'm using jquery.MD5 lib for the md5 implementation

$(function() {
  $("#test_request").click(function() {
    var api_secret, arg_keys, args, args_concat, end_point, key, 
    mixpanel_base_uri, sig, sorted_keys, _i, _len;
    args = {};
    end_point = "export";
    api_secret = "BIG_SECRET2";
    args.api_key = "BIG_SECRET";

    args.from_date = $("input[name=from_date]").val();
    args.to_date = $("input[name=to_date]").val();
    //using Math.floor to round to integer as api expects integer
    args.expire = Math.floor(new Date().getTime() / 1000 + 3600); 
    arg_keys = Object.keys(args);
    sorted_keys = arg_keys.sort();
    args_concat = "";

    //concatenating key value pairs
    for (_i = 0, _len = sorted_keys.length; _i < _len; _i++) {
      key = sorted_keys[_i];
      args_concat = "" + args_concat + key + "=" + args[key];
    }
    sig = $.md5(args_concat + api_secret);

    //merge signature property with args hash
    $.extend(args, {
      sig: sig
    });

    //export endpoint isn't part of the main api and data.mixpanel instead of just mixpanel.com
    DATA_URI = "https://data.mixpanel.com/api/2.0"
    DEFAULT_URI = "https://mixpanel.com/api/2.0"
    BASE_URI = end_point === "export" ? DATA_URI : DEFAULT_URI;
    $.getJSON("" + BASE_URI + "/" + end_point + "?callback=?", args, function(result) {
      alert("result is" + JSON.stringify(result));

    });
  });
});

I've also put up a working solution for all other endpoints. Here is the link http://jsfiddle.net/Dantheta/CmKQN/

Hope you find it useful.

like image 191
dantheta Avatar answered Oct 21 '22 11:10

dantheta


After squinting at this PHP, I'm pretty sure you need to do an md5 hash of your api signature.

Import an md5 library, like this one

<script type="text/javascript" src="jquery.md5.min.js"></script>

And then do something like this:

var sig = "api_key=" + api_key + "expire=" + expire + "from_date=" + from_date + "to_date=" + to_date + "bigsecret2";
sig = $.md5(sig);

I'm trying to accomplish the same thing you are, but unfortunately I still haven't got it working.

Edit - This is rough. The API will fail if ANY parameter is not hashed with the sig. It will also fail if any parameter is included which is not part of the API. JsonP adds a "callback" and a "_" timestamp parameter so it can do what it does, and this breaks the call. You can hack around this by excluding the timestamp with cache: true and using a special jsonp plugin which allows you to rename the callback parameter. Here I have renamed it to to_date and named the callback function "2012-10-29". It's crazy, and it still doesn't work because the reply is not valid json. It's a series of newline-delimited json objects which can not be evaluated, and I'm still stuck on that part. Here's what I've got so far:

<script type="text/javascript" src="jquery-1.8.2.js"></script>
<script type="text/javascript" src="jquery.md5.min.js"></script>
<script type="text/javascript" src="jquery.jsonp-2.4.0.js"></script>

<script>
    var events = document.getElementById("events");

    var api_key = "secret";
    var expire = "1351811239";
    var from_date = "2012-10-29";
    var to_date = "2012-10-29";

    var sig = "api_key=" + api_key + "expire=" + expire + "from_date=" + from_date + "to_date=" + to_date + "secret2";
    sig = $.md5(sig);


    var path = 'https://data.mixpanel.com/api/2.0/export?api_key=' + api_key + "&expire=" + expire + "&from_date=" + from_date;
    // to_date will be added later as the sneaky callback

    path = path + "&sig=" + sig;

    $.jsonp({
        type: 'GET',
        url: path,
        async: false,
        callback: to_date,  // sneaky bogus shenanigans
        callbackParameter: 'to_date', // more of same
        contentType: "application/json",
        dataType: 'jsonp',
        cache: true,
        success: function(json) {
            alert(json);
        },
        error: function(e) {
            console.log(e.message);
        }
    });

</script>

Ultimately I threw up my hands and wrote a C# program to hit the API and spit out a CSV for me.

like image 33
Tyler Avatar answered Oct 21 '22 09:10

Tyler