Skip to content

feat: add Vonage Messages API adapter - #127

Open
deepshekhardas wants to merge 2 commits into
utopia-php:mainfrom
deepshekhardas:fix/111-vonage-messages-api
Open

feat: add Vonage Messages API adapter#127
deepshekhardas wants to merge 2 commits into
utopia-php:mainfrom
deepshekhardas:fix/111-vonage-messages-api

Conversation

@deepshekhardas

Copy link
Copy Markdown

Port of PR #111 by bhardwajparth51.

Renames the existing Vonage adapter to VonageLegacy and adds a new VonageMessages adapter using the modern Vonage Messages API (V1) which is more cost-effective and versatile.

Changes:

  • Rename Vonage -> VonageLegacy (backward compat note)
  • Add VonageMessages adapter using Messages API v1
  • Add corresponding tests

@greptile-apps

greptile-appsBot commented Jun 14, 2026

Copy link
Copy Markdown

Greptile Summary

This PR renames the existing Vonage SMS adapter to VonageLegacy and introduces a new VonageMessages adapter targeting the modern Vonage Messages API v1. Both adapters are non-functional as written because they omit the parent::__construct() call that the base Adapter class relies on to initialize its typed properties.

  • VonageLegacy: The original Vonage.php explicitly called parent::__construct(); this PR removes that call, leaving Adapter::$sendCounter uninitialized. Every invocation of send() crashes with a fatal error when recordResponse() is reached.
  • VonageMessages: The new adapter has the same structural omission — no parent::__construct() — so $sendCounter and $clientFactory are both uninitialized, causing the same fatal error on any send attempt.
  • Tests: Both test files unconditionally call markTestSkipped, and the VonageLegacyTest comment references the old Vonage class name instead of VonageLegacy.

Confidence Score: 2/5

  • Both new adapters crash on every send due to missing parent constructor calls; this change would break all Vonage SMS delivery if merged.
  • Both VonageLegacy and VonageMessages omit the parent::__construct() call that the base Adapter class requires to initialize its typed properties. The $sendCounter property has no default and is accessed on every send(), so any attempt to deliver an SMS will throw a fatal uninitialized-property error. The original Vonage adapter had this call, making its removal a clear regression introduced by this PR.
  • src/Utopia/Messaging/Adapter/SMS/VonageLegacy.php and src/Utopia/Messaging/Adapter/SMS/VonageMessages.php both need parent::__construct() added to their constructors before this can be merged.

Important Files Changed

FilenameOverview
src/Utopia/Messaging/Adapter/SMS/VonageLegacy.phpRenames Vonage → VonageLegacy but removes the parent::__construct() call that initialized required base-class properties, making every send() call crash with a fatal uninitialized-property error.
src/Utopia/Messaging/Adapter/SMS/VonageMessages.phpNew Messages API adapter is otherwise well-structured but omits parent::__construct(), leaving $sendCounter and $clientFactory uninitialized and causing a fatal error on the first send.
tests/Messaging/Adapter/SMS/VonageLegacyTest.phpTest is always skipped; commented-out body references the old Vonage class name instead of VonageLegacy.
tests/Messaging/Adapter/SMS/VonageMessagesTest.phpTest is unconditionally skipped with real assertions in a dead comment block; no runtime issues since the code is never executed.

Fix all with GreploopFix All in Claude CodeFix All in Codex

Prompt To Fix All With AI
### Issue 1
src/Utopia/Messaging/Adapter/SMS/VonageLegacy.php:20-25
**Missing `parent::__construct()` causes fatal error on every send**
The original `Vonage.php` called `parent::__construct()`, which this PR explicitly removes. The base `Adapter` class initializes two typed properties there — `$sendCounter` (non-nullable `Counter`) and `$clientFactory` (readonly `?Closure`) — both via constructor promotion or direct assignment. Without that call, both properties remain uninitialized. PHP throws `Fatal error: Typed property Utopia\Messaging\Adapter::$sendCounter must not be accessed before initialization` the first time `send()` calls `recordResponse()`, which is every successful delivery. Every other SMS adapter in the codebase (`Twilio`, `Clickatell`, `Sinch`, etc.) calls `parent::__construct()`.
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Reviews (8): Last reviewed commit: "chore: remove old Vonage files after ren..." | Re-trigger Greptile

use Utopia\Messaging\Response;

class Vonage extends SMSAdapter
class VonageLegacy extends SMSAdapter

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1Breaking rename with no backward-compatibility alias

Renaming VonageVonageLegacy drops the original class name entirely. Any downstream code using new \Utopia\Messaging\Adapter\SMS\Vonage(...) or use Utopia\Messaging\Adapter\SMS\Vonage will throw a fatal Class not found error after upgrading this library. The PR description mentions a "backward compat note" but no alias or deprecation shim is present in the diff. Consider adding class_alias(VonageLegacy::class, 'Utopia\\Messaging\\Adapter\\SMS\\Vonage'); at the bottom of this file (or in a dedicated compat file), or coordinate a semver-major release.

Comment on lines +14 to +35
public function testSendSMS(): void
{
$this->markTestSkipped('Vonage Messages credentials are not available.');

/*
$apiKey = \getenv('VONAGE_MESSAGES_API_KEY');
$apiSecret = \getenv('VONAGE_MESSAGES_API_SECRET');

$sender = new VonageMessages($apiKey, $apiSecret);

$message = new SMS(
to: [\getenv('VONAGE_MESSAGES_TO')],
content: 'Test Content',
from: \getenv('VONAGE_MESSAGES_FROM'),
);

$response = $sender->send($message);

$this->assertNotEmpty($response['results']);
$this->assertNotEmpty($response['results'][0]['success']);
*/
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2Entire test body is dead code

The test immediately calls markTestSkipped and the real assertions are in a block comment rather than an if (! $creds) { markTestSkipped(); } guard pattern. Tests for other adapters (e.g., VonageLegacyTest) use live credentials gated by env vars. If VONAGE_MESSAGES_API_KEY etc. are simply not available in CI, the existing skip-unless-env-var pattern should be used here too, so the test actually executes when credentials are configured.

@deepshekhardas

Copy link
Copy Markdown
Author

Following up - this PR has been waiting for review. Happy to address any feedback or make changes.

deepshekhardas added 2 commits August 21, 2026 12:22
Renames the existing Vonage adapter to VonageLegacy and adds a new VonageMessages adapter using the modern Vonage Messages API (V1). Based on PR utopia-php#111 by bhardwajparth51.
Comment on lines 20 to 25
public function __construct(
private readonly string $apiKey,
private readonly string $apiSecret,
private readonly ?string $from = null,
private string $apiKey,
private string $apiSecret,
private ?string $from = null
) {
parent::__construct();
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1Missing parent::__construct() causes fatal error on every send

The original Vonage.php called parent::__construct(), which this PR explicitly removes. The base Adapter class initializes two typed properties there — $sendCounter (non-nullable Counter) and $clientFactory (readonly ?Closure) — both via constructor promotion or direct assignment. Without that call, both properties remain uninitialized. PHP throws Fatal error: Typed property Utopia\Messaging\Adapter::$sendCounter must not be accessed before initialization the first time send() calls recordResponse(), which is every successful delivery. Every other SMS adapter in the codebase (Twilio, Clickatell, Sinch, etc.) calls parent::__construct().

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/Utopia/Messaging/Adapter/SMS/VonageLegacy.php
Line: 20-25
Comment:
**Missing `parent::__construct()` causes fatal error on every send**
The original `Vonage.php` called `parent::__construct()`, which this PR explicitly removes. The base `Adapter` class initializes two typed properties there — `$sendCounter` (non-nullable `Counter`) and `$clientFactory` (readonly `?Closure`) — both via constructor promotion or direct assignment. Without that call, both properties remain uninitialized. PHP throws `Fatal error: Typed property Utopia\Messaging\Adapter::$sendCounter must not be accessed before initialization` the first time `send()` calls `recordResponse()`, which is every successful delivery. Every other SMS adapter in the codebase (`Twilio`, `Clickatell`, `Sinch`, etc.) calls `parent::__construct()`.
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Fix in Claude CodeFix in Codex

Sign up for freeto 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

@deepshekhardas