Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Customerio Laravel Package

userscape/customerio

PHP client for the Customer.io API. Create, update, and delete customers, fire events (including historical/anonymous), and record pageviews. Returns a Response object with success() and message() for simple error handling.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the Package:

    composer require userscape/customerio
    
  2. Configure Credentials: Add to .env:

    CUSTOMERIO_SITE_ID=your_site_id
    CUSTOMERIO_API_SECRET=your_api_secret
    
  3. Bind to Laravel Container: In AppServiceProvider or a dedicated service provider:

    use Customerio\Api;
    use Customerio\Request;
    
    public function register()
    {
        $this->app->singleton(Api::class, function ($app) {
            return new Api(
                config('services.customerio.site_id'),
                config('services.customerio.api_secret'),
                new Request()
            );
        });
    }
    
  4. First Use Case: Fire a user signup event in a controller:

    use Customerio\Api;
    
    public function handleSignup(Request $request, Api $customerio)
    {
        $response = $customerio->fireEvent(
            $request->user()->id,
            'user_signed_up',
            ['plan' => $request->input('plan')]
        );
    
        if (!$response->success()) {
            Log::error("Customer.io event failed: " . $response->message());
        }
    }
    

Where to Look First

  • API Methods: Focus on fireEvent(), createCustomer(), and recordPageview() for 80% of use cases.
  • Response Handling: Always check $response->success() before proceeding.
  • Documentation: Refer to Customer.io’s API docs for payload schemas (e.g., event attributes).

Implementation Patterns

Core Workflows

1. Customer Lifecycle Management

  • Signup:
    $customerio->createCustomer(
        $user->id,                  // Customer ID
        $user->email,               // Email
        ['name' => $user->name]     // Custom attributes
    );
    
  • Update:
    $customerio->updateCustomer(
        $user->id,
        ['last_login' => now()->toDateTimeString()]
    );
    
  • Delete (e.g., GDPR compliance):
    $customerio->deleteCustomer($user->id);
    

2. Event Tracking

  • Standard Events:
    $customerio->fireEvent(
        $user->id,
        'purchase_completed',
        ['amount' => $order->total, 'items' => $order->items]
    );
    
  • Historical Events (for backfilling):
    $customerio->fireEvent(
        $user->id,
        'old_event',
        ['data' => 'value'],
        strtotime('2023-01-01') // Unix timestamp
    );
    
  • Anonymous Events (pre-signup):
    $customerio->fireAnonymousEvent(
        'page_viewed',
        ['page_url' => $request->url()]
    );
    

3. Pageview Tracking

  • Single Pageview:
    $customerio->recordPageview(
        $user->id,
        'https://example.com/checkout',
        'https://example.com/cart'
    );
    
  • Middleware for Automatic Tracking:
    // app/Http/Middleware/TrackPageviews.php
    public function handle(Request $request, Closure $next, Api $customerio)
    {
        $response = $next($request);
        if ($user = auth()->user()) {
            $customerio->recordPageview(
                $user->id,
                $request->url(),
                $request->header('Referer')
            );
        }
        return $response;
    }
    

Integration Tips

Laravel-Specific Patterns

  1. Service Binding: Use a facade for cleaner syntax:

    // config/app.php
    'aliases' => [
        'Customerio' => Customerio\Facades\Customerio::class,
    ];
    
    // app/Facades/Customerio.php
    namespace Customerio\Facades;
    use Illuminate\Support\Facades\Facade;
    class Customerio extends Facade { protected static function getFacadeAccessor() { return 'customerio'; } }
    

    Now use Customerio::fireEvent(...) anywhere.

  2. Queued Events: Offload event firing to a queue to avoid blocking requests:

    // app/Jobs/FireCustomerioEvent.php
    public function handle()
    {
        $customerio = app(Api::class);
        $customerio->fireEvent($this->userId, $this->event, $this->data);
    }
    

    Dispatch in your controller:

    FireCustomerioEvent::dispatch($user->id, 'event_name', $data)->onQueue('customerio');
    
  3. Model Observers: Automate event firing for Eloquent models:

    // app/Observers/UserObserver.php
    public function created(User $user)
    {
        $customerio = app(Api::class);
        $customerio->fireEvent($user->id, 'user_created', $user->toArray());
    }
    

Data Synchronization

  • Sync on Model Save:

    // app/Models/User.php
    protected static function booted()
    {
        static::saved(function ($user) {
            if ($user->wasRecentlyCreated) {
                $customerio = app(Api::class);
                $customerio->createCustomer($user->id, $user->email, $user->attributesToArray());
            } else {
                $customerio->updateCustomer($user->id, $user->getDirty());
            }
        });
    }
    
  • Batch Updates: For large datasets, use Laravel’s chunking:

    User::chunk(100, function ($users) {
        $customerio = app(Api::class);
        foreach ($users as $user) {
            $customerio->updateCustomer($user->id, ['last_active' => now()]);
        }
    });
    

Error Handling

  • Global Exception Handler: Catch Customer.io API failures:

    // app/Exceptions/Handler.php
    public function report(Throwable $exception)
    {
        if ($exception instanceof \Customerio\Exception) {
            Log::error("Customer.io API error: " . $exception->getMessage());
        }
        parent::report($exception);
    }
    
  • Retry Logic: Use Laravel’s retry helper for transient failures:

    retry(5, function () use ($customerio, $user, $event) {
        $response = $customerio->fireEvent($user->id, $event, $data);
        return $response->success() ?: false;
    }, 100); // Retry after 100ms
    

Gotchas and Tips

Pitfalls

  1. API Key Exposure:

    • Risk: Hardcoding siteId/apiSecret in config files.
    • Fix: Use Laravel’s .env and validate keys on startup:
      if (empty(config('services.customerio.site_id'))) {
          throw new \RuntimeException("Customer.io site ID not configured.");
      }
      
  2. Deprecated Guzzle Version:

    • Issue: The package uses Guzzle 6, which may conflict with Laravel’s Guzzle 7.
    • Fix: Add to composer.json:
      "config": {
          "preferred-install": "dist",
          "allow-plugins": {
              "php-http/discovery": true
          }
      }
      
      Or use a Guzzle 6 polyfill.
  3. No Async Support:

    • Problem: Synchronous calls block requests.
    • Solution: Always queue non-critical events (e.g., fireEvent).
  4. Response Parsing:

    • Gotcha: The Response object’s message() may return raw JSON for errors.
    • Tip: Parse errors explicitly:
      $response = $customerio->fireEvent(...);
      if (!$response->success()) {
          $error = json_decode($response->message(), true);
          Log::error("Customer.io error: " . $error['message'] ?? $response->message());
      }
      
  5. Timestamp Handling:

    • Issue: Historical events require Unix timestamps (not Carbon instances).
    • Fix: Convert Carbon to timestamp:
      $timestamp = Carbon::parse('2023-01-01')->timestamp();
      $customerio->fireEvent($user->id, 'event', [], $timestamp);
      
  6. Anonymous Event Limits:

    • Warning: Anonymous events may be rate-limited by Customer.io.
    • Workaround: Use a temporary ID (e.g., session()->id) and resolve it post-signup.
  7. Data Size Limits:

    • Risk: Large payloads (e.g., updateCustomer with 100+ attributes) may fail.
    • Tip: Batch
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
terminal42/code-quality-tools
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky