Giter Club home page Giter Club logo

novu-kotlin's Introduction

Novu Kotlin SDK

License GitHub release (with filter)

The Novu Kotlin SDK provides a fluent and expressive interface for interacting with Novu's API and managing notifications. Please refer to the full documentation to learn more.

Installation

Maven users:

<!--add dependency-->
<dependency>
    <groupId>co.novu</groupId>
    <artifactId>novu-kotlin</artifactId>
    <version>1.2.0</version>
</dependency>

Gradle users:

//Kotlin
//add dependency
implementation("co.novu:novu-kotlin:1.2.0")
//Groovy
//add dependency
implementation 'co.novu:novu-kotlin:1.2.0'

Sync your project, and you should have the artifacts downloaded.

Usage

To use the library, first initialize the client with your API token:

// without changing the backend URL
import co.novu.Novu
import co.novu.extensions.environments

fun main() {
    val novu = Novu(apiKey = "API_KEY")
    val environment = novu.environments()
    println(environment)
}
// with config param
import co.novu.Novu
import co.novu.NovuConfig
import co.novu.extensions.environments

fun main() {
    val config = NovuConfig(backendUrl = "URL", apiKey = "API_KEY")
    val novu = Novu(config)
    val environment = novu.environments()
    println(environment)
} 

You can then call methods on the client to interact with the Novu API:

novu.subscribers()

List of all methods

The client methods map directly to the Novu API endpoints. Here is a list of all the available methods. Check the API docs for list of available methods.

Changes

  • changes(query = {})
  • countChanges()
  • applyBulkChanges()
  • applyChange(changeId)

Environments

  • currentEnvironment()
  • createEnvironment(body)
  • environments()
  • updateEnvironment(environmentId, body)
  • apiKeys()
  • regenerateApiKeys()
  • updateWidgetSettings(body)

Events

  • triggerEvent(body)
  • triggerBulkEvent(body)
  • broadcastEvent(body)
  • cancelTriggeredEvent(transactionId)

Execution Details

  • executionDetails(query = {})

Feeds

  • createFeed(body)
  • feeds()
  • deleteFeed(feedId)

Inbound Parse

  • validateMxRecordSetupForInboundParse()

Integrations

  • integrations()
  • createIntegration(body)
  • activeIntegrations()
  • webhookProviderStatus(providerId)
  • updateIntegration(integrationId, body)
  • deleteIntegration(integrationId)
  • channelLimit(channelType)
  • inAppStatus()

Layouts

  • createLayout(body)
  • layouts(query = {})
  • layout(layoutId)
  • deleteLayout(layoutId)
  • updateLayout(layoutId, body)
  • makeDefaultLayout(layoutId)

Messages

  • messages(query = {})
  • deleteMessage(messageId)

Notification Groups

  • createNotificationGroup(body)
  • notificationGroups()

Notification Templates

  • notificationTemplates(query = {})
  • createNotificationTemplate(body)
  • updateNotificationTemplate(templateId, body)
  • deleteNotificationTemplate(templateId)
  • notificationTemplate(templateId)
  • notificationTemplateBlueprint(templateId)
  • createNotificationTemplateBlueprint(templateId)
  • updateNotificationTemplateStatus(templateId, body)

Notification

  • notifications(query = {})
  • notificationsStats()
  • notificationsGraphStats(query = {})
  • notification(notificationId)

Subscribers

  • subscribers(query = {})
  • createSubscriber(body)
  • createSubscriberBulk(body)
  • subscriber(subscriberId)
  • updateSubscriber(subscriberId, body)
  • deleteSubscriber(subscriberId)
  • updateSubscriberCredentials(subscriberId, body)
  • updateSubscriberOnlineStatus(subscriberId, body)
  • subscriberPreferences(subscriberId)
  • updateSubscriberPreference(subscriberId, templateId, body)
  • subscriberNotificationFeed(subscriberId, query = {})
  • subscriberUnseenNotificationCount(subscriberId, query = {})
  • markSubscriberFeedSeen(subscriberId, body)
  • markMessageActionSeen(subscriberId, messageId, type)

Topics

  • createTopic(body)
  • filterTopics(page, pageSize, key)
  • addSubscribers(topicKey, body)
  • removeSubscribers(topicKey, body)
  • checkSubscriber(topicKey, externalSubscriberId)
  • topic(topicKey)
  • renameTopic(topicKey, body)
  • deleteTopic(topicKey)

Blueprints

  • getBlueprintsByCategory()
  • getBlueprint(templateId)

Tenants

  • getTenants(page, limit)
  • createTenant(body)
  • getTenant(identifier)
  • updateTenant(identifier)
  • deleteTenant(identifier)

Organizations

  • createOrganization(body)
  • fetchAllOrganizations()
  • updateOrganizationName(body)
  • fetchCurrentOrganization()
  • removeMemberWithId(identifier)
  • updateMemberRole(identifier, body)
  • fetchMembersOfOrganization()
  • updateOrganizationBrand(body)

Workflow Override

  • createWorkflowOverride(createWorkflowOverrideRequest)
  • getWorkflowOverrides(getWorkflowOverrideRequest)
  • getWorkflowOverride(workflowId, tenantId)
  • getWorkflowOverrideById(overrideId)
  • updateWorkflowOverride(workflowId, tenantId)
  • updateWorkflowOverrideById(overrideId)
  • deleteWorkflowOverride(overrideId)

For more information about these methods and their parameters, see the API documentation.

Contributing

Feature requests, bug reports and pull requests are welcome. Please create an issue.

Support and Feedback

Be sure to visit the Novu official documentation website for additional information about our API. If you need additional assistance, join our Discord server here.

License

Novu Kotlin SDK is licensed under the MIT License - see the LICENSE file for details.

Contributors

Contributors

novu-kotlin's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

novu-kotlin's Issues

Add Missing Methods for Messages

Some endpoints of the following section can't be hit from this SDK.

We would like to ensure that all endpoints can be hit. For this issue, we would like to build out the Messages

Some of these methods may already exist. 
If so no need to change/update them, just point out that they already exist and we will close the issue.

This is just to bring every SDK we have on par with all the methods available.

Check all the endpoints here and add the missing ones.

Add Missing Methods for Feeds

Some endpoints of the following section can't be hit from this SDK.

We would like to ensure that all endpoints can be hit. For this issue, we would like to build out the Feeds

Some of these methods may already exist. 
If so no need to change/update them, just point out that they already exist and we will close the issue.

This is just to bring every SDK we have on par with all the methods available.

Check all the endpoints here and add the missing ones.

Add Missing Methods for Integrations

Some endpoints of the following section can't be hit from this SDK.

We would like to ensure that all endpoints can be hit. For this issue, we would like to build out the Integrations

Some of these methods may already exist. 
If so no need to change/update them, just point out that they already exist and we will close the issue.

This is just to bring every SDK we have on par with all the methods available.

Check all the endpoints here and add the missing ones.

Add Missing Methods for Layouts

Some endpoints of the following section can't be hit from this SDK.

We would like to ensure that all endpoints can be hit. For this issue, we would like to build out the Layouts

Some of these methods may already exist. 
If so no need to change/update them, just point out that they already exist and we will close the issue.

This is just to bring every SDK we have on par with all the methods available.

Check all the endpoints here and add the missing ones.

Add Missing Methods for Execution details

Some endpoints of the following section can't be hit from this SDK.

We would like to ensure that all endpoints can be hit. For this issue, we would like to build out the Execution details

Some of these methods may already exist. 
If so no need to change/update them, just point out that they already exist and we will close the issue.

This is just to bring every SDK we have on par with all the methods available.

Check all the endpoints here and add the missing ones.

Setup GitHub Workflow for Running Unit Tests

In order to ensure the stability and reliability of our codebase, it is essential to have automated unit tests running for each push and pull request. Currently, our repository lacks a GitHub Actions workflow to run unit tests, and this needs to be addressed to maintain code quality and catch issues early.

Suggested Solution:

  1. Create a new workflow file in .github/workflows/ directory.
    Filename: run-unit-tests.yml

  2. Configure the workflow to be triggered on every push and pull_request event to the main branch.

  3. Define job steps:
    Checkout the repository.
    Setup the environment/java runtime.
    Install dependencies.
    Run the unit tests.

Missing methods

Some endpoints of the following section can't be hit from this SDK. Please ensure that all the SDK methods are up to date. I'm adding here a list of sections to check/update:

  • Notification templates
  • Integrations
  • Layouts
  • Inbound Parse
  • Environments
  • Changes
  • Execution details
  • Feeds
  • Messages
  • Blueprints

Some of these methods already exist. No need to change/update them. This is just to bring every SDK we have on par with all the methods available.

Check all the endpoints here and add the missing ones.

Add Missing Methods for Blueprints

Some endpoints of the following section can't be hit from this SDK.

We would like to ensure that all endpoints can be hit. For this issue, we would like to build out the Blueprints

Some of these methods may already exist. 
If so no need to change/update them, just point out that they already exist and we will close the issue.

This is just to bring every SDK we have on par with all the methods available.

Check all the endpoints here and add the missing ones.

Untyped Arguments

Many kotlin sdk methods are untyped such as co.novu.dto.request.MarkMessageActionAsSeenRequest and
have an Any type or String.

It would make the kotlin sdk more useful and less error prone to use if the types were more strict in this case.

Unit Testing Triage: Issue while mocking Novu object

Hey folks, i am trying to write some UTs around my Novu service class. For that i am using mockito to mock the behavior of Novu. However, I am blocked because the APIs are marked as internal which makes is accessible only to its project scope. Any workaround i can do to mock Novu and do something like this:

@Mock
private lateinit var novu: Novu

@InjectMocks
private lateinit var notifService: NotifService

...

@Test
fun `test-success`() = runTest {
    whenever(novu.subscribers()).thenReturn(...)     <---------- this is where it throws NPE because subscriberApi isnt mocked and is internal
    notifService.getSubscribers()
}

Add Exponential Retry Mechanism with Idempotency Headers

In order to enhance the resilience and reliability of our SDK, we would like to introduce an Exponential Retry mechanism for retrying failed requests. Additionally, to ensure the idempotent processing of requests, it's vital to incorporate support for providing an Idempotency Key as per the draft specified in the HTTP Idempotency Key Header Field.

The key requirements for this implementation include:

  1. Exponential Retry Mechanism:

    • The SDK should retry failed requests following an exponential backoff strategy to minimize the contention and impact on the systems involved.
    • The SDK should ensure that the retry mechanism is configurable (e.g., max retries, initial delay, maximum delay).
  2. Idempotency Key Provisioning:

    • The SDK should allow for either automatic or manual provisioning of an Idempotency Key for each request.
    • The Idempotency Key should conform to either CUID, ULID, or UUID formats as specified in the draft.
    • The Idempotency Key should be included in the HTTP Header as Idempotency-Key and following the standards outlined in the draft.
  3. Configuration and Documentation:

    • The SDK should provide configuration options for enabling/disabling the Exponential Retry mechanism and Idempotency Key provisioning.
    • Comprehensive documentation should be provided explaining the configuration options, operational behavior, and the benefits of using the Exponential Retry mechanism along with Idempotency Keys.

Acceptance Criteria:

  • Implementation of the Exponential Retry mechanism with configurable parameters.
  • Provisioning of Idempotency Keys, either automatically or manually, conforming to specified formats (CUID, ULID, or UUID).
  • Adequate unit and integration testing to ensure the robustness and reliability of the implemented features.
  • Comprehensive documentation on the usage and configuration of the Exponential Retry mechanism and Idempotency Key provisioning.
  • Adherence to the specifications outlined in the HTTP Idempotency Key Header Field draft.

Update: You can reference the go-lang library to keep the method signature and configuration the same.
novuhq/go-novu#62

Please refer to the draft for further details on the HTTP Idempotency Key Header Field and ensure adherence to the specified standards while implementing this feature in the SDK.

Can't seem to trigger notification to a topic

Thanks for writing this SDK in Kotlin, it's amazing to see it supported as one of the first languages ❤️

I'm trying to figure out how to send a notification to a topic. In the docs it tells me to do this with the trigger endpoint but none of the constructor methods seems to allow for this input:

to: [{ type: 'Topic', topicKey: topicKey }],

Am I overlooking something or is this something that still needs to be added?

Add Missing Methods for Integrations

Some endpoints of the following section can't be hit from this SDK.

We would like to ensure that all endpoints can be hit. For this issue, we would like to build out the Integrations

Some of these methods may already exist. 
If so no need to change/update them, just point out that they already exist and we will close the issue.

This is just to bring every SDK we have on par with all the methods available.

Check all the endpoints here and add the missing ones.

Add Missing Methods for Environments

Some endpoints of the following section can't be hit from this SDK.

We would like to ensure that all endpoints can be hit. For this issue, we would like to build out the Environments

Some of these methods may already exist. 
If so no need to change/update them, just point out that they already exist and we will close the issue.

This is just to bring every SDK we have on par with all the methods available.

Check all the endpoints here and add the missing ones.

Add Missing Methods for Changes

Some endpoints of the following section can't be hit from this SDK.

We would like to ensure that all endpoints can be hit. For this issue, we would like to build out the Changes

Some of these methods may already exist. 
If so no need to change/update them, just point out that they already exist and we will close the issue.

This is just to bring every SDK we have on par with all the methods available.

Check all the endpoints here and add the missing ones.

Add Missing Methods for Notification templates

Some endpoints of the following section can't be hit from this SDK.

We would like to ensure that all endpoints can be hit. For this issue, we would like to build out the Notification templates

Some of these methods may already exist. 
If so no need to change/update them, just point out that they already exist and we will close the issue.

This is just to bring every SDK we have on par with all the methods available.

Check all the endpoints here and add the missing ones.

Add Missing Methods for Inbound Parse

Some endpoints of the following section can't be hit from this SDK.

We would like to ensure that all endpoints can be hit. For this issue, we would like to build out the Inbound Parse

Some of these methods may already exist. 
If so no need to change/update them, just point out that they already exist and we will close the issue.

This is just to bring every SDK we have on par with all the methods available.

Check all the endpoints here and add the missing ones.

Bulk trigger throw exception

I'm trying to use the Bulk Trigger functionality but I'm running into a 400 HTTP status code. Below is the log of the OkHTTPClient (with some stuff redacted or left out because it's not relevant).

To me it looks like the body should be an object with a key events which contains all the events. Now, the events are on the top level as an array.

--> POST https://api.novu.co/v1/events/trigger/bulk 
Content-Type: application/json; charset=UTF-8 
Content-Length: 195 
Authorization: ApiKey <REDACTED> 
 
[{"to":{"subscriberId":"ac88dd17-32bf-45a6-a863-48961525a87e"},"name":"simple","payload":{"redacted": "redacted"}}] 
--> END POST (195-byte body) 

<-- 400 https://api.novu.co/v1/events/trigger/bulk (694ms) 
date: Fri, 23 Jun 2023 13:24:44 GMT 
content-type: application/json; charset=utf-8 
content-length: 155 
...
 
{"statusCode":400,"message":["events must contain no more than 100 elements","events should not be empty","events must be an array"],"error":"Bad Request"} 
<-- END HTTP (155-byte body) 

MarkSubscriberFeed method throws exception

When calling the Novu#markSubscriberFeed method with a MarkSubscriberFeedAsRequestthe following exception is thrown:

java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 10 path $.data
	at com.google.gson.stream.JsonReader.beginObject(JsonReader.java:395)
	at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:259)
	at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:161)
	at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:266)
	at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:40)
	at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:27)
	at retrofit2.OkHttpCall.parseResponse(OkHttpCall.java:243)
	at retrofit2.OkHttpCall$1.onResponse(OkHttpCall.java:153)
	at okhttp3.internal.connection.RealCall$AsyncCall.run(RealCall.kt:519)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
	at java.base/java.lang.Thread.run(Thread.java:840)

Code snippet used:

 fun markNotificationAs(user: User, messageId: String, isRead: Boolean) {
        val markRequest = MarkSubscriberFeedAsRequest(
            messageId = messageId,
            mark = Mark(read = isRead, seen = true),
        )
        runBlocking {
            novu.markSubscriberFeed(user.id, markRequest)
        }
    }

Add User Agent Header

Add the user-agent request header to every call in this sdk.

Example:

headers: {
Authorization: Bearer ${ApiKey},
"User-Agent": novu/${sdk}@${version},
},

Why? (Context)

Having request headers in the SDKs will help us in monitoring which SDK is mostly used by the community and customers. It will help us make the decisions in the future on which SDKs to officially support in the future.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.