Skip to content

feat: add Vonage Messages API adapter#111

Open
bhardwajparth51 wants to merge 5 commits intoutopia-php:mainfrom
bhardwajparth51:feat/vonage-messages-adapter
Open

feat: add Vonage Messages API adapter#111
bhardwajparth51 wants to merge 5 commits intoutopia-php:mainfrom
bhardwajparth51:feat/vonage-messages-adapter

Conversation

@bhardwajparth51
Copy link
Copy Markdown

@bhardwajparth51 bhardwajparth51 commented Apr 1, 2026

What does this PR do?

Adds a new SMS adapter for the Vonage Messages API (v1). This adapter is preferred over the legacy SMS API as it is more cost-effective and built on Vonage's modern messaging infrastructure.

Key details of the implementation:

  • Uses Basic authentication (Base64 encoded API Key and Secret) for the Messages API, matching Vonage's requirements for this endpoint.
  • Strictly validates responses against the 202 Accepted status code, which is the exclusive success response for the Messages API.
  • Implements a shared VonageMessagesBase trait containing the common API logic, allowing future channel adapters (like WhatsApp or Viber) to easily reuse it.

Test Plan

  1. Static Analysis: Verified type safety and syntax using vendor/bin/phpstan analyse --level=6 src tests.
  2. Integration Test: Added tests/Messaging/Adapter/SMS/VonageMessagesTest.php, adhering to the repository's convention of environment-gated integration testing using the assertResponse() request-catcher.
  3. Operational Verification: Validated the request Authorization header generation, JSON payload composition, and fallbacks to guarantee the adapter correctly structures API requests.

Related PRs and Issues

Closes #82

Have you read the Contributing Guidelines on issues?

Yes.

@greptile-apps
Copy link
Copy Markdown

greptile-apps bot commented Apr 1, 2026

Greptile Summary

This PR adds a new VonageMessages SMS adapter that targets the modern Vonage Messages API (v1) instead of the legacy SMS API. It also introduces a VonageMessagesBase trait to share authentication and header logic across future channel adapters (WhatsApp, Viber, etc.).

Key observations:

  • Previously raised from null issue is resolved: The process() method now contains an explicit early-return guard (if (empty($from))) that returns a clean error result instead of serialising null into the JSON body.
  • Previously raised test env-var guard issue is resolved: All three env vars (VONAGE_API_KEY, VONAGE_API_SECRET, VONAGE_TO) are now checked before the test proceeds, and a combined markTestSkipped is emitted if any are missing.
  • Consistent number formatting: Both $to and $from are stripped of the leading + via ltrim, matching the behaviour of the existing Vonage legacy adapter and Vonage's expected E.164-without-prefix format.
  • Correct error extraction: The error handler checks detailtitleerror in priority order, matching the Vonage Messages API problem+json error schema.
  • Header format is correct: getRequestHeaders() returns array<string> in 'Key: Value' format, which is what the base Adapter::request() method passes to CURLOPT_HTTPHEADER.

Confidence Score: 5/5

This PR is safe to merge; all previously raised P0/P1 concerns have been addressed and no new critical issues were found.

Both prior P1 issues (null from serialised as JSON null, and missing VONAGE_TO guard in tests) have been fully resolved. The implementation is consistent with the existing Vonage adapter's conventions, the trait is minimal and correctly scoped, and the tests gate properly on all required credentials. No remaining issues of P1 severity or above were identified.

No files require special attention.

Important Files Changed

Filename Overview
src/Utopia/Messaging/Adapter/SMS/VonageMessages.php New SMS adapter for the Vonage Messages API; includes proper from guard, consistent number stripping, and structured error extraction from the Messages API problem+json response.
src/Utopia/Messaging/Adapter/VonageMessagesBase.php Shared trait providing Basic-auth header generation and request headers for the Vonage Messages API; clean and minimal with correct array header format expected by the base request() method.
tests/Messaging/Adapter/SMS/VonageMessagesTest.php Integration tests correctly gate on all three required env vars (VONAGE_API_KEY, VONAGE_API_SECRET, VONAGE_TO) and cover both the constructor-level from and the message-level fallback from paths.

Reviews (5): Last reviewed commit: "fix: move from field trimming before emp..." | Re-trigger Greptile

@bhardwajparth51
Copy link
Copy Markdown
Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 1, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 1, 2026

Walkthrough

Adds a new SMS adapter Utopia\Messaging\Adapter\SMS\VonageMessages that sends SMS via the Vonage Messages API (v1). The adapter accepts apiKey, apiSecret, and optional default from, limits requests to one message per call, normalizes destination numbers, and treats HTTP 202 as delivered; other responses are reported as failures with error extraction. A shared trait Utopia\Messaging\Adapter\VonageMessagesBase supplies the API endpoint and request/authorization header helpers. Two PHPUnit tests exercise send behavior with and without a fallback from.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and clearly summarizes the main change: adding a new Vonage Messages API adapter for SMS messaging.
Linked Issues check ✅ Passed The PR fully addresses all coding requirements from issue #82: creates VonageMessagesBase trait [#82], implements VonageMessages SMS adapter [#82], and includes proper integration tests.
Out of Scope Changes check ✅ Passed All changes are directly scoped to issue #82 requirements: new VonageMessagesBase trait, VonageMessages SMS adapter, and corresponding integration tests with no extraneous modifications.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Description check ✅ Passed The pull request description clearly explains the motivation, implementation details, and test plan for adding a new Vonage Messages API SMS adapter.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
tests/Messaging/Adapter/SMS/VonageMessagesTest.php (1)

30-34: Inconsistent handling of VONAGE_FROM between constructor and message.

The constructor fallback (line 27) uses 'Vonage' when VONAGE_FROM is unset, but the message's from (line 33) receives false (from getenv() returning false). This creates an inconsistent test scenario where the adapter's from differs from the message's from.

If the intent is to test the adapter's constructor from taking precedence, the message's from could be explicitly set to null or omitted. If the intent is to pass matching values, both should use the same fallback.

♻️ Suggested clarification
         $message = new SMS(
             to: [$to],
             content: 'Test Content',
-            from: \getenv('VONAGE_FROM')
+            from: \getenv('VONAGE_FROM') ?: null
         );

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: e6eed56d-cd95-4c22-9ff3-18c201ec0c9c

📥 Commits

Reviewing files that changed from the base of the PR and between fcb4c3c and 6710210.

📒 Files selected for processing (3)
  • src/Utopia/Messaging/Adapter/SMS/VonageMessages.php
  • src/Utopia/Messaging/Adapter/VonageMessagesBase.php
  • tests/Messaging/Adapter/SMS/VonageMessagesTest.php

@bhardwajparth51
Copy link
Copy Markdown
Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 1, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@bhardwajparth51
Copy link
Copy Markdown
Author

@stnguyen90 Ready for review! let me know if it need any additional changes.

@bhardwajparth51
Copy link
Copy Markdown
Author

i think the CI failures are all pre-existing they're coming from expired or missing github secrets for Twilio, Resend, Sendgrid, Mailgun, Fast2SMS, Inforu, Discord, APNS, and FCM. My Vonage tests are correctly skipping since the VONAGE_* secrets aren't configured in CI yet.

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.

🚀 Feature: Vonage Messages Adapter

1 participant