Join BoxWorks in San Francisco Nov 12-13! Keynotes, product demos, and Box Master Classes. Reserve your spot!

help with event stream

Answered
New post

Comments

9 comments

  • bibek_k

    Hi,

     

    I believe when you get the first result like this:

    chunk_size": 1,
        "next_stream_position": ***number removed for privacy***9819,
        "entries": [ ........

    For the next call, you would still specify limit but use the stream position value to be the value of "next_stream_position". so, your stream position will be "***number removed for privacy***9819" for the next call. And you should do while loop or any loop until the next_stream_position gets to current. 

     

    let me know if this makes sense.

     

    thanks,

    Bibek

    0
    Comment actions Permalink
  • kendomen

    Here's some code:

            static void Main(string[] args)
            {
                Task t = MainAsync();
                t.Wait();
                Console.WriteLine("Done...");
                Console.ReadKey();   
            }
    
            static async Task MainAsync()
            {
                var privateKey = File.ReadAllText(PRIVATE_KEY_FILE);            
                var boxConfig = new BoxConfig(CLIENT_ID, CLIENT_SECRET, ENTERPRISE_ID, privateKey, JWT_PRIVATE_KEY_PASSWORD, JWT_PUBLIC_KEY_ID);
                var boxJWT = new BoxJWTAuth(boxConfig);
    
                var adminToken = boxJWT.AdminToken();
                var adminClient = boxJWT.AdminClient(adminToken);
    
                DateTime createdAfter = DateTime.Parse("2016-12-01T01:00:00-7:00");  // 2014-05-17T13:35:01-07:00
                DateTime createdBefore = DateTime.Parse("2016-12-01T01:05:00-7:00");
                string streamPosition = null;
    
                await loadEvents(adminClient, createdAfter, createdBefore, streamPosition); 
            }
    
            static async Task loadEvents(BoxClient adminClient, 
                DateTime createdAfter, DateTime createdBefore, string streamPosition)
            {
                Console.WriteLine("stream position: " + streamPosition);
    
                BoxEventCollection events = 
                    await adminClient.EventsManager.EnterpriseEventsAsync(
                        500, 
                        streamPosition, 
                        null,
                        createdAfter, 
                        createdBefore);
    
                events.Entries.ForEach(i =>
                {
                    // get your events
                });
    
                string nextStreamPosition = events.NextStreamPosition;
                if ((null != nextStreamPosition) && (nextStreamPosition != streamPosition))
                {
                    BoxEnterpriseEvent be = events.Entries.Last();
                    Console.WriteLine(be.CreatedAt);
    
                    await loadEvents(adminClient, createdAfter, createdBefore, nextStreamPosition);
                }
            }

     

    And here's the output:

    stream position:
    12/1/2016 4:01:10 PM
    stream position: 1152922985214917947
    12/1/2016 4:02:16 PM
    stream position: 1152922985214983518
    12/1/2016 4:03:09 PM
    stream position: 1152922985215036862
    12/1/2016 4:04:16 PM
    stream position: 1152922985215103558
    12/1/2016 4:04:59 PM
    stream position: 1152922985215146913
    Done...

    0
    Comment actions Permalink
  • bdudley

    Thank you. This is pretty much what I eventually did... I think it is working. (My code is in powershell.. but looks very similar).

     

    However, what is confusing to me is that once you start using stream position, you can no longer user the created before and created after dates. So if you want to get the events for a time period, wouldn't you also need to make sure that you stop at the "created before" date?

     

    Here's what I ended up with (that definitely needs cleaned up) :

     

    function Get-BoxAdminLog($token,$eventtype,$createdafter, $createdbefore, $limit=500){
        $head = @{}
        $head.Add("Authorization","Bearer $token")
        if($createdafter -and $createdbefore){
            $uri = "https://api.box.com/2.0/events?stream_type=admin_logs&event_type=$eventtype&created_after=$createdafter&created_before=$createdbefore&limit=$limit"
        }
        elseif($createdafter){
            $uri = "https://api.box.com/2.0/events?stream_type=admin_logs&event_type=$eventtype&created_after=$createdafter&limit=$limit"
        }
        elseif($createdbefore){
            $uri = "https://api.box.com/2.0/events?stream_type=admin_logs&event_type=$eventtype&created_before=$createdbefore&limit=$limit"
        }
        else{
            return "Please provide createdbefore, createdafter, or both"
        }
        $return = Invoke-RestMethod -Uri $uri -Method Get -Headers $head -ContentType "application/x-www-form-urlencoded"
    
        if($return.next_stream_position -eq 0){
            #get-date | out-file c:\temp\test.txt
            return $return.entries
        }
        else{
            $streampos = $return.next_stream_position
            $items = $return.entries
            while($return.next_stream_position -ne 0){
                $uri = "https://api.box.com/2.0/events?stream_type=admin_logs&event_type=$eventtype&stream_position=$streampos&limit=$limit"
                $return = Invoke-RestMethod -Uri $uri -Method Get -Headers $head -ContentType "application/x-www-form-urlencoded"
                if($return.next_stream_position -eq $streampos){
                    break
                }
                $items += $return.entries
                $streampos = $return.next_stream_position
                if($createdbefore){
                    if($return.entries[-1].created_at -gt $createdbefore){
                        break
                    }
                }
            }
            return $items
        }
    }

     

     

    0
    Comment actions Permalink
  • kendomen

    I believe it uses all 3.  When it first starts, it has no stream position and only createdAfter & createdBefore.  Then after the first loop, you'll get a stream_position but it will stop once it reaches createdBefore.

     

    I changed the code to output all 3 variables on the above test...

     

    stream position:
    createdAfter: 12/1/2016 8:00:00 AM
    createdBefore: 12/1/2016 8:05:00 AM
    -------------------------------------
    12/1/2016 4:01:10 PM
    stream position: 1152922985214917947
    createdAfter: 12/1/2016 8:00:00 AM
    createdBefore: 12/1/2016 8:05:00 AM
    -------------------------------------
    12/1/2016 4:02:16 PM
    stream position: 1152922985214983518
    createdAfter: 12/1/2016 8:00:00 AM
    createdBefore: 12/1/2016 8:05:00 AM
    -------------------------------------
    12/1/2016 4:03:09 PM
    stream position: 1152922985215036862
    createdAfter: 12/1/2016 8:00:00 AM
    createdBefore: 12/1/2016 8:05:00 AM
    -------------------------------------
    12/1/2016 4:04:16 PM
    stream position: 1152922985215103558
    createdAfter: 12/1/2016 8:00:00 AM
    createdBefore: 12/1/2016 8:05:00 AM
    -------------------------------------
    12/1/2016 4:04:59 PM
    stream position: 1152922985215146913
    createdAfter: 12/1/2016 8:00:00 AM
    createdBefore: 12/1/2016 8:05:00 AM
    -------------------------------------
    Done...
    0
    Comment actions Permalink
  • bdudley

    Can you share the code? In the original code, createdAfter and createdBefore were variables that you defined... so I would expect that the output is just printing variables you defined and not data returned from the API call.

     

    Also, the documentation specifically says:

    Important
    Box responds to the created_before and created_after parameters only if the stream_position parameter is not included.

     

    0
    Comment actions Permalink
  • kendomen
            static async Task MainAsync()
            {
                var privateKey = File.ReadAllText(PRIVATE_KEY_FILE);            
                var boxConfig = new BoxConfig(CLIENT_ID, CLIENT_SECRET, ENTERPRISE_ID, privateKey, JWT_PRIVATE_KEY_PASSWORD, JWT_PUBLIC_KEY_ID);
                var boxJWT = new BoxJWTAuth(boxConfig);
    
                var adminToken = boxJWT.AdminToken();
                var adminClient = boxJWT.AdminClient(adminToken);
    
                DateTime createdAfter = DateTime.Parse("2016-12-01T01:00:00-7:00");  
                DateTime createdBefore = DateTime.Parse("2016-12-01T01:05:00-7:00");
                string streamPosition = null;
    
                await loadEvents(adminClient, createdAfter, createdBefore, streamPosition);         
            }
    
            static async Task loadEvents(BoxClient adminClient, 
                DateTime createdAfter, DateTime createdBefore, string streamPosition)
            {
    
                Console.WriteLine("stream position: " + streamPosition);
                Console.WriteLine("createdAfter: " + createdAfter);
                Console.WriteLine("createdBefore: " + createdBefore);
                Console.WriteLine("-------------------------------------");
    
                BoxEventCollection events = 
                    await adminClient.EventsManager.EnterpriseEventsAsync(
                        500, 
                        streamPosition, 
                        null,
                        createdAfter, 
                        createdBefore);
    
                events.Entries.ForEach(i =>
                {
                    // get your events
                });
    
                string nextStreamPosition = events.NextStreamPosition;
                if ((null != nextStreamPosition) && (nextStreamPosition != streamPosition))
                {
                    BoxEnterpriseEvent be = events.Entries.Last();
                    Console.WriteLine(be.CreatedAt);
    
                    await loadEvents(adminClient, createdAfter, createdBefore, nextStreamPosition);
                }
            }
    0
    Comment actions Permalink
  • bdudley

    If your events actually stop at the "created_before" datetime... then the API call has to be using the created_before parameter still even though you are providing the stream_position... this goes opposite of what the documentation says.

     

    Because... the only thing stopping your loop is if the steamposition returned is null or if the stream position returned is the same as the last call... right?

    0
    Comment actions Permalink
  • kendomen

    Yes.  It's behaving that way.

    0
    Comment actions Permalink
  • bdudley

    Thank you.

    0
    Comment actions Permalink

Please sign in to leave a comment.