feat(providers): add new messente sms connector#10685
feat(providers): add new messente sms connector#10685roman-supy-io wants to merge 3 commits intonovuhq:nextfrom
Conversation
👷 Deploy request for dashboard-v2-novu-staging pending review.Visit the deploys page to approve it
|
📝 WalkthroughWalkthroughAdds Messente as a new SMS provider: new provider implementation, handler, factory registration, credential config, schema and enum entries, package dependency, and unit tests. Changes
Sequence DiagramsequenceDiagram
participant Client as Client
participant Factory as SmsFactory
participant Handler as MessenteSmsHandler
participant Provider as MessenteSmsProvider
participant API as Messente API
Client->>Factory: getHandler(integration)
Factory->>Handler: canHandle(integration)?
Handler-->>Factory: matches (Messente/SMS)
Factory->>Client: return MessenteSmsHandler
Client->>Handler: buildProvider(credentials)
Handler->>Provider: new MessenteSmsProvider(username, password)
Provider->>API: configure OmnimessageApi (BasicAuth)
Client->>Provider: sendMessage(options, bridgeProviderData)
Provider->>API: sendOmnimessage(omnimessage)
API-->>Provider: callback(error, response)
Provider->>Client: ISendMessageSuccessResponse { id, date }
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes 🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. 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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
packages/providers/src/lib/sms/messente/messente.test.provider.spec.ts (1)
19-46: Consider adding error handling test coverage.The tests cover the happy path well. Consider adding a test for error scenarios to verify the provider correctly rejects the promise when
sendOmnimessagereturns an error.📝 Example error test
test('should reject when messente library returns an error', async () => { const error = new Error('API Error'); sendOmnimessageMock.mockImplementation((_params, callback) => { callback(error, null); }); const provider = new MessenteSmsProvider({ username: 'test-username', password: 'test-password', }); await expect( provider.sendMessage({ to: '+176543', content: 'SMS Content', from: '+112345', }) ).rejects.toThrow('API Error'); });🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/providers/src/lib/sms/messente/messente.test.provider.spec.ts` around lines 19 - 46, Add a new test that exercises the error path by having sendOmnimessageMock invoke its callback with an Error and asserting that MessenteSmsProvider.sendMessage rejects; specifically, mock sendOmnimessageMock to call callback(error, null), instantiate new MessenteSmsProvider({...}), call provider.sendMessage({ to, content, from }) and use await expect(...).rejects.toThrow with the error message to verify the promise is rejected when the messente library returns an error.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/providers/src/lib/sms/messente/messente.provider.ts`:
- Line 89: The code destructures message_id from response.messages assuming the
array is non-empty; update the logic in messente.provider.ts (around the
response/messages handling where const [{ message_id }] = response.messages is
used) to guard against an empty or missing response.messages (e.g., check
Array.isArray(response.messages) && response.messages.length > 0), safely read
the first element (handle undefined) and then handle the empty-case by returning
an error, throwing a clear exception, or logging and returning a fallback result
as appropriate for send flow so you never attempt to destructure from undefined.
- Around line 49-55: The code is mutating the shared messente.ApiClient.instance
(basicAuth) causing credential clashes; instead create and configure a dedicated
ApiClient for each MessenteSmsProvider: instantiate a new messente.ApiClient
(not messente.ApiClient.instance), set its authentications.basicAuth.username
and .password from config, then pass that client into the provider-specific API
instance (use new messente.OmnimessageApi(yourClient) or the library's
constructor that accepts a client) so each MessenteSmsProvider keeps isolated
credentials and avoids concurrent overwrite.
---
Nitpick comments:
In `@packages/providers/src/lib/sms/messente/messente.test.provider.spec.ts`:
- Around line 19-46: Add a new test that exercises the error path by having
sendOmnimessageMock invoke its callback with an Error and asserting that
MessenteSmsProvider.sendMessage rejects; specifically, mock sendOmnimessageMock
to call callback(error, null), instantiate new MessenteSmsProvider({...}), call
provider.sendMessage({ to, content, from }) and use await
expect(...).rejects.toThrow with the error message to verify the promise is
rejected when the messente library returns an error.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: e0375930-260a-44ab-b55b-9a9decda53b4
⛔ Files ignored due to path filters (2)
apps/dashboard/public/images/providers/light/square/messente.svgis excluded by!**/*.svgpnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (12)
libs/application-generic/src/factories/sms/handlers/index.tslibs/application-generic/src/factories/sms/handlers/messente.handler.tslibs/application-generic/src/factories/sms/sms.factory.tspackages/framework/src/schemas/providers/sms/index.tspackages/framework/src/shared.tspackages/providers/package.jsonpackages/providers/src/lib/sms/index.tspackages/providers/src/lib/sms/messente/messente.provider.tspackages/providers/src/lib/sms/messente/messente.test.provider.spec.tspackages/shared/src/consts/providers/channels/sms.tspackages/shared/src/consts/providers/credentials/provider-credentials.tspackages/shared/src/types/providers.ts
What changed? Why was the change needed?
We're using Messente as our SMS gateway and I found it missing in Novu.
What changed
Added Messente (https://messente.com) as a new SMS delivery provider for Novu. The change introduces a Messente SMS provider and handler, registers the provider across product and SDK layers, and wires credential/config metadata so Messente integrations can be created and used. This enables sending SMS via Messente’s Omnimessage API using HTTP Basic Auth (username/password).
Affected areas
Key technical decisions
Testing
Added unit tests for MessenteSmsProvider that mock messente_api, covering normal sends and passthrough overrides. Manual UI configuration validation is demonstrated in the PR screenshots.
Screenshots
This PR adds a new connector, called [Messente](https://messente.com)
Related enterprise PR
Special notes for your reviewer
Messente, unlike most providers, uses basic auth, so the username/pass are not really account password, they are API credentials, which can be generated just like an API Key.
Note
Medium Risk
Adds a new third-party SMS provider integration and introduces the
messente_apidependency (with older transitive deps), which could affect runtime behavior and bundle/dependency security posture.Overview
Adds Messente as a new SMS connector end-to-end: a new
MessenteSmsProvider(Basic Auth viamessente_apiand Omnimessage send), a correspondingMessenteSmsHandler, and registration in the SMS handler factory.Extends shared/provider metadata to surface the integration in product and SDK layers (new
SmsProviderIdEnum.Messente, credentials schema for username/password +from, framework SMS schema entry), and adds the provider logo asset plus unit tests validating library invocation and_passthroughrequest overrides.Reviewed by Cursor Bugbot for commit 119a82b. Configure here.