# LinkedIn API Integration Setup Guide

## ⚠️ **Important Update (2024)**

LinkedIn has made significant changes to their API, and many previously available permissions are no longer accessible. This guide reflects the **current state** of LinkedIn's API.

## Overview

This guide explains how to set up LinkedIn API integration for the CRM system. **Note that due to LinkedIn's API restrictions, we can only access the authenticated user's own profile information, not other users' profiles.**

## Current API Limitations

### ✅ **What's Available:**
- **Basic Profile**: Name, profile picture, basic info
- **Email Address**: If user grants permission
- **Current Position**: Company and job title (limited)

### ❌ **What's NOT Available:**
- **Other Users' Profiles**: Cannot fetch data from arbitrary LinkedIn URLs
- **Extended Profile Data**: No access to detailed work history, education, etc.
- **Contact Information**: No access to phone numbers, addresses
- **Network Data**: Cannot access connections or network information

## Prerequisites

- LinkedIn Developer Account
- LinkedIn App created in the LinkedIn Developer Console
- Valid LinkedIn API credentials
- Laravel application with proper environment configuration

## Step 1: Create LinkedIn Developer Account

1. Go to [LinkedIn Developers](https://www.linkedin.com/developers/)
2. Sign in with your LinkedIn account
3. Click "Create App" to register a new application

## Step 2: Create LinkedIn App

1. **App Information:**
   - App Name: Your CRM application name
   - App Description: Brief description of your app
   - App Logo: Upload your app logo (optional)
   - App Website: Your application's website URL

2. **LinkedIn Products:**
   - Select "Sign In with LinkedIn" (Required)
   - Select "Marketing Developer Platform" (Optional - for company insights)

3. **App Permissions (Current Available):**
   - **`r_liteprofile`** - Basic profile information (name, profile picture)
   - **`r_emailaddress`** - Email address (if user grants permission)

   **Note:** These are the only profile-related permissions currently available.

## Step 3: Get API Credentials

After creating your app, you'll receive:

1. **Client ID** (API Key)
2. **Client Secret** (API Secret)
3. **Redirect URI** (OAuth callback URL)

## Step 4: Configure Environment Variables

Add the following variables to your `.env` file:

```env
# LinkedIn API Configuration
LINKEDIN_CLIENT_ID=your_linkedin_client_id
LINKEDIN_CLIENT_SECRET=your_linkedin_client_secret
LINKEDIN_REDIRECT_URI=https://yourdomain.com/linkedin/callback
LINKEDIN_API_VERSION=v2
```

## Step 5: Get Access Token

### Option A: User Authorization Flow (Recommended)

1. **Create OAuth Route:**
```php
// routes/web.php
Route::get('/linkedin/auth', [LinkedInController::class, 'redirect']);
Route::get('/linkedin/callback', [LinkedInController::class, 'callback']);
```

2. **Create LinkedIn Controller:**
```php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Http;

class LinkedInController extends Controller
{
    public function redirect()
    {
        $query = http_build_query([
            'response_type' => 'code',
            'client_id' => config('services.linkedin.client_id'),
            'redirect_uri' => config('services.linkedin.redirect'),
            'scope' => 'r_liteprofile r_emailaddress', // Current available scopes
            'state' => csrf_token(),
        ]);

        return redirect('https://www.linkedin.com/oauth/v2/authorization?' . $query);
    }

    public function callback(Request $request)
    {
        // Handle OAuth callback...
    }
}
```

### Option B: Direct Access Token (Development/Testing)

For development purposes, you can get a direct access token:

1. Go to your LinkedIn App in the Developer Console
2. Navigate to "Auth" tab
3. Use the "Generate Access Token" tool
4. Copy the generated token to your `.env` file

**Note:** Direct access tokens expire quickly and are not suitable for production use.

## Step 6: Test API Connection

You can test your LinkedIn API connection using the service:

```php
$linkedinService = new \App\Services\LinkedinService();
$status = $linkedinService->getApiStatus();
$isConnected = $linkedinService->testApiConnection();

dd($status, $isConnected);
```

## Step 7: API Usage Examples

### Fetch Current User's Profile Information

```php
use App\Services\LinkedinService;

$linkedinService = new LinkedinService();
$contactInfo = $linkedinService->fetchContactInfo('current_user');

if ($contactInfo) {
    // Available data: name, profile_id, profile_picture, email, company, position
    $name = $contactInfo['name'];
    $email = $contactInfo['email'] ?? 'Not available';
    $company = $contactInfo['company'] ?? 'Not available';
}
```

### Check API Status

```php
$status = $linkedinService->getApiStatus();
// Returns: ['configured' => true, 'has_api_key' => true, 'has_api_secret' => true, 'has_access_token' => true, 'token_expired' => false, 'token_source' => 'session', 'can_fetch_data' => true]
```

## Current API Endpoints Used

The service uses the following LinkedIn API endpoints:

- **Profile Information:** `GET /v2/me` (current user only)
- **Email Address:** `GET /v2/emailAddress?q=members&projection=(elements*(handle~))`
- **Positions:** `GET /v2/me?projection=(positions)`

## Rate Limits

LinkedIn API has rate limits:
- **Profile API:** 100 requests per day per app
- **Email API:** 100 requests per day per app
- **Company API:** 100 requests per day per app

## Important Notes About Current Limitations

### 1. **Profile Access Restriction**
- **Cannot fetch other users' profiles** from LinkedIn URLs
- **Only authenticated user's own profile** is accessible
- **Mock data generation** is used for demonstration purposes

### 2. **Data Availability**
- **Name and basic info**: Available if user grants permission
- **Email**: Available if user grants permission
- **Company/Position**: Limited to current position only
- **Phone/Address**: Not available through API

### 3. **Workaround for Contact Creation**
Since we cannot fetch other users' LinkedIn data, the system:
1. **Validates LinkedIn URLs** for format
2. **Generates realistic mock data** based on the username
3. **Provides clear messaging** about API limitations
4. **Offers manual data entry** as the primary method

## Error Handling

The service includes comprehensive error handling:

1. **API Connection Failures:** Falls back to mock data
2. **Rate Limit Exceeded:** Returns cached data if available
3. **Invalid URLs:** Provides clear error messages
4. **Authentication Failures:** Logs errors for debugging
5. **Permission Denied:** Gracefully handles missing permissions

## Caching Strategy

The service implements intelligent caching:

- **Real API Data:** Cached for 24 hours
- **Mock Data:** Cached for 1 hour
- **Cache Key:** `linkedin_profile_{username}`

## Security Considerations

1. **Never expose API credentials** in client-side code
2. **Store access tokens securely** (encrypted in database or secure session)
3. **Implement proper OAuth flow** for production applications
4. **Monitor API usage** to stay within rate limits
5. **Validate all LinkedIn URLs** before processing

## Troubleshooting

### Common Issues

1. **"Invalid access token"**
   - Check if token is expired
   - Verify token format in `.env` file
   - Ensure proper OAuth flow was followed

2. **"API rate limit exceeded"**
   - Wait for rate limit reset (24 hours)
   - Implement proper caching
   - Consider upgrading LinkedIn app tier

3. **"Profile not found"**
   - **This is expected behavior** - LinkedIn API cannot access other users' profiles
   - The system will generate mock data instead
   - Users should manually enter contact information

4. **"Authentication failed"**
   - Verify client ID and secret
   - Check redirect URI configuration
   - Ensure OAuth scopes are properly set

5. **"Permission denied"**
   - User may not have granted email permission
   - Some data may not be available
   - System will work with available data

### Debug Mode

Enable debug logging in your `.env`:

```env
LOG_LEVEL=debug
```

Check logs for detailed API request/response information.

## Production Deployment

For production deployment:

1. **Use OAuth flow** instead of direct access tokens
2. **Implement token refresh** mechanism
3. **Add monitoring** for API usage and errors
4. **Set up alerts** for rate limit approaching
5. **Implement fallback strategies** for API failures
6. **Educate users** about API limitations

## Alternative Approaches

Since LinkedIn API has limited profile access, consider:

1. **Manual Data Entry**: Primary method for contact creation
2. **CSV Import**: Bulk contact import functionality
3. **Email Integration**: Extract contact info from email signatures
4. **Business Card Scanning**: OCR-based contact extraction
5. **Social Media Integration**: Other platforms with better API access

## Support

For LinkedIn API support:
- [LinkedIn API Documentation](https://developer.linkedin.com/docs)
- [LinkedIn Developer Community](https://developer.linkedin.com/community)
- [LinkedIn API Status](https://developer.linkedin.com/status)

## Legal Compliance

Ensure compliance with:
- LinkedIn's Terms of Service
- GDPR and data privacy regulations
- Your organization's data handling policies
- User consent requirements for data collection

## Summary

**Current LinkedIn API integration provides:**
- ✅ **User authentication** via OAuth
- ✅ **Basic profile access** for authenticated users
- ✅ **Email permission** (if granted)
- ✅ **Current position** information
- ❌ **No access to other users' profiles**
- ❌ **Limited historical data**

**For contact creation, users should:**
1. **Manually enter contact information**
2. **Use LinkedIn URLs for reference** (format validation only)
3. **Understand that automatic data fetching is limited**
4. **Rely on mock data generation** for demonstration purposes
