Skip to content

Commit

Permalink
feat: add trackNow and identifyNow (#17)
Browse files Browse the repository at this point in the history
Co-authored-by: Tom Roelofs <[email protected]>
  • Loading branch information
TheTomRoelofs and Tom Roelofs authored Jul 15, 2024
1 parent d47264a commit 90d3b55
Show file tree
Hide file tree
Showing 10 changed files with 230 additions and 13 deletions.
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,12 @@ Segment::forUser($user)->track('User Signed Up', [
Segment::track('User Signed Up', [
'source' => 'Product Hunt',
]);

// If you have defer enabled in the config
// you can still track an event immediately using trackNow.
Segment::trackNow('User Signed Up', [
'source' => 'Product Hunt',
]);
```

### For identifying users
Expand All @@ -156,6 +162,12 @@ Segment::identify([
'last_logged_in' => '2021-03-24 20:05:30',
'latest_subscription_amount' => '$24.60',
]);

// If you have defer enabled in the config
// you can still identify a user immediately using identifyNow.
Segment::identifyNow('User Signed Up', [
'source' => 'Product Hunt',
]);
```

### Laravel Notifications
Expand Down
4 changes: 1 addition & 3 deletions src/Facades/Fakes/SegmentFake.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,7 @@ public function push(CanBeSentToSegment $segment): void
}
}

public function terminate(): void
{
}
public function terminate(): void {}

public function assertIdentified(Closure|int|null $callback = null): void
{
Expand Down
2 changes: 2 additions & 0 deletions src/Facades/Segment.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@
* @method static void setGlobalUser(CanBeIdentifiedForSegment $globalUser)
* @method static void setGlobalContext(?array $globalContext)
* @method static void track(string $event, ?array $eventData = null)
* @method static void trackNow(string $event, ?array $eventData = null)
* @method static void identify(?array $identifyData = null)
* @method static void identifyNow(?array $identifyData = null)
* @method static PendingUserSegment forUser(CanBeIdentifiedForSegment $user)
* @method static void push(CanBeSentToSegment $segment)
* @method static void terminate()
Expand Down
24 changes: 24 additions & 0 deletions src/PendingUserSegment.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,18 @@ public function track(string $event, ?array $eventData = null): void
);
}

/**
* @param array<string, mixed>|null $eventData
*/
public function trackNow(string $event, ?array $eventData = null): void
{
$this->service->push(
new SimpleSegmentEvent($this->user, $event, $eventData)
);

$this->service->terminate();
}

/**
* @param array<string, mixed>|null $identifyData
*/
Expand All @@ -36,4 +48,16 @@ public function identify(?array $identifyData = null): void
new SimpleSegmentIdentify($this->user, $identifyData)
);
}

/**
* @param array<string, mixed>|null $identifyData
*/
public function identifyNow(?array $identifyData = null): void
{
$this->service->push(
new SimpleSegmentIdentify($this->user, $identifyData)
);

$this->service->terminate();
}
}
27 changes: 25 additions & 2 deletions src/SegmentService.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@ class SegmentService implements SegmentServiceContract
*/
public function __construct(
private readonly array $config
) {
}
) {}

public function setGlobalUser(CanBeIdentifiedForSegment $globalUser): void
{
Expand All @@ -54,6 +53,18 @@ public function track(string $event, ?array $eventData = null): void
);
}

/**
* @param array<string, mixed> $eventData
*/
public function trackNow(string $event, ?array $eventData = null): void
{
$this->push(
new SimpleSegmentEvent($this->globalUser, $event, $eventData)
);

$this->terminate();
}

/**
* @param array<string, mixed> $identifyData
*/
Expand All @@ -64,6 +75,18 @@ public function identify(?array $identifyData = null): void
);
}

/**
* @param array<string, mixed> $identifyData
*/
public function identifyNow(?array $identifyData = null): void
{
$this->push(
new SimpleSegmentIdentify($this->globalUser, $identifyData)
);

$this->terminate();
}

public function forUser(CanBeIdentifiedForSegment $user): PendingUserSegment
{
return new PendingUserSegment($this, $user);
Expand Down
3 changes: 1 addition & 2 deletions src/SimpleSegmentEvent.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@ public function __construct(
private readonly CanBeIdentifiedForSegment $user,
private readonly string $event,
private readonly ?array $eventData = null,
) {
}
) {}

public function toSegment(): SegmentPayload
{
Expand Down
3 changes: 1 addition & 2 deletions src/SimpleSegmentIdentify.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@ class SimpleSegmentIdentify implements CanBeSentToSegment
public function __construct(
private CanBeIdentifiedForSegment $user,
private ?array $identifyData = null
) {
}
) {}

public function toSegment(): SegmentPayload
{
Expand Down
3 changes: 1 addition & 2 deletions tests/Stubs/SegmentTestNotification.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ class SegmentTestNotification extends Notification implements CanNotifyViaSegmen
{
public function __construct(
private int $number
) {
}
) {}

public function via(object $notifiable): array
{
Expand Down
3 changes: 1 addition & 2 deletions tests/Stubs/SegmentTestUser.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ class SegmentTestUser implements CanBeIdentifiedForSegment

public function __construct(
private string $id
) {
}
) {}

public function getSegmentIdentifier(): string
{
Expand Down
162 changes: 162 additions & 0 deletions tests/Unit/SegmentServiceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,168 @@
});
});

it('terminates directly when using trackNow while deferred is enabled', function () {
// Given we have a user
$user = new SegmentTestUser('abcd');

// And we are deferring
setDefer(true);

// And we have set a write key
setWriteKey();

// And we are faking the Http facade
Http::fake();

// And we call the track method
Segment::forUser($user)->trackNow('Something Happened', [
'name' => 'special',
]);

// Then we have made the calls to Segment
Http::assertSent(function (Request $request) {
return $request->hasHeader('Content-Type', 'application/json')
&& $request->hasHeader('Authorization', 'Bearer '.base64_encode('key_1234:'))
&& $request->url() === 'https://api.segment.io/v1/batch'
&& $request['context'] === []
&& count($request['batch']) === 1
&& arraysMatch($request['batch'][0], [
'type' => 'track',
'userId' => 'abcd',
'timestamp' => (new DateTime())->format('Y-m-d\TH:i:s\Z'),
'properties' => [
'name' => 'special',
],
'event' => 'Something Happened',
]);
});
});

it('terminates directly when using identifyNow while deferred is enabled', function () {
// Given we have a user
$user = new SegmentTestUser('abcd');

// And we are deferring
setDefer(true);

// And we have set a write key
setWriteKey();

// And we are faking the Http facade
Http::fake();

// And we call the track method
Segment::forUser($user)->identifyNow([
'seen_email' => true,
]);

// Then we have made the calls to Segment
Http::assertSent(function (Request $request) {
return $request->hasHeader('Content-Type', 'application/json')
&& $request->hasHeader('Authorization', 'Bearer '.base64_encode('key_1234:'))
&& $request->url() === 'https://api.segment.io/v1/batch'
&& $request['context'] === []
&& count($request['batch']) === 1
&& arraysMatch($request['batch'][0], [
'type' => 'identify',
'userId' => 'abcd',
'timestamp' => (new DateTime())->format('Y-m-d\TH:i:s\Z'),
'traits' => [
'seen_email' => true,
],
]);
});
});

it('terminates directly when using trackNow while deferred is enabled with global user and context', function () {
// Given we have a user
$user = new SegmentTestUser('abcd');

// And we are deferring
setDefer(true);

// And we have set a write key
setWriteKey();

// And we have set global user
Segment::setGlobalUser($user);

// And we have set global context
Segment::setGlobalContext([
'ip' => '127.0.0.1',
]);

// And we are faking the Http facade
Http::fake();

// And we call the track method
Segment::trackNow('Something Happened', [
'name' => 'special',
]);

// Then we have made the calls to Segment
Http::assertSent(function (Request $request) {
return $request->hasHeader('Content-Type', 'application/json')
&& $request->hasHeader('Authorization', 'Bearer '.base64_encode('key_1234:'))
&& $request->url() === 'https://api.segment.io/v1/batch'
&& $request['context'] === ['ip' => '127.0.0.1']
&& count($request['batch']) === 1
&& arraysMatch($request['batch'][0], [
'type' => 'track',
'userId' => 'abcd',
'timestamp' => (new DateTime())->format('Y-m-d\TH:i:s\Z'),
'properties' => [
'name' => 'special',
],
'event' => 'Something Happened',
]);
});
});

it('terminates directly when using identifyNow while deferred is enabled with global user and context', function () {
// Given we have a user
$user = new SegmentTestUser('abcd');

// And we are deferring
setDefer(true);

// And we have set a write key
setWriteKey();

// And we have set global user
Segment::setGlobalUser($user);

// And we have set global context
Segment::setGlobalContext([
'ip' => '127.0.0.1',
]);

// And we are faking the Http facade
Http::fake();

// And we call the track method
Segment::identifyNow([
'seen_email' => true,
]);

// Then we have made the calls to Segment
Http::assertSent(function (Request $request) {
return $request->hasHeader('Content-Type', 'application/json')
&& $request->hasHeader('Authorization', 'Bearer '.base64_encode('key_1234:'))
&& $request->url() === 'https://api.segment.io/v1/batch'
&& $request['context'] === ['ip' => '127.0.0.1']
&& count($request['batch']) === 1
&& arraysMatch($request['batch'][0], [
'type' => 'identify',
'userId' => 'abcd',
'timestamp' => (new DateTime())->format('Y-m-d\TH:i:s\Z'),
'traits' => [
'seen_email' => true,
],
]);
});
});

it('does not sent tracking events when not enabled', function () {
// Given we have a user
$user = new SegmentTestUser('abcd');
Expand Down

0 comments on commit 90d3b55

Please sign in to comment.