Skip to content

feat(providers): add new messente sms connector#10685

Open
roman-supy-io wants to merge 3 commits intonovuhq:nextfrom
supy-io:feat/messente-sms-connector
Open

feat(providers): add new messente sms connector#10685
roman-supy-io wants to merge 3 commits intonovuhq:nextfrom
supy-io:feat/messente-sms-connector

Conversation

@roman-supy-io
Copy link
Copy Markdown

@roman-supy-io roman-supy-io commented Apr 13, 2026

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

  • shared: Added Messente to SMS provider lists with display metadata, logo, doc link, and a new credentials schema (User and Password plus base SMS fields).
  • framework: Registered the Messente provider in SMS provider schemas to enable validation and type-checking.
  • providers: Implemented MessenteSmsProvider using the messente_api client (OmnimessageApi) to send SMS; added provider export and unit tests that mock messente_api and validate send and _passthrough behavior.
  • application-generic: Added MessenteSmsHandler and registered it in the SMS factory so the handler/factory pattern can instantiate Messente for SMS channel.

Key technical decisions

  • Uses HTTP Basic Auth (username/password) per Messente’s API rather than an API-key header model.
  • New npm dependency: messente_api@^2.5.0 added to packages/providers.
  • Implementation follows existing provider/handler patterns (BaseProvider/ISmsProvider and BaseSmsHandler).

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

image
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_api dependency (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 via messente_api and Omnimessage send), a corresponding MessenteSmsHandler, 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 _passthrough request overrides.

Reviewed by Cursor Bugbot for commit 119a82b. Configure here.

@netlify
Copy link
Copy Markdown

netlify Bot commented Apr 13, 2026

👷 Deploy request for dashboard-v2-novu-staging pending review.

Visit the deploys page to approve it

Name Link
🔨 Latest commit 7ed76fd

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 13, 2026

📝 Walkthrough

Walkthrough

Adds Messente as a new SMS provider: new provider implementation, handler, factory registration, credential config, schema and enum entries, package dependency, and unit tests.

Changes

Cohort / File(s) Summary
Type & Enum Definitions
packages/framework/src/shared.ts, packages/shared/src/types/providers.ts
Added Messente = 'messente' to SmsProviderIdEnum.
SMS Provider Schema
packages/framework/src/schemas/providers/sms/index.ts
Registered messente key in smsProviderSchemas mapped to genericProviderSchemas.
Handler & Factory
libs/application-generic/src/factories/sms/handlers/index.ts, libs/application-generic/src/factories/sms/handlers/messente.handler.ts, libs/application-generic/src/factories/sms/sms.factory.ts
Added MessenteSmsHandler and re-export; registered handler in SmsFactory.handlers.
Provider Implementation & Barrel
packages/providers/src/lib/sms/messente/messente.provider.ts, packages/providers/src/lib/sms/index.ts
Implemented MessenteSmsProvider (auth config, sendMessage → messente Omnimessage API) and exported it from SMS providers barrel.
Provider Tests
packages/providers/src/lib/sms/messente/messente.test.provider.spec.ts
Added tests mocking messente_api to verify request mapping and passthrough behavior.
Credentials Configuration
packages/shared/src/consts/providers/credentials/provider-credentials.ts
Added messenteConfig credential definition (User, Password) plus base SMS fields.
Provider Metadata
packages/shared/src/consts/providers/channels/sms.ts
Added Messente entry to smsProviders (displayName, channel, credentials, docs URL, logos).
Dependency
packages/providers/package.json
Added runtime dependency messente_api ^2.5.0.

Sequence Diagram

sequenceDiagram
    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 }
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The pull request title follows the Conventional Commits format with a valid type (feat) and scope (providers), uses lowercase imperative description, and accurately describes the main change of adding a new Messente SMS connector.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ 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.

❤️ Share

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

@roman-supy-io roman-supy-io changed the title feat(integrations): add new messente sms connector feat(providers): add new messente sms connector Apr 13, 2026
Copy link
Copy Markdown
Contributor

@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: 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 sendOmnimessage returns 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

📥 Commits

Reviewing files that changed from the base of the PR and between 1a5f0f9 and 119a82b.

⛔ Files ignored due to path filters (2)
  • apps/dashboard/public/images/providers/light/square/messente.svg is excluded by !**/*.svg
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (12)
  • libs/application-generic/src/factories/sms/handlers/index.ts
  • libs/application-generic/src/factories/sms/handlers/messente.handler.ts
  • libs/application-generic/src/factories/sms/sms.factory.ts
  • packages/framework/src/schemas/providers/sms/index.ts
  • packages/framework/src/shared.ts
  • packages/providers/package.json
  • packages/providers/src/lib/sms/index.ts
  • packages/providers/src/lib/sms/messente/messente.provider.ts
  • packages/providers/src/lib/sms/messente/messente.test.provider.spec.ts
  • packages/shared/src/consts/providers/channels/sms.ts
  • packages/shared/src/consts/providers/credentials/provider-credentials.ts
  • packages/shared/src/types/providers.ts

Comment thread packages/providers/src/lib/sms/messente/messente.provider.ts
Comment thread packages/providers/src/lib/sms/messente/messente.provider.ts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant