PHPackages                             skeylup/laravel-pipedrive - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [API Development](/categories/api)
4. /
5. skeylup/laravel-pipedrive

ActiveLibrary[API Development](/categories/api)

skeylup/laravel-pipedrive
=========================

Wrapper for Pipedrive &lt;&gt; Laravel

10PHPCI failing

Since Jul 20Pushed 1mo agoCompare

[ Source](https://github.com/skeylup/laravel-pipedrive)[ Packagist](https://packagist.org/packages/skeylup/laravel-pipedrive)[ RSS](/packages/skeylup-laravel-pipedrive/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependenciesVersions (1)Used By (0)

🚀 Laravel Pipedrive Integration
===============================

[](#-laravel-pipedrive-integration)

A comprehensive Laravel package for seamless Pipedrive CRM integration. Sync entities, manage custom fields, and leverage Eloquent relationships with a robust JSON-based data structure for maximum flexibility and performance.

✨ **Features**
--------------

[](#-features)

- 🔄 **Complete Entity Synchronization** - Activities, Deals, Files, Notes, Organizations, Persons, Pipelines, Products, Stages, Users, Goals
- 🔔 **Real-Time Webhooks** - Instant synchronization with secure webhook handling
- � **Scheduled Synchronization** - Automated background sync with configurable frequency
- 🛡️ **API Rate Limiting** - Built-in delays to prevent API rate limit issues
- �🔗 **Eloquent Relationships** - Navigate between entities with Laravel's relationship system
- 🎯 **Custom Fields Management** - Full support for Pipedrive custom fields with automated synchronization
- 🏗️ **Hybrid Data Structure** - Essential columns + JSON storage for maximum flexibility
- 🔐 **Dual Authentication** - Support for both API tokens and OAuth
- ⚡ **Performance Optimized** - Efficient queries with proper indexing
- 📊 **Rich Querying** - Advanced filtering and relationship queries
- 🔄 **Automatic Entity Merging** - Seamless handling of entity merges with relationship continuity
- 🤖 **Smart Custom Field Detection** - Real-time detection and sync of new custom fields via webhooks

🛡️ **Production-Ready Robustness**
----------------------------------

[](#️-production-ready-robustness)

This package includes enterprise-grade robustness features designed for production environments:

### **Smart Rate Limiting**

[](#smart-rate-limiting)

- 🚦 **Token-based system** supporting Pipedrive's December 2024 rate limiting changes
- 📊 **Daily budget tracking** with automatic token consumption monitoring
- ⏱️ **Exponential backoff** with intelligent retry strategies
- 🎯 **Per-endpoint cost calculation** for optimal API usage

### **Intelligent Error Handling**

[](#intelligent-error-handling)

- 🔄 **Circuit breaker pattern** prevents cascading failures
- 🎯 **Error classification** with specific retry strategies for different error types
- 🔍 **Automatic exception classification** (rate limits, auth, server errors, etc.)
- 📈 **Failure tracking** with automatic recovery detection

### **Adaptive Memory Management**

[](#adaptive-memory-management)

- 🧠 **Real-time memory monitoring** with automatic alerts
- 📏 **Dynamic batch size adjustment** based on memory usage
- 🗑️ **Automatic garbage collection** during large operations
- ⚠️ **Memory threshold warnings** with suggested optimizations

### **API Health Monitoring**

[](#api-health-monitoring)

- 💚 **Continuous health checks** with cached status
- 📊 **Performance degradation detection** with response time monitoring
- 🔄 **Automatic recovery** when API health improves
- 📈 **Health statistics** and trend analysis

### **Centralized Job Architecture**

[](#centralized-job-architecture)

- 🏗️ **Unified processing** eliminates code duplication
- ⚡ **Dual execution modes** (synchronous for commands, asynchronous for schedulers)
- 📊 **Progress tracking** with detailed statistics
- 🔄 **Automatic retry logic** with intelligent backoff strategies

📦 **Installation**
------------------

[](#-installation)

Install the package via Composer:

```
composer require skeylup/laravel-pipedrive
```

Publish and run the migrations:

```
php artisan vendor:publish --tag="laravel-pipedrive-migrations"
php artisan migrate
```

Publish the config file:

```
php artisan vendor:publish --tag="laravel-pipedrive-config"
```

⚙️ **Configuration**
--------------------

[](#️-configuration)

Add your Pipedrive credentials to your `.env` file:

### **API Token Authentication (Recommended for Simple Integrations)**

[](#api-token-authentication-recommended-for-simple-integrations)

The simplest way to authenticate with Pipedrive. Get your API token from Pipedrive:

1. **Log into your Pipedrive account**
2. **Go to Settings → Personal preferences → API**
3. **Copy your API token**
4. **Add to your `.env` file:**

```
PIPEDRIVE_AUTH_METHOD=token
PIPEDRIVE_TOKEN=your_api_token_here
```

### **OAuth 2.0 Authentication (Recommended for Production Apps)**

[](#oauth-20-authentication-recommended-for-production-apps)

OAuth provides more secure authentication and is required for public applications. Follow these steps:

#### **Step 1: Create a Pipedrive App**

[](#step-1-create-a-pipedrive-app)

1. **Go to [Pipedrive Developer Hub](https://developers.pipedrive.com/)**
2. **Sign in with your Pipedrive account**
3. **Click "Create an app"**
4. **Fill in your app details:**
    - **App name**: Your application name
    - **App description**: Brief description of your app
    - **App URL**: Your application's homepage URL
    - **Callback URL**: `https://your-domain.com/pipedrive/oauth/callback`
5. **Select required scopes** (permissions your app needs)
6. **Submit for review** (for public apps) or **create as private app**

#### **Step 2: Get Your OAuth Credentials**

[](#step-2-get-your-oauth-credentials)

After app creation/approval, you'll receive:

- **Client ID**: Public identifier for your app
- **Client Secret**: Secret key (keep this secure!)

#### **Step 3: Configure Your Laravel App**

[](#step-3-configure-your-laravel-app)

Add OAuth credentials to your `.env` file:

```
PIPEDRIVE_AUTH_METHOD=oauth
PIPEDRIVE_CLIENT_ID=your_client_id_from_pipedrive
PIPEDRIVE_CLIENT_SECRET=your_client_secret_from_pipedrive
PIPEDRIVE_REDIRECT_URL=https://your-domain.com/pipedrive/oauth/callback
```

#### **Step 4: OAuth Web Interface (Built-in)**

[](#step-4-oauth-web-interface-built-in)

The package includes a complete OAuth web interface with beautiful UI pages. After configuration, you can use these routes:

```
# OAuth management routes (automatically registered)
/pipedrive/oauth/authorize    # Start OAuth flow (protected)
/pipedrive/oauth/callback     # OAuth callback (set this in Pipedrive app)
/pipedrive/oauth/status       # Check connection status (protected)
/pipedrive/oauth/disconnect   # Disconnect from Pipedrive (protected)
/pipedrive/webhook/health     # Webhook health check (protected)
```

> **🔒 Security Note**: Most routes are protected by dashboard authorization in non-local environments. See [Dashboard Authorization](docs/authorization/dashboard-authorization.md) for configuration details.

#### **Step 5: Initiate OAuth Flow**

[](#step-5-initiate-oauth-flow)

**Option A: Use Built-in Web Interface**

1. Visit `/pipedrive/oauth/status` to check current status
2. Click "Connect to Pipedrive" or visit `/pipedrive/oauth/authorize`
3. You'll see a beautiful authorization page with scope details
4. Click "Connect to Pipedrive" to redirect to Pipedrive
5. Authorize your app on Pipedrive
6. You'll be redirected back with a success page

**Option B: Programmatic OAuth (Custom Implementation)**

```
// In your controller
public function connectToPipedrive()
{
    $authService = app(\Skeylup\LaravelPipedrive\Services\PipedriveAuthService::class);
    $pipedrive = $authService->getPipedriveInstance();

    $authUrl = $pipedrive->getAuthorizationUrl([
        'scope' => 'deals:read deals:write persons:read persons:write'
    ]);

    return redirect($authUrl);
}
```

#### **Step 6: Non-Expiring Tokens**

[](#step-6-non-expiring-tokens)

The package automatically handles token storage and refresh. For non-expiring tokens:

- Tokens are stored securely in cache with long TTL (1 year for non-expiring tokens)
- No manual refresh needed for non-expiring tokens
- Automatic refresh for expiring tokens (when supported by Pipedrive)
- Use `/pipedrive/oauth/status` to monitor token status

#### **OAuth vs API Token Comparison**

[](#oauth-vs-api-token-comparison)

FeatureAPI TokenOAuth 2.0**Setup Complexity**SimpleModerate**Security**GoodExcellent**Token Expiration**NeverYes (with refresh)**User Consent**Not requiredRequired**Multi-user Support**NoYes**Recommended For**Personal/Internal appsProduction/Public apps**Pipedrive App Store**Not eligibleRequired### **Scheduled Synchronization &amp; Robustness Configuration**

[](#scheduled-synchronization--robustness-configuration)

```
# Enable scheduled sync (SAFE MODE - always uses standard sync, never full-data)
PIPEDRIVE_SCHEDULER_ENABLED=true
PIPEDRIVE_SCHEDULER_FREQUENCY=24
PIPEDRIVE_SCHEDULER_TIME=02:00
PIPEDRIVE_SCHEDULER_LIMIT=500

# Custom fields automatic synchronization
PIPEDRIVE_CUSTOM_FIELDS_SCHEDULER_ENABLED=true
PIPEDRIVE_CUSTOM_FIELDS_SCHEDULER_FREQUENCY=1
PIPEDRIVE_CUSTOM_FIELDS_SCHEDULER_FORCE=true

# Webhook custom field detection
PIPEDRIVE_WEBHOOKS_DETECT_CUSTOM_FIELDS=true

# Entity configuration
PIPEDRIVE_ENABLED_ENTITIES=deals,activities,persons,organizations,products

# Robustness features
PIPEDRIVE_RATE_LIMITING_ENABLED=true
PIPEDRIVE_DAILY_TOKEN_BUDGET=10000
PIPEDRIVE_MEMORY_THRESHOLD=80
PIPEDRIVE_HEALTH_MONITORING_ENABLED=true
PIPEDRIVE_CIRCUIT_BREAKER_THRESHOLD=5
```

🚀 **Quick Start**
-----------------

[](#-quick-start)

### **Test Your Connection**

[](#test-your-connection)

```
php artisan pipedrive:test-connection
```

### **View Configuration**

[](#view-configuration)

```
# Show current entity configuration
php artisan pipedrive:config --entities

# Show full configuration
php artisan pipedrive:config

# JSON output
php artisan pipedrive:config --json
```

### **Sync Entities from Pipedrive**

[](#sync-entities-from-pipedrive)

```
# Sync all enabled entities
php artisan pipedrive:sync-entities

# Sync specific entity (even if disabled)
php artisan pipedrive:sync-entities --entity=deals --limit=50

# Verbose output with configuration details
php artisan pipedrive:sync-entities --entity=users --verbose
```

### **Sync Custom Fields**

[](#sync-custom-fields)

```
# Sync all custom fields
php artisan pipedrive:sync-custom-fields

# Sync specific entity fields
php artisan pipedrive:sync-custom-fields --entity=deal --verbose

# Force sync (skip confirmations)
php artisan pipedrive:sync-custom-fields --force

# Full data mode with pagination (use with caution)
php artisan pipedrive:sync-custom-fields --full-data --force
```

**🤖 Automatic Custom Field Synchronization:**

- **Hourly Scheduler**: Automatically syncs custom fields every hour (configurable)
- **Webhook Detection**: Real-time detection of new custom fields in entity updates
- **Smart Triggering**: Only syncs when new fields are detected to minimize API usage

### **Scheduled Synchronization**

[](#scheduled-synchronization)

```
# Run scheduled sync manually (SAFE MODE - always uses standard sync)
php artisan pipedrive:scheduled-sync

# Test configuration (dry run)
php artisan pipedrive:scheduled-sync --dry-run

# Verbose output for debugging
php artisan pipedrive:scheduled-sync --verbose
```

**🛡️ Safety Features**:

- Scheduled sync **ALWAYS** uses standard mode (limit=500, sorted by last modified)
- **NEVER** uses full-data mode for safety and performance
- Includes comprehensive robustness features (rate limiting, error handling, memory management)
- Automatic retry logic with circuit breaker protection

### **Real-Time Webhooks**

[](#real-time-webhooks)

```
# Setup webhook for real-time sync
php artisan pipedrive:webhooks create \
    --url=https://your-app.com/pipedrive/webhook \
    --event=*.* \
    --auth-user=webhook_user \
    --auth-pass=secure_password

# List existing webhooks
php artisan pipedrive:webhooks list

# Test webhook endpoint
curl https://your-app.com/pipedrive/webhook/health
```

🔒 **Dashboard Authorization**
-----------------------------

[](#-dashboard-authorization)

The package includes a Telescope-like authorization system to protect management routes in production:

### **Quick Setup**

[](#quick-setup)

```
# Complete installation (config, migrations, views, service provider)
php artisan pipedrive:install

# Run migrations
php artisan migrate

# Add to config/app.php providers array
App\Providers\PipedriveServiceProvider::class,
```

### **Configuration Options**

[](#configuration-options)

**Option 1: Simple Email/ID Authorization**

```
// config/pipedrive.php
'dashboard' => [
    'authorized_emails' => [
        'admin@example.com',
        'developer@example.com',
    ],
    'authorized_user_ids' => [1, 2],
],
```

**Option 2: Custom Gate Logic**

```
// app/Providers/PipedriveServiceProvider.php
Gate::define('viewPipedrive', function ($user) {
    return $user->hasRole('admin') || $user->can('manage-pipedrive');
});
```

**Protected Routes**: `/pipedrive/oauth/*`, `/pipedrive/webhook/health`

📖 **[Complete Authorization Guide →](docs/authorization/dashboard-authorization.md)**

📊 **Models &amp; Relationships**
--------------------------------

[](#-models--relationships)

All Pipedrive entities are available as Eloquent models with full relationship support:

```
use Skeylup\LaravelPipedrive\Models\{
    PipedriveActivity, PipedriveDeal, PipedriveFile, PipedriveNote,
    PipedriveOrganization, PipedrivePerson, PipedrivePipeline,
    PipedriveProduct, PipedriveStage, PipedriveUser, PipedriveGoal
};

// Link your Laravel models to Pipedrive entities
use Skeylup\LaravelPipedrive\Traits\HasPipedriveEntity;
use Skeylup\LaravelPipedrive\Enums\PipedriveEntityType;

class Order extends Model
{
    use HasPipedriveEntity;

    // Define default Pipedrive entity type
    protected PipedriveEntityType $pipedriveEntityType = PipedriveEntityType::DEALS;

    public function linkToDeal(int $dealId): void
    {
        $this->linkToPipedriveEntity($dealId, true);
    }
}

// Navigate relationships
$deal = PipedriveDeal::with(['user', 'person', 'organization', 'stage'])->first();
echo $deal->user->name;         // Deal owner
echo $deal->person->name;       // Contact person
echo $deal->organization->name; // Company
echo $deal->stage->name;        // Current stage

// Reverse relationships
$user = PipedriveUser::with(['deals', 'activities'])->first();
echo $user->deals->count();     // Number of deals
echo $user->activities->count(); // Number of activities
```

🔗 **Entity Linking**
--------------------

[](#-entity-linking)

Link your Laravel models to Pipedrive entities with morphic relationships:

```
// In your Laravel model
class Order extends Model
{
    use HasPipedriveEntity;

    // Set default entity type
    protected PipedriveEntityType $pipedriveEntityType = PipedriveEntityType::DEALS;
}

// Usage
$order = Order::create([...]);

// Link to Pipedrive deal (uses default entity type)
$order->linkToPipedriveEntity(123, true, ['source' => 'manual']);

// Link to additional entities
$order->linkToPipedrivePerson(456, false, ['role' => 'customer']);
$order->linkToPipedriveOrganization(789, false, ['type' => 'client']);

// Get linked entities
$deal = $order->getPrimaryPipedriveEntity();
$persons = $order->getPipedrivePersons();

// Check if linked
if ($order->isLinkedToPipedriveEntity(123)) {
    // Order is linked to deal 123
}

// Push modifications to Pipedrive (async by default)
$result = $order->pushToPipedrive([
    'title' => 'Updated Order',
    'value' => 1500.00,
], [
    'Order Number' => $order->order_number,
    'Customer Email' => $order->customer_email,
]);

// Force synchronous execution
$result = $order->pushToPipedrive($modifications, $customFields, true);

// Use custom queue with retries
$result = $order->pushToPipedrive($modifications, $customFields, false, 'high-priority', 5);

// Display details with readable custom field names
$details = $order->displayPipedriveDetails();
foreach ($details['custom_fields'] as $name => $fieldData) {
    echo "{$name}: {$fieldData['value']}\n";
}

// Manage links via Artisan
php artisan pipedrive:entity-links stats
php artisan pipedrive:entity-links sync
php artisan pipedrive:entity-links cleanup
```

📡 **Events**
------------

[](#-events)

Listen to Pipedrive entity changes with Laravel events:

```
// In EventServiceProvider.php
protected $listen = [
    PipedriveEntityCreated::class => [
        App\Listeners\NewDealNotificationListener::class,
    ],
    PipedriveEntityUpdated::class => [
        App\Listeners\DealStatusChangeListener::class,
    ],
    PipedriveEntityDeleted::class => [
        App\Listeners\CleanupListener::class,
    ],
];

// Example listener
public function handle(PipedriveEntityUpdated $event)
{
    if ($event->isDeal() && $event->hasChanged('status')) {
        $deal = $event->entity;
        $newStatus = $event->getNewValue('status');

        if ($newStatus === 'won') {
            CreateInvoiceJob::dispatch($deal);
        }
    }
}
```

🔍 **Querying Data**
-------------------

[](#-querying-data)

### **Basic Queries**

[](#basic-queries)

```
// Active deals with high value
$deals = PipedriveDeal::where('status', 'open')
    ->where('value', '>', 10000)
    ->active()
    ->get();

// Overdue activities
$activities = PipedriveActivity::where('done', false)
    ->where('due_date', '
