Skip to content

Commit 4c7eb26

Browse files
committed
Add CallProSmsService for MessagePro.mn SMS API integration
1 parent 423e464 commit 4c7eb26

File tree

1 file changed

+170
-0
lines changed

1 file changed

+170
-0
lines changed

src/Services/CallProSmsService.php

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
<?php
2+
3+
namespace Fleetbase\Services;
4+
5+
use Illuminate\Support\Facades\Http;
6+
use Illuminate\Support\Facades\Log;
7+
8+
class CallProSmsService
9+
{
10+
protected string $apiKey;
11+
12+
protected string $from;
13+
14+
protected string $baseUrl;
15+
16+
/**
17+
* Create a new CallProSmsService instance.
18+
*/
19+
public function __construct()
20+
{
21+
$this->apiKey = config('services.callpromn.api_key', '');
22+
$this->from = config('services.callpromn.from', '');
23+
$this->baseUrl = config('services.callpromn.base_url', 'https://api.messagepro.mn');
24+
25+
Log::info('CallProSmsService initialized', [
26+
'base_url' => $this->baseUrl,
27+
'from' => $this->from,
28+
]);
29+
}
30+
31+
/**
32+
* Send an SMS message.
33+
*
34+
* @param string $to Recipient phone number (8 digits)
35+
* @param string $text Message text (max 160 characters)
36+
* @param string|null $from Optional sender ID (8 characters), defaults to config
37+
*
38+
* @return array Response containing status and message ID
39+
*
40+
* @throws \Exception If API request fails
41+
*/
42+
public function send(string $to, string $text, ?string $from = null): array
43+
{
44+
$from = $from ?? $this->from;
45+
46+
// Validate parameters
47+
$this->validateParameters($to, $text, $from);
48+
49+
try {
50+
Log::info('Sending SMS via CallPro', [
51+
'to' => $to,
52+
'from' => $from,
53+
'text' => substr($text, 0, 50) . (strlen($text) > 50 ? '...' : ''),
54+
]);
55+
56+
$response = Http::withHeaders([
57+
'x-api-key' => $this->apiKey,
58+
])->get("{$this->baseUrl}/send", [
59+
'from' => $from,
60+
'to' => $to,
61+
'text' => $text,
62+
]);
63+
64+
$statusCode = $response->status();
65+
$body = $response->json();
66+
67+
// Handle response based on status code
68+
if ($statusCode === 200) {
69+
Log::info('SMS sent successfully', [
70+
'message_id' => $body['Message ID'] ?? null,
71+
'result' => $body['Result'] ?? null,
72+
]);
73+
74+
return [
75+
'success' => true,
76+
'message_id' => $body['Message ID'] ?? null,
77+
'result' => $body['Result'] ?? 'SUCCESS',
78+
];
79+
}
80+
81+
// Handle error responses
82+
$errorMessage = $this->getErrorMessage($statusCode);
83+
84+
Log::error('SMS sending failed', [
85+
'status_code' => $statusCode,
86+
'error' => $errorMessage,
87+
'response' => $body,
88+
]);
89+
90+
return [
91+
'success' => false,
92+
'error' => $errorMessage,
93+
'code' => $statusCode,
94+
];
95+
} catch (\Throwable $e) {
96+
Log::error('SMS API request failed', [
97+
'error' => $e->getMessage(),
98+
'trace' => $e->getTraceAsString(),
99+
]);
100+
101+
throw new \Exception('Failed to send SMS: ' . $e->getMessage(), 0, $e);
102+
}
103+
}
104+
105+
/**
106+
* Validate SMS parameters.
107+
*
108+
* @throws \InvalidArgumentException If parameters are invalid
109+
*/
110+
protected function validateParameters(string $to, string $text, string $from): void
111+
{
112+
if (empty($this->apiKey)) {
113+
throw new \InvalidArgumentException('CallPro API key is not configured');
114+
}
115+
116+
if (strlen($from) !== 8) {
117+
throw new \InvalidArgumentException('Sender ID (from) must be exactly 8 characters');
118+
}
119+
120+
if (strlen($to) !== 8) {
121+
throw new \InvalidArgumentException('Recipient phone number (to) must be exactly 8 characters');
122+
}
123+
124+
if (strlen($text) > 160) {
125+
throw new \InvalidArgumentException('Message text cannot exceed 160 characters');
126+
}
127+
128+
if (empty($text)) {
129+
throw new \InvalidArgumentException('Message text cannot be empty');
130+
}
131+
}
132+
133+
/**
134+
* Get error message based on status code.
135+
*/
136+
protected function getErrorMessage(int $statusCode): string
137+
{
138+
return match ($statusCode) {
139+
402 => 'Invalid request parameters',
140+
403 => 'Invalid API key (x-api-key)',
141+
404 => 'Invalid sender ID or recipient phone number format',
142+
503 => 'API rate limit exceeded (max 5 requests per second)',
143+
default => "API request failed with status code: {$statusCode}",
144+
};
145+
}
146+
147+
/**
148+
* Check if the service is configured.
149+
*/
150+
public function isConfigured(): bool
151+
{
152+
return !empty($this->apiKey) && !empty($this->from);
153+
}
154+
155+
/**
156+
* Get the configured sender ID.
157+
*/
158+
public function getFrom(): string
159+
{
160+
return $this->from;
161+
}
162+
163+
/**
164+
* Get the API base URL.
165+
*/
166+
public function getBaseUrl(): string
167+
{
168+
return $this->baseUrl;
169+
}
170+
}

0 commit comments

Comments
 (0)