Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/verful/adonis-notifications
Handle notifications on your AdonisJS applications
https://github.com/verful/adonis-notifications
adonisjs notifications typescript
Last synced: about 1 month ago
JSON representation
Handle notifications on your AdonisJS applications
- Host: GitHub
- URL: https://github.com/verful/adonis-notifications
- Owner: verful
- License: mit
- Created: 2022-02-19T16:50:16.000Z (almost 3 years ago)
- Default Branch: main
- Last Pushed: 2024-04-15T16:33:34.000Z (8 months ago)
- Last Synced: 2024-05-21T04:21:49.548Z (7 months ago)
- Topics: adonisjs, notifications, typescript
- Language: TypeScript
- Homepage:
- Size: 1.45 MB
- Stars: 64
- Watchers: 1
- Forks: 8
- Open Issues: 8
-
Metadata Files:
- Readme: README.md
- Contributing: .github/CONTRIBUTING.md
- License: LICENSE.md
Awesome Lists containing this project
- awesome-adonisjs - @verful/notifications - Notifications provider for Adonis 5. Inspired by Laravel Notifications (Packages)
README
Adonis Notifications
Send notifications with ease
[![npm-image]][npm-url] [![license-image]][license-url] [![typescript-image]][typescript-url]
## **Pre-requisites**
The `@verful/notifications` package requires `@adonisjs/core >= 5.4.2`Also, it relies on `@adonisjs/lucid >= 16.3.2` for database notifications and on `@adonisjs/mail >= 7.2.4` for mail notifications.
## **Setup**
Install the package from the npm registry as follows.
```
npm i @verful/notifications
# or
yarn add @verful/notifications
```Next, configure the package by running the following ace command.
```
node ace configure @verful/notifications
```## **Generating Notifications**
Notifications are represented by a simple class, generally stored in the `app/Notifications` directory. If you dont see the directory, dont worry, it will be created when you run the `make:notification` ace command.> `node ace make:notification TestNotification`
The command will create a notification class in the `app/Notifications` directory. Each notification class contains a `via` method and any number of message builder methods, like `toMail` or `toDatabase`, that convert the notification to a message made for that channel.
## **Sending Notifications**
Notifications may be sent using the `notify` or the `notifyLater` methods of the `Notifiable` mixin, or using the `Notification` module.
### **Using the Notifiable Mixin**First, apply the mixin on the model you are wanting to notify.
```typescript
import { BaseModel } from '@ioc:Adonis/Lucid/Orm'
import { compose } from '@ioc:Adonis/Core/Helpers'
import { Notifiable } from '@ioc:Verful/Notification/Mixins'// Notifiable takes the notification table name as it's only param
export default class User extends compose(BaseModel, Notifiable('notifications')){
}
```Then use the `notify` or the `notifyLater` methods to notify the model.
```typescript
import TestNotification from 'App/Notifications/TestNotification'user.notify(new TestNotification())
// Uses a in-memory queue to send the notification
user.notifyLater(new TestNotification())
```### **Using the Notification module**
You can also use the `Notification` module to send notifications. Sending notifications this way is useful when you need to send a notification to multiple notifiables, like a array of users.
```typescript
import Notification from '@ioc:Verful/Notification'Notification.send(users, new TestNotification())
```You can also delay notifications using the `sendLater` method. This method uses a in-memory queue to send the notifications.
```typescript
import Notification from '@ioc:Verful/Notification'Notification.sendLater(users, new TestNotification())
```## **Specifying Delivery Channels**
Every notification class has a `via` method that determines which channels will be used to deliver the notification.
> If you want to use other delivery channels, you can build your own.
The `via` method receives a `notifiable` instance, that is a instance of the class which the notification is being sent. You may use the `notifiable` to determine which channels to sent the notification to.
```typescript
class TestNotification implements NotificationContract {
public via(notifiable: User){
return notifiable.prefersEmail ? 'mail' : 'database'
}
}
```## **Delaying notifications**
Sending notifications can take some time, to ensure the notification doesn't block HTTP requests, you can use the `notifyLater` method of the `Notifiable` Mixin and the `sendLater` method of the `Notification` module to push notifications to a in-memory queue, ensuring that notifications will be sent after the http request ends.
## **Mail Notifications**
If you want to send a notification via e-mail, you should define a `toMail` method on the notification class. This method receives the `notifiable` entity and should return a [`BaseMailer`](https://github.com/adonisjs/mail/blob/develop/src/BaseMailer/index.ts) instance
> If you want to use a mail driver other than default driver to send the notification, you can define it in the mailer class
```typescript
class TestMailer extends BaseMailer {
constructor(private user: User){
super()
}public prepare(message){
message
.subject('Test email')
.from('[email protected]')
.to(this.user.email)
}
}class TestNotification implements NotificationContract {
public toMail(notifiable: User){
return new TestMailer(notifiable)
}
}
```> Mail notifications requires [@adonisjs/mail](https://github.com/adonisjs/mail) >= 7.2.4
## **Database Notifications**
The `database` channel stores the notification in a database table. This table contain the notification, and a JSON object that describes the notification
> Database notifications requires [@adonisjs/lucid](https://github.com/adonisjs/lucid) >= 16.3.2
You can query the table to display the notifications in your UI. But, before you can do that, you need to create a table to store the notifications. You may use the `notifications:table` ace command to generate a migration with the correct table schema.
```
node ace notifications:tablenode ace migration:run
```### **Sending Database Notifications**
If you want to store a notification in a database, you should define a `toDatabase` method on the notification class. This method receives the `notifiable` entity and should return a javascript object that can be transformed in JSON```typescript
class TestNotification implements NotificationContract {
public toDatabase(notifiable: User){
return {
title: `Hello, ${notifiable.email}, this is a test notification`
}
}
}
```### **Accessing the notifications**
After notifications are stored, you can acess them from your notifiable model entities. The `Notifiable` mixin includes a `notifications` Lucid relationship that returns the notifications for that entity. You can use the notifications like any other Lucid relationship. By default, the `readNotifications` and `unreadNotifications` methods will sort the notifications using the `created_at` timestamp, with the most recent at the beginning.
```typescript
const user = User.findOrFail(1)for(const notification of await user.readNotifications()){
console.log(notification.data)
}
```If you want to retrieve only the unread notifications, you may use the `unreadNotifications` method.
```typescript
const user = User.findOrFail(1)for(const notification of await user.unreadNotifications()){
console.log(notification.data)
}
```> The notifications are normal Lucid Models, you can use anything that applies to a Lucid Model on them
### **Marking notifications as read**
Typically, you will want to mark a notification as read when a user views it. The notification model provides a markAsRead method, which updates the read_at column on the notification's database record:```typescript
const user = User.findOrFail(1)for(const notification of await user.unreadNotifications()){
await notification.markAsRead();
}
```If you want to mark all notifications of a user as read, you can use the `markNotificationsAsRead` method of the `Notifiable` mixin
```typescript
const user = User.findOrFail(1)await user.markNotificationsAsRead()
```> There is also `markAsRead` and `markNotificationsAsUnread` methods to mark notifications as unread.
## **Custom Channels**
You may want to deliver notifications using other channels, for that, you can use any class that implements the `NotificationChannelContract`
```typescript
import { NotificationChannelContract } from '@ioc:Verful/Notification'interface VoiceMessageContract {
text: string
}export default class VoiceChannel implements NotificationChannelContract {
/**
* Typing the notification argument guarantees type safety in the toChannel
* method of the notification, in this case toVoice
*/
public send(notification: VoiceMessageContract, notifiable: NotifiableModel){}
}
```After the channel is created, you must extend the `Notification` module, you can use a preload or a provider to do this
```typescript
// start/notification.ts
import Notification from '@ioc:Verful/Notification'
import VoiceChannel from 'App/Channels/VoiceChannel'Notification.extend('voice', () => new VoiceChannel())
```Then you must setup the config and contract for your channel
```typescript
// config/notification.ts
{
channels: {
voice: {
driver: 'voice'
}
}
}// contracts/notification.ts
interface NotificationChannelsList {
voice: {
implementation: VoiceChannel
config: {
driver: 'voice'
}
}
}
```[npm-image]: https://img.shields.io/npm/v/@verful/notifications.svg?style=for-the-badge&logo=npm
[npm-url]: https://npmjs.org/package/@verful/notifications "npm"[license-image]: https://img.shields.io/npm/l/@verful/notifications?color=blueviolet&style=for-the-badge
[license-url]: LICENSE.md "license"[typescript-image]: https://img.shields.io/badge/Typescript-294E80.svg?style=for-the-badge&logo=typescript
[typescript-url]: "typescript"