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

Laravel There There Laravel Package

spatie/laravel-there-there

Expose your Laravel app data as JSON for There There. Configure a secret and endpoint, validate incoming requests, and register a sidebar callback to return relevant customer info when agents open a ticket, shown in There There’s sidebar.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require spatie/laravel-there-there
    

    Publish the config file:

    php artisan vendor:publish --provider="Spatie\ThereThere\ThereThereServiceProvider"
    
  2. Configure Webhook: Add the There There webhook URL to your config/there-there.php:

    'webhook_url' => env('THERE_THERE_WEBHOOK_URL'),
    
  3. First Use Case: Expose a simple model (e.g., User) by implementing Spatie\ThereThere\ThereThereable:

    use Spatie\ThereThere\ThereThereable;
    
    class User implements ThereThereable
    {
        public function getThereThereData(): array
        {
            return [
                'name' => $this->name,
                'email' => $this->email,
                'created_at' => $this->created_at->toDateTimeString(),
            ];
        }
    }
    
  4. Trigger Webhook: When a ticket is created in There There, it will call your endpoint (e.g., /there-there/{model}/{id}) to fetch data.


Implementation Patterns

Core Workflow

  1. Model Integration:

    • Implement ThereThereable on Eloquent models to define exposed data.
    • Use getThereThereData() to return a structured array of attributes.
  2. Dynamic Data Fetching:

    • For complex relationships, fetch data lazily in getThereThereData():
      public function getThereThereData(): array
      {
          return [
              'orders' => $this->orders()->with(['customer'])->get()->map(fn ($order) => [
                  'id' => $order->id,
                  'customer_name' => $order->customer->name,
              ]),
          ];
      }
      
  3. API Endpoint:

    • The package auto-generates a route (/there-there/{model}/{id}) to handle webhook calls.
    • Customize the route by publishing the config and modifying routes/there-there.php.
  4. Authentication:

    • Secure the endpoint with middleware (e.g., api or custom):
      Route::middleware(['api', 'signed'])->group(function () {
          // ...
      });
      
  5. Testing:

    • Mock the webhook in tests:
      $response = $this->get('/there-there/user/1');
      $response->assertJson(['name' => 'John Doe']);
      

Advanced Patterns

  • Conditional Data: Use closures to conditionally include data:

    public function getThereThereData(): array
    {
        return [
            'is_admin' => $this->role === 'admin' ? true : null,
        ];
    }
    
  • Nested Resources: Expose related models recursively:

    public function getThereThereData(): array
    {
        return [
            'project' => $this->project->load(['members'])->getThereThereData(),
        ];
    }
    
  • Caching: Cache responses for performance (e.g., using Laravel's cache):

    public function getThereThereData(): array
    {
        return Cache::remember("there-there-{$this->id}", now()->addMinutes(5), function () {
            return [...];
        });
    }
    

Gotchas and Tips

Pitfalls

  1. Webhook URL Mismatch:

    • Ensure the webhook_url in config/there-there.php matches the There There app's configured URL.
    • Fix: Verify the URL in There There's dashboard and update the config.
  2. Missing Middleware:

    • Forgetting to secure the endpoint can expose sensitive data.
    • Fix: Always apply authentication middleware (e.g., api, signed, or custom).
  3. Circular References:

    • Nested getThereThereData() calls can cause infinite loops.
    • Fix: Use ->first() or limit depth:
      public function getThereThereData(): array
      {
          return [
              'parent' => $this->parent?->getThereThereData(),
          ];
      }
      
  4. Performance Issues:

    • Eager-loading too much data in getThereThereData() can slow responses.
    • Fix: Load only necessary relationships or use with():
      $this->load(['comments.user']);
      
  5. Model Not Found:

    • If the model isn’t found, the endpoint returns a 404. Handle gracefully:
      public function getThereThereData(): array
      {
          if (!$this->exists) {
              return ['error' => 'Model not found'];
          }
          return [...];
      }
      

Debugging Tips

  1. Log Webhook Calls: Add logging to debug incoming requests:

    \Log::info('There There webhook called for', ['model' => $model, 'id' => $id]);
    
  2. Test Locally: Use tools like ngrok to test webhook calls locally:

    ngrok http 8000
    

    Configure the There There webhook URL to point to your ngrok endpoint.

  3. Validate JSON: Ensure getThereThereData() returns valid JSON:

    public function getThereThereData(): array
    {
        return json_decode($this->json_data, true) ?? [];
    }
    

Extension Points

  1. Custom Endpoint Logic: Override the default route behavior by binding a custom controller:

    Route::get('/there-there/{model}/{id}', [ThereThereController::class, 'show']);
    
  2. Add Metadata: Extend the response with metadata (e.g., ticket ID):

    public function getThereThereData(): array
    {
        return [
            '_metadata' => [
                'ticket_id' => request('ticket_id'),
            ],
            // ...
        ];
    }
    
  3. Dynamic Model Resolution: Resolve models dynamically (e.g., for polymorphic relationships):

    public function getThereThereData(): array
    {
        $model = $this->morphTo()->firstOrFail();
        return $model->getThereThereData();
    }
    
  4. Localization: Support multiple languages by returning localized data:

    public function getThereThereData(): array
    {
        return [
            'name' => __("user.{$this->locale}.name", ['name' => $this->name]),
        ];
    }
    
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.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport