PHP Requires Chilkat v11.5.0+
Chilkat2 PHP
Box: Poll User Events and Save a Checkpoint
See more Box Examples
Poll the authenticated user event stream in bounded batches. The local JSON checkpoint keeps processed event IDs and the next stream position. This single-process demonstration logs events; a production worker should commit its business action, deduplication record, and cursor transactionally and prune old IDs.
See the Box API guide for setup and the complete workflow.
Chilkat PHP Downloads
<?php
use Chilkat2\FileAccess;
use Chilkat2\HttpCurl;
use Chilkat2\JsonObject;
use Chilkat2\StringBuilder;
$success = false;
// Requires Chilkat 11.5.0 or later and a previously unlocked Chilkat bundle.
// See Global Unlock Sample.
// Guide: Box API Guide.
$success = false;
// Supply an unexpired token obtained with one of the Box authentication examples.
// A token represents a particular user or service account. IDs must be accessible to it.
$curl = new HttpCurl();
$curl->SetVar('access_token', 'BOX_ACCESS_TOKEN');
$state = new JsonObject();
$files = new FileAccess();
$statePath = 'qa_data/box_events_state.json';
if ($files->FileExists($statePath)) {
try {
$state->LoadFile($statePath);
} catch (\Chilkat2\Exception $e) {
echo $e->getMessage(), "\n";
exit;
}
if (!$state->HasMember('position')) {
echo "Invalid checkpoint: position missing.\n";
exit;
}
} else {
// "now" starts a new subscription. It deliberately skips historical events.
$state->UpdateString('position', 'now');
}
$curl->SetVar('position', $state->StringOf('position'));
$page = new JsonObject();
$seenPath = new StringBuilder();
$eventId = '';
$nextPosition = '';
$batch = 0;
$i = 0;
$count = 0;
$more = true;
while (($more) && ($batch < 20)) {
$curl->ClearTargetOutput('*');
$authorizedCommand1 = new StringBuilder();
$authorizedCommand1->SetString('curl -X GET "https://api.box.com/2.0/events?stream_type=all&stream_position={{position}}&limit=100" -H "Authorization: Bearer {{access_token}}"');
$headerReplacement1 = $authorizedCommand1->Replace('{{access_token}}', $curl->GetVar('access_token'));
try {
$curl->DoYourThing($authorizedCommand1->GetAsString());
$success = true;
} catch (\Chilkat2\Exception $e) {
$success = false;
}
if ((!$success) || ($curl->StatusCode != 200)) {
echo 'Box request failed. HTTP status: ', $curl->StatusCode, "\n";
echo 'Failure reason: ', $curl->FailReason, "\n";
echo $curl->ResponseBodyStr, "\n";
exit;
}
try {
$curl->GetResponseJson($page);
} catch (\Chilkat2\Exception $e) {
echo $e->getMessage(), "\n";
exit;
}
$count = $page->SizeOfArray('entries');
$i = 0;
while ($i < $count) {
$page->I = $i;
$eventId = $page->StringOf('entries[i].event_id');
if ($eventId === '') {
echo "Event without an event_id; checkpoint not advanced.\n";
exit;
}
$seenPath->Clear();
$seenPath->Append('seen.');
$seenPath->Append($eventId);
if (!$state->HasMember($seenPath->GetAsString())) {
// Replace this logging with your idempotent business operation.
// Record success only after that operation succeeds.
echo $eventId, ' ', $page->StringOf('entries[i].event_type'), ' ', $page->StringOf('entries[i].source.id'), "\n";
$state->UpdateBool($seenPath->GetAsString(), true);
}
$i = $i + 1;
}
$nextPosition = $page->StringOf('next_stream_position');
if ($nextPosition === '') {
echo "Missing next_stream_position; checkpoint not advanced.\n";
exit;
}
$more = ($count > 0) && ($nextPosition !== $curl->GetVar('position'));
$state->UpdateString('position', $nextPosition);
try {
$state->WriteFile($statePath);
} catch (\Chilkat2\Exception $e) {
echo $e->getMessage(), "\n";
exit;
}
$curl->SetVar('position', $nextPosition);
$batch = $batch + 1;
}
echo "Checkpoint saved. Run again later to continue polling.\n";