PHPackages                             andydefer/autotext-sdk - 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. andydefer/autotext-sdk

ActiveLibrary

andydefer/autotext-sdk
======================

1.0.0(4mo ago)023MITPHP

Since Dec 10Pushed 4mo agoCompare

[ Source](https://github.com/andydefer/autotext-sdk)[ Packagist](https://packagist.org/packages/andydefer/autotext-sdk)[ RSS](/packages/andydefer-autotext-sdk/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependencies (3)Versions (8)Used By (0)

AutoText SDK PHP
================

[](#autotext-sdk-php)

Une bibliothèque PHP robuste et type-safe pour envoyer des SMS via Firebase Cloud Messaging (FCM) vers des appareils Android. Architecture orientée DTO avec injection de dépendances.

🚀 Caractéristiques principales
------------------------------

[](#-caractéristiques-principales)

- ✅ **Envoi de SMS via FCM** - Communication directe avec les appareils Android
- ✅ **Architecture SOLID** - Interfaces, DTOs immutables, injection de dépendances
- ✅ **Type-safe avec Enums PHP** - Validation au niveau du langage
- ✅ **Factory Pattern** - Instanciation centralisée et configurable
- ✅ **HTTP Client interchangeable** - Support Guzzle par défaut, extensible
- ✅ **Gestion complète d'authentification Firebase** - Tokens JWT automatiques
- ✅ **Compatibilité PHP 8.1+** - Utilise les dernières fonctionnalités PHP

📦 Installation
--------------

[](#-installation)

```
composer require andydefer/autotext-sdk
```

🎯 Cas d'utilisation
-------------------

[](#-cas-dutilisation)

- Systèmes de notification SMS en temps réel
- Applications de marketing par SMS
- Systèmes d'alerte et de notification
- Intégration avec des appareils Android distants
- Microservices de messagerie

⚙️ Configuration minimale
-------------------------

[](#️-configuration-minimale)

### 1. Obtenir les credentials Firebase

[](#1-obtenir-les-credentials-firebase)

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

### 2. Initialiser le SDK

[](#2-initialiser-le-sdk)

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

$config = require 'firebase-config.php';

$factory = new NotificationFactory(
    new GuzzleHttpClient(),
    new FirebaseAuthProvider(),
    new FcmPayloadBuilder(),
    $config
);
```

📖 Guide d'utilisation
---------------------

[](#-guide-dutilisation)

### Envoyer un SMS en 4 étapes

[](#envoyer-un-sms-en-4-étapes)

```
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();
}
```

### Utilisation avancée

[](#utilisation-avancée)

```
// 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);
```

🏗 Architecture
--------------

[](#-architecture)

### Structure des DTOs (Data Transfer Objects)

[](#structure-des-dtos-data-transfer-objects)

```
// 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();
```

### Interfaces et contrats

[](#interfaces-et-contrats)

```
// 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
}
```

🔧 Services disponibles
----------------------

[](#-services-disponibles)

### `DeviceSmsDispatcher`

[](#devicesmsdispatcher)

Gestionnaire principal d'envoi de SMS avec validation.

```
$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`

[](#firebaseservice)

Service Firebase complet avec gestion de tokens.

```
$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);
```

### `FcmPayloadBuilder`

[](#fcmpayloadbuilder)

Constructeur de payloads FCM optimisés.

```
// 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": { ... }
//   }
// }
```

📊 Gestion des états
-------------------

[](#-gestion-des-états)

### Statuts d'appareil (`DeviceStatus`)

[](#statuts-dappareil-devicestatus)

```
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
}
```

### Statuts de texto (`TextoStatus`)

[](#statuts-de-texto-textostatus)

```
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;
}
```

🛠 Intégration avec différents frameworks
----------------------------------------

[](#-intégration-avec-différents-frameworks)

### Laravel

[](#laravel)

```
// 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);
    }
}
```

### Symfony

[](#symfony)

```
# services.yaml
services:
    Andydefer\AutotextSdk\Services\GuzzleHttpClient: ~
    Andydefer\AutotextSdk\Services\FirebaseAuthProvider: ~
    Andydefer\AutotextSdk\Services\FcmPayloadBuilder: ~

    Andydefer\AutotextSdk\Core\NotificationFactory:
        arguments:
            $httpClient: '@Andydefer\AutotextSdk\Services\GuzzleHttpClient'
            $authProvider: '@Andydefer\AutotextSdk\Services\FirebaseAuthProvider'
            $payloadBuilder: '@Andydefer\AutotextSdk\Services\FcmPayloadBuilder'
            $config: '%env(json:FIREBASE_CONFIG)%'
```

🧪 Tests et qualité
------------------

[](#-tests-et-qualité)

### Structure de test recommandée

[](#structure-de-test-recommandée)

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

```

### Exemple de test unitaire

[](#exemple-de-test-unitaire)

```
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);
    }
}
```

🔍 Dépannage
-----------

[](#-dépannage)

### Problèmes courants

[](#problèmes-courants)

1. **Token FCM invalide**

    ```
    // Vérifier le token avant utilisation
    if (empty($device->fcmId)) {
        throw new \RuntimeException('Token FCM manquant');
    }
    ```
2. **Erreur d'authentification Firebase**

    ```
    // Vérifier les credentials
    $required = ['project_id', 'client_email', 'private_key'];
    foreach ($required as $key) {
        if (empty($config[$key])) {
            throw new \InvalidArgumentException("Missing Firebase config: $key");
        }
    }
    ```
3. **Appareil hors ligne**

    ```
    // 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");
    }
    ```

📈 Bonnes pratiques
------------------

[](#-bonnes-pratiques)

### 1. Gestion des erreurs

[](#1-gestion-des-erreurs)

```
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);
}
```

### 2. Monitoring et métriques

[](#2-monitoring-et-métriques)

```
// 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
    );
}
```

🔮 Roadmap
---------

[](#-roadmap)

- Support des notifications push iOS
- Système de file d'attente intégré
- Support WebSocket pour les mises à jour en temps réel
- Dashboard de monitoring
- SDK JavaScript/TypeScript complémentaire
- Plugin Laravel/Symfony officiel

🤝 Contribution
--------------

[](#-contribution)

Les contributions sont les bienvenues ! Voici comment participer :

1. **Signaler un bug** - [Ouvrir une issue](https://github.com/andydefer/autotext-sdk/issues)
2. **Proposer une fonctionnalité** - Discuter dans les issues
3. **Soumettre une PR** - Suivre les standards de code
4. **Améliorer la documentation** - Corrections et ajouts

### Standards de code

[](#standards-de-code)

- Suivre PSR-12
- Ajouter des tests pour les nouvelles fonctionnalités
- Documenter les changements breaking
- Maintenir la rétrocompatibilité

📄 Licence
---------

[](#-licence)

MIT License - Voir le fichier [LICENSE](LICENSE) pour plus de détails.

📞 Support
---------

[](#-support)

- **Documentation** : [github.com/andydefer/autotext-sdk](https://github.com/andydefer/autotext-sdk)
- **Issues** : [Signaler un problème](https://github.com/andydefer/autotext-sdk/issues)
- **Email** :

---

**Note importante** : Ce SDK est conçu pour les environnements de production. Assurez-vous de :

- Tester en environnement de staging
- Mettre en place un système de monitoring
- Configurer les alertes d'erreur
- Sauvegarder régulièrement les tokens FCM
- Surveiller les quotas Firebase

📚 Ressources supplémentaires
----------------------------

[](#-ressources-supplémentaires)

- [Documentation Firebase Cloud Messaging](https://firebase.google.com/docs/cloud-messaging)
- [Guide des tokens FCM](https://firebase.google.com/docs/cloud-messaging/manage-tokens)
- [Meilleures pratiques FCM](https://firebase.google.com/docs/cloud-messaging/android/client)
- [Exemples d'implémentation](https://github.com/firebase/quickstart-android/tree/master/messaging)

**Version minimum** : PHP 8.1 **Dépendances** : GuzzleHTTP 7.0+ **License** : MIT **Mainteneur** : Andy Kani

###  Health Score

33

—

LowBetter than 75% of packages

Maintenance73

Regular maintenance activity

Popularity7

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity39

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

7

Last Release

149d ago

Major Versions

0.4.0 → 1.0.02025-12-11

### Community

Maintainers

![](https://www.gravatar.com/avatar/2170ec3fbad9eb4b002661ab4f58b1cc374eae4293b92904c6a74bc2818bd570?d=identicon)[andydefer](/maintainers/andydefer)

---

Top Contributors

[![andydefer](https://avatars.githubusercontent.com/u/124321745?v=4)](https://github.com/andydefer "andydefer (9 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/andydefer-autotext-sdk/health.svg)

```
[![Health](https://phpackages.com/badges/andydefer-autotext-sdk/health.svg)](https://phpackages.com/packages/andydefer-autotext-sdk)
```

###  Alternatives

[neuron-core/neuron-ai

The PHP Agentic Framework.

1.8k245.3k20](/packages/neuron-core-neuron-ai)[tencentcloud/tencentcloud-sdk-php

TencentCloudApi php sdk

3731.2M42](/packages/tencentcloud-tencentcloud-sdk-php)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
