prelude-so/laravel

Laravel integration package for prelude-so/sdk

Installs: 5

Dependents: 0

Suggesters: 0

Security: 0

Stars: 0

Watchers: 0

Forks: 0

Open Issues: 0

pkg:composer/prelude-so/laravel

1.2.0 2025-08-07 00:54 UTC

README

codecov Made with Trae

A Laravel integration package for the prelude-so/sdk, providing seamless integration of Prelude services into your Laravel applications.

Requirements

  • PHP: 8.1 or higher
  • Laravel: 9.0 or higher (supports Laravel 9, 10, and 11)
  • Composer: 2.0 or higher

Installation

You can install the package via Composer:

composer require prelude-so/laravel

Configuration

Automatic Setup

Run the install command to automatically set up the package:

php artisan prelude:install

This command will:

  • Publish the configuration file
  • Add environment variables to your .env file
  • Provide setup instructions

Manual Setup

If you prefer manual setup:

  1. Publish the configuration file:
php artisan vendor:publish --tag=prelude-config
  1. Add your Prelude API credentials to your .env file:
PRELUDE_API_KEY=your-api-key-here
PRELUDE_BASE_URL=https://api.prelude.so
PRELUDE_TIMEOUT=30
  1. Configure the package in config/prelude.php as needed.

Usage

Using the Facade

The package provides a convenient facade for accessing Prelude services:

use PreludeSo\Laravel\Facades\Prelude;

// Create a phone verification
$verification = Prelude::verification()->create('+1234567890');

// Check verification OTP
$result = Prelude::verification()->check($verificationId, '123456');

// Lookup phone number information
$lookup = Prelude::lookup()->phoneNumber('+1234567890');

// Send transactional message
$message = Prelude::transactional()->send('+1234567890', 'Your verification code is 123456');

// Process webhook data (requires SDK v1.2.1+)
$webhookData = json_decode(request()->getContent(), true);
$webhookResult = Prelude::webhook()->processWebhook($webhookData);

Dependency Injection

You can also inject the PreludeClient directly into your classes:

use PreludeSo\Sdk\PreludeClient;

class UserController extends Controller
{
    public function createVerification(Request $request, PreludeClient $prelude)
    {
        $phoneNumber = $request->input('phone_number');
        $verification = $prelude->verification()->create($phoneNumber);
        
        return response()->json([
            'verification_id' => $verification->getId(),
            'status' => $verification->getStatus()
        ]);
    }
    
    public function checkVerification(Request $request, PreludeClient $prelude)
    {
        $verificationId = $request->input('verification_id');
        $code = $request->input('code');
        
        $result = $prelude->verification()->check($verificationId, $code);
        
        return response()->json([
            'success' => $result->isSuccess(),
            'status' => $result->getStatus()->value
        ]);
    }
}

SendTransactionalRequest

For sending transactional messages with comprehensive validation:

use PreludeSo\Laravel\Http\Requests\SendTransactionalRequest;

class MessageController extends Controller
{
    public function sendTransactional(SendTransactionalRequest $request)
    {
        // All validation is handled automatically
        $to = $request->validated('to');
        $templateId = $request->validated('template_id');
        $options = $request->validated('options');
        $metadata = $request->validated('metadata');
        
        // Create options object for SDK if provided
        $optionsObject = null;
        if ($options) {
            $optionsObject = new \PreludeSo\Sdk\Options($options);
        }
        
        // Send transactional message using the SDK
        $result = Prelude::transactional()->send($to, $templateId, $optionsObject);
        
        return response()->json([
            'message_id' => $result->getId(),
            'status' => $result->getStatus(),
            'sent_at' => $result->getSentAt(),
            'recipient' => $to,
            'template_id' => $templateId,
        ]);
    }
}

Complete Examples

For complete working examples, see the examples/UserController.php file which demonstrates:

  • Phone verification creation and checking
  • Phone number lookup
  • Transactional messaging
  • Error handling
  • Both Facade and dependency injection patterns

Using the Trait

For models or other classes that frequently interact with Prelude, use the provided trait:

use PreludeSo\Laravel\Traits\InteractsWithPrelude;

class VerificationService
{
    use InteractsWithPrelude;
    
    public function createVerification(string $phoneNumber)
    {
        return $this->createVerification($phoneNumber);
    }
    
    public function checkVerification(string $verificationId, string $code)
    {
        return $this->checkVerification($verificationId, $code);
    }
    
    public function lookupPhone(string $phoneNumber)
    {
        return $this->lookupPhoneNumber($phoneNumber);
    }
    
    public function sendMessage(string $phoneNumber, string $message)
    {
        return $this->sendTransactionalMessage($phoneNumber, $message);
    }
}

Form Requests with Prelude Integration

The package provides Form Request classes that extend Laravel's FormRequest with comprehensive validation rules for Prelude SDK parameters:

CreateVerificationRequest

For creating verifications with full parameter validation:

use PreludeSo\Laravel\Http\Requests\CreateVerificationRequest;

// Use the base class directly with all validation rules
$request = new CreateVerificationRequest();

// Or extend it for custom requirements
class CreateOtpRequest extends CreateVerificationRequest
{
    public function rules(): array
    {
        // Option 1: Use all parent rules
        return parent::rules();
        
        // Option 2: Override with custom rules
        return [
            'target.type' => 'required|string|in:phone_number',
            'target.value' => 'required|string|regex:/^\+?[1-9]\d{1,14}$/',
            'signals' => 'nullable|array',
            'options' => 'nullable|array',
            'metadata' => 'nullable|array',
            'dispatch_id' => 'nullable|string',
        ];
    }
}

CheckVerificationRequest

For checking verification codes with target and code validation:

use PreludeSo\Laravel\Http\Requests\CheckVerificationRequest;

class VerificationController extends Controller
{
    public function checkVerification(CheckVerificationRequest $request)
    {
        // All validation is handled automatically
        $target = $request->validated('target');
        $code = $request->validated('code');
        
        // Create target object for SDK
        $targetObject = new \PreludeSo\Sdk\Target(
            $target['value'],
            $target['type']
        );
        
        // Check verification using the SDK
        $result = Prelude::verification()->check($targetObject, $code);
        
        return response()->json([
            'success' => $result->isSuccess(),
            'status' => $result->getStatus()->value
        ]);
    }
}

PredictOutcomeRequest

For predicting outcomes with comprehensive validation:

use PreludeSo\Laravel\Http\Requests\PredictOutcomeRequest;

class PredictionController extends Controller
{
    public function predictOutcome(PredictOutcomeRequest $request)
    {
        // All validation is handled automatically
        $target = $request->validated('target');
        $signals = $request->validated('signals');
        $metadata = $request->validated('metadata');
        $dispatchId = $request->validated('dispatch_id');
        
        // Create objects for SDK
        $targetObject = new \PreludeSo\Sdk\Target(
            $target['value'],
            $target['type']
        );
        
        $signalsObject = new \PreludeSo\Sdk\Signals($signals);
        
        $metadataObject = null;
        if ($metadata) {
            $metadataObject = new \PreludeSo\Sdk\Metadata($metadata);
        }
        
        // Predict outcome using the SDK
        $result = Prelude::predictOutcome($targetObject, $signalsObject, $dispatchId, $metadataObject);
        
        return response()->json([
            'prediction_id' => $result->getId(),
            'outcome' => $result->getOutcome(),
            'confidence' => $result->getConfidence()
        ]);
    }
}

LookupRequest

For looking up phone number information with comprehensive validation:

use PreludeSo\Laravel\Http\Requests\LookupRequest;

class LookupController extends Controller
{
    public function lookupPhoneNumber(LookupRequest $request)
    {
        // All validation is handled automatically
        $phoneNumber = $request->validated('phone_number');
        $type = $request->validated('type', []);
        
        // Lookup phone number using the SDK
        $result = Prelude::lookup()->lookup($phoneNumber, $type);
        
        return response()->json([
            'phone_number' => $result->getPhoneNumber(),
            'country_code' => $result->getCountryCode(),
            'line_type' => $result->getLineType()?->value,
            'caller_name' => $result->getCallerName(),
            'flags' => array_map(fn($flag) => $flag->value, $result->getFlags()),
            'network_info' => [
                'carrier_name' => $result->getNetworkInfo()->getCarrierName(),
                'mcc' => $result->getNetworkInfo()->getMcc(),
                'mnc' => $result->getNetworkInfo()->getMnc(),
            ],
            'original_network_info' => [
                'carrier_name' => $result->getOriginalNetworkInfo()->getCarrierName(),
                'mcc' => $result->getOriginalNetworkInfo()->getMcc(),
                'mnc' => $result->getOriginalNetworkInfo()->getMnc(),
            ],
        ]);
    }
}

SendFeedbackRequest

For sending feedback about verifications with comprehensive validation:

use PreludeSo\Laravel\Http\Requests\SendFeedbackRequest;

class FeedbackController extends Controller
{
    public function sendFeedback(SendFeedbackRequest $request)
    {
        // All validation is handled automatically
        $feedbacks = $request->validated('feedbacks');
        
        // Create feedback objects for SDK
        $feedbackObjects = [];
        foreach ($feedbacks as $feedback) {
            // Create target object
            $targetObject = new \PreludeSo\Sdk\ValueObjects\Shared\Target(
                $feedback['target']['value'],
                $feedback['target']['type']
            );
            
            // Create signals object if provided
            $signalsObject = null;
            if (!empty($feedback['signals'])) {
                $signalsObject = new \PreludeSo\Sdk\ValueObjects\Shared\Signals($feedback['signals']);
            }
            
            // Create metadata object if provided
            $metadataObject = null;
            if (!empty($feedback['metadata'])) {
                $metadataObject = new \PreludeSo\Sdk\ValueObjects\Shared\Metadata($feedback['metadata']);
            }
            
            $feedbackObjects[] = new \PreludeSo\Sdk\ValueObjects\Watch\Feedback(
                $targetObject,
                $feedback['type'],
                $signalsObject,
                $feedback['dispatch_id'] ?? '',
                $metadataObject
            );
        }
        
        // Send feedback using the SDK
        $result = Prelude::sendFeedback($feedbackObjects);
        
        return response()->json([
            'success' => $result->isSuccess(),
            'processed_count' => count($feedbackObjects)
        ]);
    }
}

Supported Validation Parameters

CreateVerificationRequest includes validation rules for all SDK parameters:

  • Target (required): Phone number or email validation

    • target.type: Must be 'phone_number' or 'email_address'
    • target.value: Validated based on the target type
  • Signals (optional): Browser/device information

    • signals.ip_address: Valid IP address
    • signals.user_agent: Browser user agent string
    • signals.device_fingerprint: Device identification
    • And more browser-related fields
  • Options (optional): Verification configuration

    • options.template: Custom message template
    • options.expiry_minutes: OTP expiration time (1-60 minutes)
    • options.code_length: OTP length (4-10 digits)
    • options.channel: Delivery method (sms, voice, email, whatsapp)
    • And more configuration options
  • Metadata (optional): Custom tracking data

    • metadata.user_id: Your internal user ID
    • metadata.source: Request source identifier
    • metadata.campaign_id: Marketing campaign tracking
    • metadata.custom_fields: Additional custom data
  • Dispatch ID (optional): Frontend SDK integration

    • dispatch_id: ID from Prelude's JavaScript SDK for enhanced fraud detection

CheckVerificationRequest includes validation rules for verification checking:

  • Target (required): Phone number or email validation

    • target.type: Must be 'phone_number' or 'email_address'
    • target.value: Validated based on the target type
  • Code (required): Verification code validation

    • code: String with length between 4-10 characters

PredictOutcomeRequest includes validation rules for outcome prediction:

  • Target (required): Phone number or email validation

    • target.type: Must be 'phone_number' or 'email_address'
    • target.value: Validated based on the target type
  • Signals (required): Browser/device information for fraud detection

    • signals.ip_address: Valid IP address
    • signals.user_agent: Browser user agent string
    • signals.device_fingerprint: Device identification
    • signals.browser_plugins: Array of browser plugins
    • signals.screen_resolution: Screen resolution information
    • signals.timezone: User timezone
    • signals.language: User language preference
    • signals.session_id: Session identifier
    • signals.timestamp: Request timestamp
  • Metadata (optional): Custom tracking data

    • metadata.user_id: Your internal user ID
    • metadata.source: Request source identifier
    • metadata.campaign_id: Marketing campaign tracking
    • metadata.reference_id: Reference identifier
    • metadata.custom_fields: Additional custom data
  • Dispatch ID (optional): Frontend SDK integration

    • dispatch_id: ID from Prelude's JavaScript SDK for enhanced fraud detection

LookupRequest includes validation rules for phone number lookup:

  • Phone Number (required): Phone number in E.164 format

    • phone_number: Must be in E.164 format (e.g., +1234567890)
    • Validates international format with country code
    • Length between 7-15 digits (including country code)
  • Type (optional): Array of lookup features to retrieve

  • type: Optional array of lookup feature strings

  • type.*: Each type must be a valid LookupType enum value

  • Available lookup types (defined in LookupType enum):

    • cnam: Caller Name (CNAM) information
    • network_info: Network and carrier information
    • fraud: Fraud detection and risk analysis

SendFeedbackRequest includes validation rules for feedback submission:

  • Feedbacks (required): Array of feedback objects
    • feedbacks: Required array with minimum 1 item
    • feedbacks.*.target: Required target object with phone number or email validation
      • feedbacks.*.target.type: Must be 'phone_number' or 'email_address'
      • feedbacks.*.target.value: Validated based on the target type
    • feedbacks.*.type: Required string identifier for the feedback type (max 100 characters)
    • feedbacks.*.signals: Optional browser/device information for fraud detection
      • feedbacks.*.signals.ip_address: Valid IP address
      • feedbacks.*.signals.user_agent: Browser user agent string
      • feedbacks.*.signals.device_fingerprint: Device identification
      • And more browser-related fields
    • feedbacks.*.metadata: Optional custom tracking data
      • feedbacks.*.metadata.user_id: Your internal user ID
      • feedbacks.*.metadata.source: Request source identifier
      • feedbacks.*.metadata.campaign_id: Marketing campaign tracking
      • feedbacks.*.metadata.reference_id: Reference identifier
      • feedbacks.*.metadata.custom_fields: Additional custom data
    • feedbacks.*.dispatch_id: Optional ID from Prelude's JavaScript SDK for enhanced fraud detection

SendTransactionalRequest includes validation rules for transactional messaging:

  • To (required): Recipient validation

    • to: Valid phone number (international format, 7-15 digits) or email address
  • Template ID (required): Message template

    • template_id: String identifier for the message template (max 255 characters)
  • Options (optional): Message configuration

    • options.from: Sender identifier
    • options.channel: Delivery method (sms, email, whatsapp, voice)
    • options.priority: Message priority (low, normal, high)
    • options.scheduled_at: Schedule message for future delivery
    • options.callback_url: URL for delivery status callbacks
    • options.webhook_url: URL for webhook notifications
    • options.variables: Template variables for personalization
    • options.attachments: File attachments (URLs)
    • options.reply_to: Reply-to email address
    • options.subject: Email subject line
    • options.tags: Message tags for categorization
  • Metadata (optional): Custom tracking data

    • metadata.user_id: Your internal user ID
    • metadata.source: Request source identifier
    • metadata.campaign_id: Marketing campaign tracking
    • metadata.reference_id: External reference ID
    • metadata.custom_fields: Additional custom data

Configuration Options

The configuration file (config/prelude.php) supports the following options:

  • api_key: Your Prelude API key

  • base_url: The base URL for the Prelude API

  • timeout: Request timeout in seconds

  • defaults: Default options for SDK operations

Development Environment

Docker Setup (Recommended)

For a consistent development environment, use Docker:

# Build and start the environment
make build
make up

# Install dependencies
make install

# Run tests
make test

See DOCKER.md for detailed Docker setup instructions.

Local Setup

Alternatively, set up locally with PHP 8.1+ and Composer:

composer install

Testing

This package uses Pest for testing.

With Docker:

make test                # Run tests
make test-coverage      # Run with coverage
make test-watch         # Run in watch mode

Local Testing:

composer test           # Run tests
composer test-coverage  # Run with coverage

License

The MIT License (MIT). Please see License File for more information.