alchemistsoft/textmagic-api-bundle
Install the Bundle
Add the bundle to your composer.json:
composer require alchemistsoft/textmagic-api-bundle
Enable it in config/bundles.php:
return [
// ...
AlchemistSoft\TextMagicApiBundle\AlchemistSoftTextMagicApiBundle::class => ['all' => true],
];
Configure the Bundle Publish the default configuration:
php bin/console config:dump-reference AlchemistSoftTextMagicApiBundle
Update config/packages/alchemistsoft_textmagic_api.yaml with your TextMagic API credentials (username, password, and sender ID):
alchemistsoft_textmagic_api:
username: 'your_username'
password: 'your_password'
sender_id: 'YourSender'
First Use Case: Send an SMS
Inject the TextMagicApi service into a controller or command:
use AlchemistSoft\TextMagicApiBundle\Service\TextMagicApi;
class SendSmsController extends AbstractController
{
public function sendSms(TextMagicApi $textMagicApi)
{
$response = $textMagicApi->sendSms(
'RecipientPhoneNumber',
'Hello from Laravel!'
);
return $this->json($response);
}
}
Sending SMS
Use the sendSms() method for basic SMS delivery:
$textMagicApi->sendSms('+1234567890', 'Your message here');
Bulk SMS Send to multiple recipients via an array:
$recipients = ['+1234567890', '+1987654321'];
$textMagicApi->sendBulkSms($recipients, 'Bulk message');
SMS Templates Predefined templates (if configured in TextMagic):
$textMagicApi->sendSmsWithTemplate(
'RecipientPhone',
'template_id',
['var1' => 'value1'] // Template variables
);
Asynchronous Processing Use Symfony’s Messenger component to queue SMS jobs (recommended for high volumes):
// In a command or event listener
$this->messageBus->dispatch(new SendSmsMessage(
'phone_number',
'message',
$textMagicApi
));
Event Listeners
Hook into SMS delivery events (e.g., SmsSentEvent) for logging or retries:
// config/services.yaml
services:
App\EventListener\SmsListener:
tags:
- { name: 'kernel.event_listener', event: 'textmagic.sms.sent', method: 'onSmsSent' }
Validation
Validate phone numbers before sending (use libphonenumber or a custom validator):
if (!$phoneNumberValidator->isValid($phone)) {
throw new \InvalidArgumentException('Invalid phone number');
}
Error Handling
Catch TextMagicApiException for API failures:
try {
$textMagicApi->sendSms($phone, $message);
} catch (TextMagicApiException $e) {
$this->logger->error('SMS failed: ' . $e->getMessage());
// Retry logic or notify admin
}
Testing
Use a mock service in tests (override the bundle’s service via config/test/services.yaml):
services:
AlchemistSoft\TextMagicApiBundle\Service\TextMagicApi: '@App\Service\MockTextMagicApi'
Rate Limits TextMagic enforces request limits (e.g., 1 SMS/sec for free tier). Implement exponential backoff in retries:
$attempts = 0;
while ($attempts < 3) {
try {
$textMagicApi->sendSms($phone, $message);
break;
} catch (RateLimitExceededException $e) {
sleep(2 ** $attempts); // Exponential delay
$attempts++;
}
}
Character Limits SMS messages are limited to 160 characters (70 for Unicode). Truncate long messages:
$message = Str::limit($longMessage, 160);
Phone Number Formatting
TextMagic expects E.164 format (+countrycode...). Sanitize inputs:
$phone = preg_replace('/[^0-9+]/', '', $rawPhone);
Configuration Overrides
Avoid hardcoding credentials. Use environment variables (%env()) in config/packages/alchemistsoft_textmagic_api.yaml:
username: '%env(TEXTMAGIC_USERNAME)%'
Enable API Logging
Set debug: true in config to log raw API responses:
alchemistsoft_textmagic_api:
debug: true
Check HTTP Status Codes
TextMagic returns HTTP 200 for success but may include errors in the response body. Parse JSON:
$response = $textMagicApi->sendSms($phone, $message);
if ($response['status'] !== 'success') {
throw new \RuntimeException($response['error']);
}
Common Errors
401 Unauthorized: Invalid username/password.400 Bad Request: Malformed phone number or message.429 Too Many Requests: Hit rate limits.Custom Response Handling
Extend the TextMagicApi service to add domain-specific logic:
class CustomTextMagicApi extends TextMagicApi
{
public function sendPromoSms($phone, $product)
{
$message = "Promo: $product is on sale!";
return parent::sendSms($phone, $message);
}
}
Register it as a replacement in services.yaml:
services:
AlchemistSoft\TextMagicApiBundle\Service\TextMagicApi: '@App\Service\CustomTextMagicApi'
Add New Endpoints The bundle wraps the TextMagic PHP SDK. Extend it to support unsupported API methods:
// In a custom service
public function getBalance()
{
return $this->client->get('/account/balance');
}
Webhook Integration
Use Symfony’s HttpClient to listen for TextMagic webhooks (e.g., delivery reports):
// src/EventListener/TextMagicWebhookListener.php
public function onKernelRequest(RequestEvent $event)
{
if ($event->isMainRequest() && $event->getRequest()->getPathInfo() === '/textmagic/webhook') {
$this->handleWebhook($event->getRequest()->getContent());
}
}
How can I help you explore Laravel packages today?