-
Notifications
You must be signed in to change notification settings - Fork 68
Feat 7714 adding semaphore messaging adapter #144
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,135 @@ | ||
| <?php | ||
|
|
||
| namespace Utopia\Messaging\Adapter\SMS; | ||
|
|
||
| use Utopia\Messaging\Adapter\SMS as SMSAdapter; | ||
| use Utopia\Messaging\Messages\SMS as SMSMessage; | ||
| use Utopia\Messaging\Response; | ||
|
|
||
| // Reference Material | ||
| // https://semaphore.co/docs | ||
|
|
||
| class Semaphore extends SMSAdapter | ||
| { | ||
| protected const NAME = 'Semaphore'; | ||
|
|
||
| /** | ||
| * @param string $apikey Semaphore api key | ||
| */ | ||
|
|
||
|
|
||
| public function __construct( | ||
| private string $apikey | ||
| ) { | ||
| } | ||
|
|
||
| public function getName(): string | ||
| { | ||
| return static::NAME; | ||
| } | ||
|
|
||
| public function getMaxMessagesPerRequest(): int | ||
| { | ||
| // NOTE: user can do upto 1000 numbers per API call | ||
| return 1000; | ||
| } | ||
|
|
||
| /** | ||
| * {@inheritdoc} | ||
| */ | ||
| public function process(SMSMessage $message): array | ||
| { | ||
| $response = new Response($this->getType()); | ||
| $result = $this->request( | ||
| method: 'POST', | ||
| url: 'https://api.semaphore.co/api/v4/messages', | ||
| headers: [ | ||
| 'Content-Type: application/json', | ||
| ], | ||
| body: [ | ||
| 'apikey' => $this->apikey, | ||
| 'number' => $message->getTo()[0], | ||
| 'message' => $message->getContent(), | ||
| 'sendername' => $message->getFrom() | ||
| ], | ||
| ); | ||
|
|
||
| if ($result['statusCode'] === 200) { | ||
| if ($result['response'][0] && count($result['response'][0]) > 1) { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When Semaphore returns its documented 200 validation-error object keyed by fields such as Prompt To Fix With AIThis is a comment left during a code review.
Path: src/Utopia/Messaging/Adapter/SMS/Semaphore.php
Line: 58
Comment:
**Validation errors access missing index**
When Semaphore returns its documented 200 validation-error object keyed by fields such as `sendername`, this condition reads the nonexistent numeric key `0`, causing an undefined-array-key warning before error handling continues.
How can I resolve this? If you propose a fix, please make it concise. |
||
| $response->addResult($message->getTo()[0]); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When Semaphore returns a successful response, this branch adds a result without updating Prompt To Fix With AIThis is a comment left during a code review.
Path: src/Utopia/Messaging/Adapter/SMS/Semaphore.php
Line: 59
Comment:
**Successful delivery count stays zero**
When Semaphore returns a successful response, this branch adds a result without updating `deliveredTo`, causing successful sends to report zero deliveries and fail the shared adapter response assertion.
How can I resolve this? If you propose a fix, please make it concise. |
||
| } else { | ||
| foreach ($result['response'] as $variableName) { | ||
| $errorMessage = $variableName; | ||
| if (is_array($variableName)) { | ||
| $response->addResult($message->getTo()[0], $errorMessage[0]); | ||
| } else { | ||
| $response->addResult($message->getTo()[0], 'Unknown error'); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| if ($result['statusCode'] === 500) { | ||
| $response->addResult($message->getTo()[0], $result['response'][0]); | ||
| } | ||
|
Comment on lines
+70
to
+73
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When Semaphore returns an authentication, validation, rate-limit, service, or transport failure with a status other than 500, neither branch adds a result, causing the adapter to return an empty result set with no recipient or error details. Prompt To Fix With AIThis is a comment left during a code review.
Path: src/Utopia/Messaging/Adapter/SMS/Semaphore.php
Line: 70-73
Comment:
**Non-500 failures lose results**
When Semaphore returns an authentication, validation, rate-limit, service, or transport failure with a status other than 500, neither branch adds a result, causing the adapter to return an empty result set with no recipient or error details.
How can I resolve this? If you propose a fix, please make it concise. |
||
|
|
||
| return $response->toArray(); | ||
| } | ||
| } | ||
|
|
||
|
|
||
| // Below is a Sample Error response for bad payload | ||
| // The status code is 200 even if there is an error. | ||
| // The status code is 200 if semaphore returns a response irrespective of good or error response | ||
|
|
||
| // $errorResponse = array( | ||
| // "url" => "https://api.semaphore.co/api/v4/messages", | ||
| // "statusCode" => 200, | ||
| // "response" => array( | ||
| // "sendername" => array( | ||
| // "The selected sendername is invalid." | ||
| // ) | ||
| // ), | ||
| // "error" => "" | ||
| // ); | ||
|
|
||
|
|
||
|
|
||
| // Below is a Sample Error response when Semaphore credits are empty | ||
|
|
||
| // $errorResponse = [ | ||
| // "url" => "https://api.semaphore.co/api/v4/messages", | ||
| // "statusCode" => 500, | ||
| // "response" => [ | ||
| // "Your current balance of 0 credits is not sufficient. This transaction requires 1 credits." | ||
| // ], | ||
| // "error" => "" | ||
| // ]; | ||
|
|
||
|
|
||
|
|
||
| // Below is a sample success response | ||
| // Unlike error response, More than 1 keys are returned in the response array. Refer to docs | ||
|
|
||
| // $successResponse = array( | ||
| // "url" => "https://api.semaphore.co/api/v4/messages", | ||
| // "statusCode" => 200, | ||
| // "response" => array( | ||
| // array( | ||
| // "message_id" => 212210271, | ||
| // "user_id" => 40495, | ||
| // "user" => "hello@gmail.com", | ||
| // "account_id" => 40356, | ||
| // "account" => "Semiphore", | ||
| // "recipient" => "639358574402", | ||
| // "message" => "Nice meeting you", | ||
| // "sender_name" => "Semaphore", | ||
| // "network" => "Globe", | ||
| // "status" => "Pending", | ||
| // "type" => "Single", | ||
| // "source" => "Api", | ||
| // "created_at" => "2024-03-12 23:14:50", | ||
| // "updated_at" => "2024-03-12 23:14:50" | ||
| // ) | ||
| // ), | ||
| // "error" => "" | ||
| // ); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| <?php | ||
|
|
||
| namespace Utopia\Tests\Adapter\SMS; | ||
|
|
||
| use Utopia\Messaging\Adapter\SMS\Semaphore; | ||
| use Utopia\Messaging\Messages\SMS; | ||
| use Utopia\Tests\Adapter\Base; | ||
|
|
||
| class SemaphoreTest extends Base | ||
| { | ||
| public function testSendSMS(): void | ||
| { | ||
| $sender = new Semaphore(getenv('SEMAPHORE_API_KEY')); | ||
|
|
||
| $message = new SMS( | ||
| [getenv('SEMAPHORE_TO')], | ||
| 'Test Content', | ||
| getenv('SEMAPHORE_SENDER_NAME') | ||
| ); | ||
|
|
||
| $response = $sender->send($message); | ||
|
|
||
| $this->assertResponse($response); | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When a message contains 2–1000 recipients, the adapter accepts the message but submits and records only
getTo()[0], causing every remaining recipient to be silently omitted from delivery and results.Prompt To Fix With AI