Skip to content

feat: add AfricasTalking SMS adapter#132

Open
deepshekhardas wants to merge 3 commits into
utopia-php:mainfrom
deepshekhardas:feat/africastalking-adapter
Open

feat: add AfricasTalking SMS adapter#132
deepshekhardas wants to merge 3 commits into
utopia-php:mainfrom
deepshekhardas:feat/africastalking-adapter

Conversation

@deepshekhardas

Copy link
Copy Markdown
  • New SMS adapter for AfricasTalking API
  • Supports sending SMS messages with optional 'from' field
  • Handles up to 100 messages per request
  • Proper error handling for API responses
  • Includes integration tests

@greptile-apps

greptile-apps Bot commented Jun 17, 2026

Copy link
Copy Markdown

Greptile Summary

This PR adds a new AfricasTalking SMS adapter that authenticates via username and API key, supports an optional sender ID, and iterates over recipients to dispatch individual HTTP POST requests to the Africa's Talking v1 messaging endpoint.

  • The adapter declares getMaxMessagesPerRequest() as 100 but its process() loop fires a separate HTTP request for each recipient, so passing multiple recipients causes sequential round-trips rather than the single batched call that value implies — this mismatch also leaves callers at risk of hitting provider rate limits.
  • A 201 HTTP response is treated as full success without inspecting the SMSMessageData.Recipients array returned by the API, which carries per-number statuses; provider-side rejections (invalid number, insufficient balance) are therefore silently reported as delivered.

Confidence Score: 3/5

The adapter has two functional defects that affect correctness in multi-recipient scenarios and error visibility.

The declared batch capacity (100) contradicts the one-request-per-recipient implementation, and 201 responses are accepted as fully delivered without reading the per-recipient status objects the API embeds in the body. Both issues produce wrong data for callers on the changed code path.

src/Utopia/Messaging/Adapter/SMS/AfricasTalking.php needs attention for the request-batching mismatch and per-recipient status handling.

Important Files Changed

Filename Overview
src/Utopia/Messaging/Adapter/SMS/AfricasTalking.php New SMS adapter for Africa's Talking; fires one HTTP request per recipient despite getMaxMessagesPerRequest() returning 100, and does not inspect per-recipient statuses inside the 201 response body, so callers receive a success result even when individual numbers are rejected by the provider.
tests/Messaging/Adapter/SMS/AfricasTalkingTest.php Integration tests for default and custom-sender cases; tests correctly assert against the returned array and skip cleanly when credentials are absent.

Reviews (4): Last reviewed commit: "fix: correct API endpoint and preserve p..." | Re-trigger Greptile

Comment thread src/Utopia/Messaging/Adapter/SMS/AfricasTalking.php
Comment on lines +59 to +61
if ($result['statusCode'] === 201) {
$response->incrementDeliveredTo();
$response->addResult($recipient);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Check recipient status

Africa's Talking returns per-recipient statuses in SMSMessageData.Recipients, including failures such as invalid numbers or insufficient balance, while the HTTP request itself can still succeed. This branch marks every 201 response as delivered without reading those recipient statuses, so callers can receive success and an incremented deliveredTo count for messages the provider rejected.

Artifacts

Repro: focused PHP harness mocking a 201 failed-recipient Africa's Talking response

  • Contains supporting evidence from the run (text/x-php; charset=utf-8).

Repro: harness execution output showing HTTP 201 Created and adapter success/deliveredTo behavior

  • Keeps the command output available without making the summary code-heavy.

View artifacts

T-Rex Ran code and verified through T-Rex

Comment thread tests/Messaging/Adapter/SMS/AfricasTalkingTest.php Outdated
Comment on lines +28 to +31
public function getMaxMessagesPerRequest(): int
{
return 100;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 getMaxMessagesPerRequest claims 100 but makes one HTTP call per recipient

getMaxMessagesPerRequest() returning 100 tells the base Adapter::send() to allow up to 100 recipients in a single call, but process() loops over each one and fires a separate $this->request() for every number. A caller passing 100 recipients will trigger 100 sequential HTTP round-trips rather than the single batched request the value implies, and can easily hit Africa's Talking rate limits or exhaust the 30-second socket timeout.

The Africa's Talking API supports multiple recipients natively — the to parameter accepts a comma-separated list in one POST. The adapter should either join all recipients into a single request body (and process the per-recipient statuses from SMSMessageData.Recipients) or, as a minimal safe fix, change getMaxMessagesPerRequest() to 1 to match the actual one-request-per-recipient behavior, consistent with how Twilio and Vonage adapters are implemented.

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/Utopia/Messaging/Adapter/SMS/AfricasTalking.php
Line: 28-31

Comment:
**`getMaxMessagesPerRequest` claims 100 but makes one HTTP call per recipient**

`getMaxMessagesPerRequest()` returning `100` tells the base `Adapter::send()` to allow up to 100 recipients in a single call, but `process()` loops over each one and fires a separate `$this->request()` for every number. A caller passing 100 recipients will trigger 100 sequential HTTP round-trips rather than the single batched request the value implies, and can easily hit Africa's Talking rate limits or exhaust the 30-second socket timeout.

The Africa's Talking API supports multiple recipients natively — the `to` parameter accepts a comma-separated list in one POST. The adapter should either join all recipients into a single request body (and process the per-recipient statuses from `SMSMessageData.Recipients`) or, as a minimal safe fix, change `getMaxMessagesPerRequest()` to `1` to match the actual one-request-per-recipient behavior, consistent with how Twilio and Vonage adapters are implemented.

How can I resolve this? If you propose a fix, please make it concise.

Fix in Claude Code Fix in Codex

deepshekhardas added 3 commits July 10, 2026 10:30
- New SMS adapter for AfricasTalking API
- Supports sending SMS messages with optional 'from' field
- Handles up to 100 messages per request
- Proper error handling for API responses
- Includes integration tests
@deepshekhardas deepshekhardas force-pushed the feat/africastalking-adapter branch from 900cffb to d08ca15 Compare July 10, 2026 05:01
@deepshekhardas

Copy link
Copy Markdown
Author

Following up - AfricasTalking SMS adapter. Ready for review.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant