From d795610818b9719bcbd65c3d2126d9c8594bba06 Mon Sep 17 00:00:00 2001 From: Aleksandr Soloshenko Date: Sat, 12 Jul 2025 21:05:13 +0700 Subject: [PATCH] feat: Added SMSGateApp adapter --- .env.dev | 3 + README.md | 1 + .../Messaging/Adapter/SMS/SMSGateApp.php | 86 +++++++++++++++++++ .../Messaging/Adapter/SMS/SMSGateAppTest.php | 41 +++++++++ 4 files changed, 131 insertions(+) create mode 100644 src/Utopia/Messaging/Adapter/SMS/SMSGateApp.php create mode 100644 tests/Messaging/Adapter/SMS/SMSGateAppTest.php diff --git a/.env.dev b/.env.dev index db4ed53..e0384a5 100644 --- a/.env.dev +++ b/.env.dev @@ -34,3 +34,6 @@ FAST2SMS_MESSAGE_ID= FAST2SMS_TO= INFORU_API_TOKEN= INFORU_SENDER_ID= +SMSGATEAPP_USERNAME= +SMSGATEAPP_PASSWORD= +SMSGATEAPP_TO= diff --git a/README.md b/README.md index 110842b..c2abf1e 100644 --- a/README.md +++ b/README.md @@ -106,6 +106,7 @@ $messaging->send($message); - [x] [Seven](https://www.seven.io/) - [ ] [SmsGlobal](https://www.smsglobal.com/) - [x] [Inforu](https://www.inforu.co.il/) +- [x] [SMS Gateway for Androidâ„¢](https://sms-gate.app/) ### Push - [x] [FCM](https://firebase.google.com/docs/cloud-messaging) diff --git a/src/Utopia/Messaging/Adapter/SMS/SMSGateApp.php b/src/Utopia/Messaging/Adapter/SMS/SMSGateApp.php new file mode 100644 index 0000000..dce451f --- /dev/null +++ b/src/Utopia/Messaging/Adapter/SMS/SMSGateApp.php @@ -0,0 +1,86 @@ +apiEndpoint = $this->apiEndpoint ?: self::DEFAULT_API_ENDPOINT; + } + + /** + * {@inheritdoc} + */ + public function getName(): string { + return static::NAME; + } + + /** + * {@inheritdoc} + */ + public function getMaxMessagesPerRequest(): int { + return 10; + } + + /** + * {@inheritdoc} + */ + protected function process(SMSMessage $message): array { + $response = new Response($this->getType()); + + $body = [ + 'textMessage' => [ + 'text' => $message->getContent(), + ], + 'phoneNumbers' => $message->getTo(), + ]; + + $result = $this->request( + method: 'POST', + url: $this->apiEndpoint . '/messages?skipPhoneValidation=true', + headers: [ + 'Content-Type: application/json', + 'Authorization: Basic ' . base64_encode("{$this->apiUsername}:{$this->apiPassword}"), + ], + body: $body, + ); + + if ($result['statusCode'] === 202) { + $success = 0; + foreach ($result['response']['recipients'] as $recipient) { + $response->addResult($recipient['phoneNumber'], $recipient['error'] ?? ''); + + if ($recipient['state'] !== 'Failed') { + $success++; + } + } + + $response->setDeliveredTo($success); + } else { + $errorMessage = $result['response']['message'] ?? 'Unknown error'; + foreach ($message->getTo() as $recipient) { + $response->addResult($recipient, $errorMessage); + } + } + + return $response->toArray(); + } +} \ No newline at end of file diff --git a/tests/Messaging/Adapter/SMS/SMSGateAppTest.php b/tests/Messaging/Adapter/SMS/SMSGateAppTest.php new file mode 100644 index 0000000..4ad29a7 --- /dev/null +++ b/tests/Messaging/Adapter/SMS/SMSGateAppTest.php @@ -0,0 +1,41 @@ +markTestSkipped('SMSGateApp credentials not configured'); + } + + // Optional API endpoint if set + $endpoint = \getenv('SMSGATEAPP_ENDPOINT') ?? null; + + // Instantiate SMSGateApp + $sender = new SMSGateApp($username, $password, $endpoint); + + // Create SMS message with required 'to' parameter + $message = new SMS( + to: [$to], + content: 'Test content from SMSGateApp' + ); + + // Call send() and verify response + $response = $sender->send($message); + + // Assertion to match expected response formatting + $this->assertResponse($response); + } +} \ No newline at end of file