PHP code example of andydefer / autotext-sdk

1. Go to this page and download the library: Download andydefer/autotext-sdk library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

andydefer / autotext-sdk example snippets


// firebase-config.php
return [
    'project_id' => 'votre-project-firebase',
    'client_email' => '[email protected]',
    'private_key' => '-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n',
    'token_uri' => 'https://oauth2.googleapis.com/token',
];

use Andydefer\AutotextSdk\Core\NotificationFactory;
use Andydefer\AutotextSdk\Services\GuzzleHttpClient;
use Andydefer\AutotextSdk\Services\FirebaseAuthProvider;
use Andydefer\AutotextSdk\Services\FcmPayloadBuilder;

$config = 

use Andydefer\AutotextSdk\Dtos\{TextoDto, DeviceDto};
use Andydefer\AutotextSdk\Enums\{TextoStatus, DeviceStatus};

// 1. Préparer le texto
$texto = TextoDto::fromArray([
    'id' => 123,
    'uuid' => '550e8400-e29b-41d4-a716-446655440000',
    'message' => 'Votre code de vérification est: 123456',
    'phone_number' => '+33612345678',
    'status' => TextoStatus::PENDING->value,
    'device_id' => 1,
    'retry_count' => 0,
    'last_attempt_at' => null,
    'created_at' => date('c'),
    'updated_at' => date('c'),
]);

// 2. Préparer l'appareil cible
$device = DeviceDto::fromArray([
    'id' => 'device-android-001',
    'api_key' => 'ak-123456789',
    'status' => DeviceStatus::ONLINE->value,
    'fcm_id' => 'fcm-token-actuel-123',
    'last_connected_at' => date('c', strtotime('-5 minutes')),
    'last_action_at' => date('c', strtotime('-2 minutes')),
    'created_at' => date('c', strtotime('-30 days')),
    'updated_at' => date('c'),
    'is_recently_connected' => true,
    'is_recently_active' => true,
    'success_count' => 150,
    'failed_count' => 3,
    'success_rate' => 98,
]);

// 3. Obtenir le dispatcher
$dispatcher = $factory->makeDispatcher();

// 4. Envoyer le SMS
try {
    $result = $dispatcher->dispatch($texto, $device);

    if ($result) {
        echo "✅ SMS envoyé avec succès à {$texto->phoneNumber}";
    } else {
        echo "❌ Échec de l'envoi du SMS";
    }
} catch (InvalidArgumentException $e) {
    echo "⚠️ Erreur de validation: " . $e->getMessage();
} catch (Exception $e) {
    echo "🔥 Erreur système: " . $e->getMessage();
}

// Récupérer des services individuels
$firebaseService = $factory->makeFirebaseService();
$smsSender = $factory->makeSmsSender();

// Vérifier la connectivité d'un appareil
try {
    $pingResponse = $firebaseService->pingDevice($device->fcmId);

    if ($pingResponse->isSuccess()) {
        echo "📱 Appareil {$device->id} est en ligne";
    }
} catch (Exception $e) {
    echo "📵 Appareil {$device->id} hors ligne";
}

// Envoyer un message informatif
use Andydefer\AutotextSdk\Dtos\FcmMessageDto;
use Andydefer\AutotextSdk\Enums\FcmActionType;

$infoMessage = new FcmMessageDto(
    actionType: FcmActionType::INFO,
    message: 'Mise à jour système prévue à 02:00',
);

$response = $firebaseService->send($infoMessage, $device->fcmId);

// Tous les DTOs suivent le même pattern:
// - Constructeur avec propriétés publiques readonly
// - Méthodes fromArray() et toArray() pour la sérialisation
// - Typage strict avec Enums

$texto = new TextoDto(
    id: 123,
    uuid: '...',
    message: '...',
    phoneNumber: '+336...',
    status: TextoStatus::PENDING, // Enum
    // ...
);

// Conversion depuis un tableau (utile pour les APIs)
$texto = TextoDto::fromArray($_POST['texto']);

// Conversion vers tableau (pour le stockage/API)
$data = $texto->toArray();

// HttpClientInterface - Interchangeable HTTP client
interface HttpClientInterface {
    public function post(string $url, array $options): HttpResponseDto;
}

// SmsSenderInterface - Abstraction pour l'envoi de SMS
interface SmsSenderInterface {
    public function send(TextoDto $texto, string $deviceFcmToken): bool;
}

// Implémentation personnalisée possible:
class CustomHttpClient implements HttpClientInterface {
    // Votre logique HTTP
}

$dispatcher = $factory->makeDispatcher();

// Validation automatique:
// - Vérifie que l'appareil est ONLINE
// - Vérifie la présence du token FCM
// - Gère les exceptions de validation

try {
    $dispatcher->dispatch($texto, $device);
} catch (InvalidArgumentException $e) {
    // Gérer les erreurs de validation
}

$firebaseService = $factory->makeFirebaseService();

// Gestion automatique des tokens JWT
// Renouvellement transparent
// Configuration centralisée

// Envoyer un SMS
$response = $firebaseService->sendSmsToDevice($fcmToken, $texto);

// Envoyer un ping
$response = $firebaseService->pingDevice($fcmToken);

// Envoyer un message custom
$response = $firebaseService->send($fcmMessage, $fcmToken);

// Configure automatiquement:
// - Priorité Android: 'high'
// - Configuration APNs pour iOS
// - Serialisation des données
// - Headers appropriés

$payload = $payloadBuilder->build($fcmMessage);
// {
//   "message": {
//     "token": "fcm-token",
//     "data": { ... },
//     "android": {"priority": "high"},
//     "apns": { ... }
//   }
// }

use Andydefer\AutotextSdk\Enums\DeviceStatus;

// Vérifications type-safe
if ($device->status === DeviceStatus::ONLINE) {
    // Appareil disponible
}

if ($device->status === DeviceStatus::OFFLINE) {
    // Mettre en file d'attente
}

if ($device->status === DeviceStatus::ERROR) {
    // Journaliser l'erreur
}

use Andydefer\AutotextSdk\Enums\TextoStatus;

// Workflow complet d'un SMS
$texto->status = TextoStatus::PENDING;   // Initial
$texto->status = TextoStatus::SUCCESS;   // Après envoi réussi
$texto->status = TextoStatus::FAILED;    // Après échec

// Utilisation dans des conditions
switch ($texto->status) {
    case TextoStatus::PENDING:
        // Traitement en attente
        break;
    case TextoStatus::SUCCESS:
        // Confirmer l'envoi
        break;
    case TextoStatus::FAILED:
        // Gérer la réessai
        break;
}

// Service Provider
class AutotextServiceProvider extends ServiceProvider
{
    public function register()
    {
        $this->app->singleton(NotificationFactory::class, function ($app) {
            return new NotificationFactory(
                new GuzzleHttpClient(),
                new FirebaseAuthProvider(),
                new FcmPayloadBuilder(),
                config('services.firebase')
            );
        });
    }
}

// Utilisation dans un Controller
class SmsController extends Controller
{
    public function send(SendSmsRequest $request, NotificationFactory $factory)
    {
        $texto = TextoDto::fromArray($request->validated());
        $device = DeviceDto::fromArray($request->device_data);

        return $factory->makeDispatcher()->dispatch($texto, $device);
    }
}

use PHPUnit\Framework\TestCase;
use Andydefer\AutotextSdk\Dtos\TextoDto;
use Andydefer\AutotextSdk\Enums\TextoStatus;

class TextoDtoTest extends TestCase
{
    public function test_can_create_texto_dto_from_array()
    {
        $data = [
            'id' => 1,
            'uuid' => 'test-uuid',
            'message' => 'Test message',
            'phone_number' => '+33612345678',
            'status' => 'pending',
            'device_id' => 1,
            'retry_count' => 0,
            'last_attempt_at' => null,
            'created_at' => '2025-12-10T10:00:00+00:00',
            'updated_at' => '2025-12-10T10:00:00+00:00',
        ];

        $texto = TextoDto::fromArray($data);

        $this->assertEquals(1, $texto->id);
        $this->assertEquals('Test message', $texto->message);
        $this->assertEquals(TextoStatus::PENDING, $texto->status);
    }
}

   // Vérifier le token avant utilisation
   if (empty($device->fcmId)) {
       throw new \RuntimeException('Token FCM manquant');
   }
   

   // Vérifier les credentials
   $     if (empty($config[$key])) {
           throw new \InvalidArgumentException("Missing Firebase config: $key");
       }
   }
   

   // Vérifier le statut avant envoi
   if ($device->status !== DeviceStatus::ONLINE) {
       // Mettre en file d'attente ou journaliser
       $this->logger->warning("Device {$device->id} is offline");
   }
   

try {
    $result = $dispatcher->dispatch($texto, $device);

    if (!$result) {
        // Incrémenter le compteur de réessais
        $texto->retryCount++;
        $texto->lastAttemptAt = date('c');

        // Journaliser l'échec
        $this->logger->error('SMS dispatch failed', [
            'texto_id' => $texto->id,
            'device_id' => $device->id,
        ]);
    }
} catch (InvalidArgumentException $e) {
    // Erreur de validation - ne pas réessayer
    $this->logger->critical($e->getMessage());
} catch (Exception $e) {
    // Erreur système - réessayer plus tard
    $this->retryQueue->push($texto);
}

// Suivre les performances
$startTime = microtime(true);
$result = $dispatcher->dispatch($texto, $device);
$duration = microtime(true) - $startTime;

// Envoyer des métriques
$this->metrics->increment('sms.sent.total');
$this->metrics->timing('sms.dispatch.duration', $duration);

if ($result) {
    $this->metrics->increment('sms.sent.success');
    $device->successCount++;
} else {
    $this->metrics->increment('sms.sent.failed');
    $device->failedCount++;
}

// Calculer le taux de réussite
if (($device->successCount + $device->failedCount) > 0) {
    $device->successRate = (int) (
        ($device->successCount / ($device->successCount + $device->failedCount)) * 100
    );
}

tests/
├── Unit/
│   ├── Dtos/
│   │   ├── TextoDtoTest.php
│   │   ├── DeviceDtoTest.php
│   │   └── FcmMessageDtoTest.php
│   ├── Services/
│   │   ├── DeviceSmsDispatcherTest.php
│   │   └── FirebaseServiceTest.php
│   └── Enums/
│       └── DeviceStatusTest.php
└── Feature/
    ├── DeviceSmsDispatcherFeatureTest.php
    └── FirebaseIntegrationTest.php