{"id":13781785,"url":"https://github.com/verful/adonis-notifications","last_synced_at":"2026-01-12T00:32:57.246Z","repository":{"id":47194729,"uuid":"461253466","full_name":"verful/adonis-notifications","owner":"verful","description":"Handle notifications on your AdonisJS applications","archived":false,"fork":false,"pushed_at":"2024-09-09T16:33:01.000Z","size":994,"stargazers_count":70,"open_issues_count":7,"forks_count":8,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-01-03T15:27:48.571Z","etag":null,"topics":["adonisjs","notifications","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/verful.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":".github/CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2022-02-19T16:50:16.000Z","updated_at":"2025-04-13T15:07:03.000Z","dependencies_parsed_at":"2023-12-28T04:28:06.715Z","dependency_job_id":"86b0e985-94c8-4613-a6b0-1441ea33d773","html_url":"https://github.com/verful/adonis-notifications","commit_stats":null,"previous_names":["verful/notifications"],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/verful/adonis-notifications","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/verful%2Fadonis-notifications","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/verful%2Fadonis-notifications/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/verful%2Fadonis-notifications/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/verful%2Fadonis-notifications/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/verful","download_url":"https://codeload.github.com/verful/adonis-notifications/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/verful%2Fadonis-notifications/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28329798,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-12T00:13:06.322Z","status":"ssl_error","status_checked_at":"2026-01-12T00:04:50.725Z","response_time":60,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["adonisjs","notifications","typescript"],"created_at":"2024-08-03T18:01:29.333Z","updated_at":"2026-01-12T00:32:57.228Z","avatar_url":"https://github.com/verful.png","language":"TypeScript","funding_links":[],"categories":["Packages"],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"https://github.com/verful/adonis-notifications/raw/main/.github/banner.png\" width=\"1200px\"\u003e\n\u003c/div\u003e\n\n\n\u003cdiv align=\"center\"\u003e\n  \u003ch2\u003e\u003cb\u003eAdonis Notifications\u003c/b\u003e\u003c/h2\u003e\n  \u003cp\u003eSend notifications with ease\u003c/p\u003e\n\u003c/div\u003e\n\n\u003cdiv align=\"center\"\u003e\n\n[![npm-image]][npm-url] [![license-image]][license-url] [![typescript-image]][typescript-url]\n\n\u003c/div\u003e\n\n\n## **Pre-requisites**\nThe `@verful/notifications` package requires `@adonisjs/core \u003e= 5.4.2`\n\nAlso, it relies on `@adonisjs/lucid \u003e= 16.3.2` for database notifications and on `@adonisjs/mail \u003e= 7.2.4` for mail notifications.\n\n## **Setup**\n\nInstall the package from the npm registry as follows.\n\n```\nnpm i @verful/notifications\n# or\nyarn add @verful/notifications\n```\n\nNext, configure the package by running the following ace command.\n\n```\nnode ace configure @verful/notifications\n```\n\n## **Generating Notifications**\nNotifications 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.\n\n\u003e `node ace make:notification TestNotification`\n\nThe 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.\n\n## **Sending Notifications**\n\nNotifications may be sent using the `notify` or the `notifyLater` methods of the `Notifiable` mixin, or using the `Notification` module.\n \n### **Using the Notifiable Mixin**\n\nFirst, apply the mixin on the model you are wanting to notify.\n\n```typescript\nimport { BaseModel } from '@ioc:Adonis/Lucid/Orm'\nimport { compose } from '@ioc:Adonis/Core/Helpers'\nimport { Notifiable } from '@ioc:Verful/Notification/Mixins'\n\n// Notifiable takes the notification table name as it's only param \nexport default class User extends compose(BaseModel, Notifiable('notifications')){\n}\n```\n\nThen use the `notify` or the `notifyLater` methods to notify the model.\n\n```typescript\nimport TestNotification from 'App/Notifications/TestNotification'\n\nuser.notify(new TestNotification())\n// Uses a in-memory queue to send the notification\nuser.notifyLater(new TestNotification())\n```\n\n### **Using the Notification module**\n\nYou 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.\n\n```typescript\nimport Notification from '@ioc:Verful/Notification'\n\nNotification.send(users, new TestNotification())\n```\n\nYou can also delay notifications using the `sendLater` method. This method uses a in-memory queue to send the notifications.\n\n```typescript\nimport Notification from '@ioc:Verful/Notification'\n\nNotification.sendLater(users, new TestNotification())\n```\n\n## **Specifying Delivery Channels**\n\nEvery notification class has a `via` method that determines which channels will be used to deliver the notification.\n\n\u003e If you want to use other delivery channels, you can build your own.\n\nThe `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.\n\n```typescript\nclass TestNotification implements NotificationContract {\n  public via(notifiable: User){\n    return notifiable.prefersEmail ? 'mail' : 'database'\n  }\n}\n```\n\n## **Delaying notifications**\n\nSending 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.\n\n## **Mail Notifications**\n\nIf 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\n\n\u003e If you want to use a mail driver other than default driver to send the notification, you can define it in the mailer class\n\n```typescript\nclass TestMailer extends BaseMailer {\n  constructor(private user: User){\n    super()\n  }\n\n  public prepare(message){\n    message\n      .subject('Test email')\n      .from('test@example.com')\n      .to(this.user.email)\n  }\n}\n\nclass TestNotification implements NotificationContract {\n  public toMail(notifiable: User){\n    return new TestMailer(notifiable)\n  }\n}\n```\n\n\u003e Mail notifications requires [@adonisjs/mail](https://github.com/adonisjs/mail)  \u003e= 7.2.4\n\n## **Database Notifications**\n\nThe `database` channel stores the notification in a database table. This table contain the notification, and a JSON object that describes the notification\n\n\u003e Database notifications requires [@adonisjs/lucid](https://github.com/adonisjs/lucid) \u003e= 16.3.2\n\nYou 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. \n\n```\nnode ace notifications:table\n\nnode ace migration:run\n```\n\n### **Sending Database Notifications**\nIf 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\n\n```typescript\nclass TestNotification implements NotificationContract {\n  public toDatabase(notifiable: User){\n    return {\n      title: `Hello, ${notifiable.email}, this is a test notification`\n    }\n  }\n}\n```\n\n### **Accessing the notifications**\n\nAfter 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.\n\n```typescript\nconst user = User.findOrFail(1)\n\nfor(const notification of await user.readNotifications()){\n  console.log(notification.data)\n}\n```\n\nIf you want to retrieve only the unread notifications, you may use the `unreadNotifications` method.\n\n```typescript\nconst user = User.findOrFail(1)\n\nfor(const notification of await user.unreadNotifications()){\n  console.log(notification.data)\n}\n```\n\n\u003e The notifications are normal Lucid Models, you can use anything that applies to a Lucid Model on them \n\n### **Marking notifications as read**\nTypically, 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:\n\n```typescript\nconst user = User.findOrFail(1)\n\nfor(const notification of await user.unreadNotifications()){\n  await notification.markAsRead();\n}\n```\n\nIf you want to mark all notifications of a user as read, you can use the `markNotificationsAsRead` method of the `Notifiable` mixin\n\n```typescript\nconst user = User.findOrFail(1)\n\nawait user.markNotificationsAsRead()\n```\n\n\u003e There is also `markAsRead` and `markNotificationsAsUnread` methods to mark notifications as unread.\n\n## **Custom Channels**\n\nYou may want to deliver notifications using other channels, for that, you can use any class that implements the `NotificationChannelContract`\n\n```typescript\nimport { NotificationChannelContract } from '@ioc:Verful/Notification'\n\ninterface VoiceMessageContract {\n  text: string\n}\n\nexport default class VoiceChannel implements NotificationChannelContract {\n  /**\n   * Typing the notification argument guarantees type safety in the toChannel\n   * method of the notification, in this case toVoice\n   */\n  public send(notification: VoiceMessageContract, notifiable: NotifiableModel){}\n}\n```\n\nAfter the channel is created, you must extend the `Notification` module, you can use a preload or a provider to do this\n\n```typescript\n// start/notification.ts\nimport Notification from '@ioc:Verful/Notification'\nimport VoiceChannel from 'App/Channels/VoiceChannel'\n\nNotification.extend('voice', () =\u003e new VoiceChannel())\n```\n\nThen you must setup the config and contract for your channel\n\n```typescript\n// config/notification.ts\n{\n  channels: {\n    voice: {\n      driver: 'voice'\n    }\n  }\n}\n\n// contracts/notification.ts\ninterface NotificationChannelsList {\n  voice: {\n    implementation: VoiceChannel\n    config: {\n      driver: 'voice'\n    }\n  }\n}\n```\n\n\n[npm-image]: https://img.shields.io/npm/v/@verful/notifications.svg?style=for-the-badge\u0026logo=npm\n[npm-url]: https://npmjs.org/package/@verful/notifications \"npm\"\n\n[license-image]: https://img.shields.io/npm/l/@verful/notifications?color=blueviolet\u0026style=for-the-badge\n[license-url]: LICENSE.md \"license\"\n\n[typescript-image]: https://img.shields.io/badge/Typescript-294E80.svg?style=for-the-badge\u0026logo=typescript\n[typescript-url]:  \"typescript\"\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fverful%2Fadonis-notifications","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fverful%2Fadonis-notifications","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fverful%2Fadonis-notifications/lists"}