notifkit 0.1.3 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. package/README.md +95 -79
  2. package/dist/index.d.mts +199 -135
  3. package/dist/index.d.mts.map +1 -1
  4. package/dist/index.mjs +1 -1
  5. package/dist/index.mjs.map +1 -1
  6. package/dist/{main-DtHWhueo.mjs → main-40zwq6b0.mjs} +28 -3
  7. package/dist/{main-DtHWhueo.mjs.map → main-40zwq6b0.mjs.map} +1 -1
  8. package/dist/{main-DyfbnJc3.mjs → main-BFre2-HQ.mjs} +2 -2
  9. package/dist/{main-DyfbnJc3.mjs.map → main-BFre2-HQ.mjs.map} +1 -1
  10. package/dist/{main-CAH0_Q6d.mjs → main-BNJtzY61.mjs} +3 -3
  11. package/dist/main-BNJtzY61.mjs.map +1 -0
  12. package/dist/{main-B561M1d3.mjs → main-BOPMYqsW.mjs} +2 -2
  13. package/dist/{main-B561M1d3.mjs.map → main-BOPMYqsW.mjs.map} +1 -1
  14. package/dist/{main-CCfc45ev.mjs → main-CiigNpsP.mjs} +7 -4
  15. package/dist/main-CiigNpsP.mjs.map +1 -0
  16. package/dist/{main-Ce9dcrsg.mjs → main-DeNFQ-UL.mjs} +6 -3
  17. package/dist/{main-Ce9dcrsg.mjs.map → main-DeNFQ-UL.mjs.map} +1 -1
  18. package/dist/{main-B-jwm8ED.mjs → main-DmCPcxOc.mjs} +2 -2
  19. package/dist/{main-B-jwm8ED.mjs.map → main-DmCPcxOc.mjs.map} +1 -1
  20. package/dist/{main-C45e7grq.mjs → main-DvgJSm11.mjs} +2 -2
  21. package/dist/{main-C45e7grq.mjs.map → main-DvgJSm11.mjs.map} +1 -1
  22. package/dist/{src-C-PfEDMY.mjs → src-vG79L-8m.mjs} +57 -26
  23. package/dist/src-vG79L-8m.mjs.map +1 -0
  24. package/drizzle/0002_wide_colleen_wing.sql +2 -0
  25. package/drizzle/0003_skinny_daimon_hellstrom.sql +1 -0
  26. package/drizzle/0004_pretty_bruce_banner.sql +1 -0
  27. package/drizzle/meta/0002_snapshot.json +1460 -0
  28. package/drizzle/meta/0003_snapshot.json +1460 -0
  29. package/drizzle/meta/0004_snapshot.json +1470 -0
  30. package/drizzle/meta/_journal.json +21 -0
  31. package/package.json +2 -1
  32. package/src/client.ts +412 -0
  33. package/src/config/index.ts +107 -0
  34. package/src/contracts/common.ts +28 -0
  35. package/src/contracts/envelope.ts +31 -0
  36. package/src/contracts/events/notification-ai-pending.ts +18 -0
  37. package/src/contracts/events/notification-canceled.ts +7 -0
  38. package/src/contracts/events/notification-created.ts +14 -0
  39. package/src/contracts/events/notification-delivered.ts +17 -0
  40. package/src/contracts/events/notification-dispatched.ts +45 -0
  41. package/src/contracts/events/notification-enriched.ts +46 -0
  42. package/src/contracts/events/notification-failed.ts +19 -0
  43. package/src/contracts/events/notification-requested.ts +36 -0
  44. package/src/contracts/events/notification-scheduled.ts +9 -0
  45. package/src/contracts/events/notification-skipped.ts +9 -0
  46. package/src/contracts/helpers.ts +21 -0
  47. package/src/contracts/index.ts +46 -0
  48. package/src/contracts/metadata.ts +10 -0
  49. package/src/contracts/registry.ts +88 -0
  50. package/src/contracts/sdk.ts +242 -0
  51. package/src/contracts/streams.ts +62 -0
  52. package/src/db/index.ts +69 -0
  53. package/src/db/schema.ts +412 -0
  54. package/src/idempotency/index.ts +50 -0
  55. package/src/index.ts +19 -0
  56. package/src/logger/index.ts +60 -0
  57. package/src/metrics/index.ts +53 -0
  58. package/src/queue/index.ts +501 -0
  59. package/src/rate-limiter/index.ts +210 -0
  60. package/src/redis/index.ts +89 -0
  61. package/src/repositories/index.ts +1246 -0
  62. package/src/server.ts +277 -0
  63. package/src/services/ai/main.ts +404 -0
  64. package/src/services/api/handlers.ts +1734 -0
  65. package/src/services/api/http.ts +64 -0
  66. package/src/services/api/main.ts +693 -0
  67. package/src/services/api/router.ts +82 -0
  68. package/src/services/delivery/main.ts +842 -0
  69. package/src/services/delivery/throttle.ts +71 -0
  70. package/src/services/engine/main.ts +827 -0
  71. package/src/services/enricher/main.ts +594 -0
  72. package/src/services/events/main.ts +365 -0
  73. package/src/services/scheduler/main.ts +319 -0
  74. package/src/services/workflow/main.ts +627 -0
  75. package/src/shared/batch-processor.ts +67 -0
  76. package/src/shared/cache.ts +47 -0
  77. package/src/shared/circuit-breaker.ts +74 -0
  78. package/src/shared/dataloader.ts +41 -0
  79. package/src/shared/events.ts +3 -0
  80. package/src/shared/index.ts +39 -0
  81. package/src/shared/semaphore.ts +33 -0
  82. package/src/shared/utils.ts +64 -0
  83. package/src/templates/cache.ts +32 -0
  84. package/src/templates/index.ts +69 -0
  85. package/src/templates/render.ts +128 -0
  86. package/src/transport/index.ts +96 -0
  87. package/src/unsubscribe/index.ts +127 -0
  88. package/src/workers/health.ts +31 -0
  89. package/src/workers/index.ts +266 -0
  90. package/src/workflows/index.ts +2 -0
  91. package/src/workflows/registry.ts +21 -0
  92. package/src/workflows/sdk.ts +106 -0
  93. package/dist/main-CAH0_Q6d.mjs.map +0 -1
  94. package/dist/main-CCfc45ev.mjs.map +0 -1
  95. package/dist/src-C-PfEDMY.mjs.map +0 -1
package/README.md CHANGED
@@ -6,7 +6,7 @@
6
6
 
7
7
  Self-hosted notification infrastructure for product notifications. One API call handles email, SMS, push, and webhooks — with preferences, quiet hours, retries, fallback, scheduling, workflows, and delivery logs built in.
8
8
 
9
- [![npm version](https://img.shields.io/npm/v/notifkit.svg?style=flat-square&color=6366f1)](https://www.npmjs.com/package/notifkit) [![npm downloads](https://img.shields.io/npm/dm/notifkit.svg?style=flat-square&color=6366f1)](https://www.npmjs.com/package/notifkit) [![Coverage](https://img.shields.io/badge/coverage-85%25-brightgreen.svg?style=flat-square)](https://github.com/devkitshq/notifkit) [![TypeScript](https://img.shields.io/badge/TypeScript-5.0+-3178c6.svg?style=flat-square)](https://www.typescriptlang.org/) [![Node.js](https://img.shields.io/badge/node-%3E%3D22.0.0-339933.svg?style=flat-square)](https://nodejs.org) [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square)](./LICENSE)
9
+ [![npm version](https://img.shields.io/npm/v/notifkit.svg?style=flat-square&color=6366f1)](https://www.npmjs.com/package/notifkit) [![npm downloads](https://img.shields.io/npm/dm/notifkit.svg?style=flat-square&color=6366f1)](https://www.npmjs.com/package/notifkit) [![Coverage](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/devkitshq/notifkit/badges/coverage.json&style=flat-square)](https://github.com/devkitshq/notifkit/actions/workflows/ci.yml) [![TypeScript](https://img.shields.io/badge/TypeScript-5.0+-3178c6.svg?style=flat-square)](https://www.typescriptlang.org/) [![Node.js](https://img.shields.io/badge/node-%3E%3D22.0.0-339933.svg?style=flat-square)](https://nodejs.org) [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square)](./LICENSE)
10
10
 
11
11
  [Documentation](https://notifkit.dev/docs/) · [Quickstart](https://notifkit.dev/docs/quickstart.html) · [Examples](https://notifkit.dev/docs/examples.html) · [notifkit.dev](https://notifkit.dev)
12
12
 
@@ -99,69 +99,61 @@ flowchart TD
99
99
 
100
100
  ---
101
101
 
102
- ## Battle-tested for production
102
+ ## Agent-operable
103
103
 
104
- > **Battle-tested in production:** notifkit powers production notification pipelines handling **thousands of emails, push notifications, and OTPs every day.**
105
- >
106
- > It is the infrastructure we built because we needed it ourselves — rather than spending months reinventing distributed notification plumbing or paying SaaS tolls per alert.
104
+ https://github.com/user-attachments/assets/4dff98bb-37d3-44b4-bf46-9607c1cd89b5
107
105
 
108
- **Your servers. Your providers. Your data. Zero notification SaaS markups.**
106
+ [▶️ Watch the AI demo](assets/ai_demo.mp4) - this is link to raw video file
109
107
 
110
- ### Reliability & Chaos Engineering
108
+ **notifkit isn't just an API your application can call — your AI agent can operate it directly.**
111
109
 
112
- Because notification delivery is mission-critical, every pipeline component is tested against extreme failure conditions:
110
+ Connect the notifkit MCP server ([`@notifkit/mcp`](./packages/mcp)) to Claude Code, Cursor, Claude Desktop, Gemini, or any MCP-compatible agent:
113
111
 
114
- ```mermaid
115
- flowchart LR
116
- S1["Redis Streams"] -->|"Kill Worker (SIGKILL)"| M1["Auto-Claim and Replay"] --> O1["Zero Lost Messages"]
117
- S2["Connection Loss"] -->|"Drop DB / Redis"| M2["Auto-Reconnect / Retry"] --> O2["In-Flight State Intact"]
118
- S3["10k+ Messages"] -->|"Burst"| M3["Concurrency and Limits"] --> O3["Flat Memory, No Leaks"]
112
+ ```bash
113
+ npx -y @notifkit/mcp
114
+ ```
119
115
 
120
- classDef fault stroke:#ef4444,stroke-width:2px
121
- classDef guard stroke:#6366f1,stroke-width:2px
122
- classDef result stroke:#22c55e,stroke-width:2px
123
- class S1,S2,S3 fault
124
- class M1,M2,M3 guard
125
- class O1,O2,O3 result
116
+ ### Ask your agent
117
+
118
+ ```text
119
+ You: Why didn't usr_9182 receive their password reset?
120
+
121
+ Agent: The notification was suppressed because usr_9182's email
122
+ address has a hard-bounce suppression from yesterday.
126
123
  ```
127
124
 
128
- - **Chaos Monkey Testing (`tests/chaos/crash.test.ts`)**: Background worker processes are randomly terminated with `SIGKILL` during active, high-throughput message streaming. Consumer group Pending Entries List (PEL) re-claims guarantee **zero lost messages** and seamless failover.
129
- - **Infrastructure Recovery Testing (`tests/chaos/recovery.test.ts`)**: PostgreSQL and Redis connections are forcefully severed and restored under live traffic. Verifies automatic client reconnection, worker backpressure, and durable state resumption.
130
- - **High-Throughput Load Testing (`tests/chaos/load.test.ts`)**: Stressed with bursts of **10,000+ notifications** across parallel worker pools, verifying queue drain velocity, sliding-window rate limiters, and flat memory profiles without leaks.
131
- - **Race Conditions & Concurrency (`tests/race-conditions.test.ts`, `tests/idempotency.test.ts`)**: Hardened against concurrent duplicate dispatches, overlapping quiet-hour boundary evaluations, atomic user updates, and 24-hour idempotency key deduplication.
132
- - **100% Real Ephemeral Containers**: Unit, integration, and chaos test suites execute against real PostgreSQL and Redis containers via [Testcontainers](https://testcontainers.com), eliminating mocks for core storage and streaming primitives.
125
+ Your application and your AI agents use the **same notification infrastructure**:
133
126
 
134
- ---
127
+ - **Send & dispatch** — Send one-off notifications or campaigns to users, lists, and segments (`send_notification`, `send_campaign`)
128
+ - **Investigate & triage** — Diagnose delivery issues by inspecting message histories, provider responses, and quiet hours (`get_delivery_logs`, `get_notification`)
129
+ - **Schedule & cancel** — Schedule future sends and cancel pending notifications (`list_scheduled`, `cancel_notification`)
130
+ - **Campaign analytics** — Check delivery, open, click, bounce, and complaint metrics (`list_campaigns`, `get_campaign_stats`)
131
+ - **Template management** — List, preview, and update templates with sample data (`list_templates`, `preview_template`, `upsert_template`)
132
+ - **Users & preferences** — Look up users, contacts, preferences, and segment membership (`list_users`, `get_user_preferences`, `update_user_preferences`)
133
+ - **Workflow operations** — Trigger workflows and inspect workflow runs (`create_workflow`, `trigger_workflow`, `get_workflow_run`)
134
+ - **Suppressions & health** — Manage bounce suppressions, check system queues, and replay dead-letter messages (`list_suppressions`, `get_dead_letters`, `replay_dead_letter`)
135
135
 
136
- ## What you get
136
+ ### From “write a script” to “just ask”
137
137
 
138
- | The problem you don't want to build | How notifkit solves it |
139
- | :------------------------------------------------------- | :------------------------------------------------------------------- |
140
- | **“Should this user receive it?”** | User preferences, topic opt-outs, and consent gates |
141
- | **“Is this a bad time to send?”** | Timezone-aware quiet hours that defer non-urgent sends |
142
- | **“What if push fails?”** | Automatic ordered multi-channel fallback (`push` → `email` → `sms`) |
143
- | **“What if my worker crashes?”** | Redis Streams consumer groups, retries, and durable idempotency |
144
- | **“What if an event fires twice?”** | 24-hour deduplication via idempotency keys |
145
- | **“Can I send this later?”** | Priority scheduling with `sendAt` and cancellation before dispatch |
146
- | **“Can I send this 3 days after signup?”** | Stateful multi-step workflows with `wait` and `waitForEvent` |
147
- | **“How do I know what happened?”** | Queryable delivery logs, Prometheus metrics, and campaign reporting |
148
- | **“What happens when a provider goes down?”** | Circuit breakers, exponential backoff, and DLQ replay |
149
- | **“What about bounces and spam complaints?”** | RFC 8058 one-click unsubscribe and automatic hard-bounce suppression |
150
- | **“What if I don't want another SaaS holding my data?”** | 100% self-hosted on your PostgreSQL and Redis |
138
+ | Without an agent | With NotifKit MCP |
139
+ | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
140
+ | Jump into the DB to find contact info → open Twilio/Resend or write a throwaway script → format the payload → check their timezone manually → fire it off → hope it delivered | **You:** _“Send an urgent update to alex@acme.com that his package was lost in transit and support is rushing a replacement — text him if push doesn't deliver.”_<br><br>**Agent:** Looks up `alex@acme.com` → renders template → dispatches push with SMS fallback → bypasses quiet hours for urgent delivery → tracks delivery status → confirms it hit his phone |
151
141
 
152
- > **The idea is simple:** You decide what to say. **notifkit handles getting it there reliably.**
142
+ [Set up MCP](https://notifkit.dev/docs/mcp.html) · [MCP documentation](https://notifkit.dev/docs/mcp.html)
153
143
 
154
144
  ---
155
145
 
156
- ## What notifkit is — and what it isn't
146
+ ## AI-assisted migration
157
147
 
158
- **What it is:** the durable notification infrastructure layer running directly inside your own stack.
148
+ Already have notification code scattered across your application?
159
149
 
160
- **What it isn't:** a marketing automation suite.
150
+ Point your coding agent at:
161
151
 
162
- notifkit is not Customer.io, OneSignal, or SendGrid. You bring your own provider accounts — your keys, your billing, your deliverability.
152
+ ```text
153
+ https://notifkit.dev/llms-full.txt
154
+ ```
163
155
 
164
- First-party providers ship for Resend and Firebase Cloud Messaging. Anything else is a simple `Transport` class with a `send()` method.
156
+ It can understand notifkit's API and help identify ad-hoc notification code in your repository and refactor it into durable notifkit calls.
165
157
 
166
158
  ---
167
159
 
@@ -233,57 +225,69 @@ curl -X POST http://localhost:3000/v1/notify \
233
225
 
234
226
  ---
235
227
 
236
- ## Agent-operable
228
+ ## Battle-tested for production
237
229
 
238
- **notifkit isn't just an API your application can call your AI agent can operate it directly.**
230
+ > **Battle-tested in production:** notifkit powers production notification pipelines handling **thousands of emails, push notifications, and OTPs every day.**
231
+ >
232
+ > It is the infrastructure we built because we needed it ourselves — rather than spending months reinventing distributed notification plumbing or paying SaaS tolls per alert.
239
233
 
240
- Connect the notifkit MCP server ([`@notifkit/mcp`](./packages/mcp)) to Claude Code, Cursor, Claude Desktop, Gemini, or any MCP-compatible agent:
234
+ **Your servers. Your providers. Your data. Zero notification SaaS markups.**
241
235
 
242
- ```bash
243
- npx -y @notifkit/mcp
244
- ```
236
+ ### Reliability & Chaos Engineering
245
237
 
246
- ### Ask your agent
238
+ Because notification delivery is mission-critical, every pipeline component is tested against extreme failure conditions:
247
239
 
248
- ```text
249
- You: Why didn't usr_9182 receive their password reset?
240
+ ```mermaid
241
+ flowchart LR
242
+ S1["Redis Streams"] -->|"Kill Worker (SIGKILL)"| M1["Auto-Claim and Replay"] --> O1["Zero Lost Messages"]
243
+ S2["Connection Loss"] -->|"Drop DB / Redis"| M2["Auto-Reconnect / Retry"] --> O2["In-Flight State Intact"]
244
+ S3["10k+ Messages"] -->|"Burst"| M3["Concurrency and Limits"] --> O3["Flat Memory, No Leaks"]
250
245
 
251
- Agent: The notification was suppressed because usr_9182's email
252
- address has a hard-bounce suppression from yesterday.
246
+ classDef fault stroke:#ef4444,stroke-width:2px
247
+ classDef guard stroke:#6366f1,stroke-width:2px
248
+ classDef result stroke:#22c55e,stroke-width:2px
249
+ class S1,S2,S3 fault
250
+ class M1,M2,M3 guard
251
+ class O1,O2,O3 result
253
252
  ```
254
253
 
255
- Your application and your AI agents use the **same notification infrastructure**:
254
+ - **Chaos Monkey Testing (`tests/chaos/crash.test.ts`)**: Background worker processes are randomly terminated with `SIGKILL` during active, high-throughput message streaming. Consumer group Pending Entries List (PEL) re-claims guarantee **zero lost messages** and seamless failover.
255
+ - **Infrastructure Recovery Testing (`tests/chaos/recovery.test.ts`)**: PostgreSQL and Redis connections are forcefully severed and restored under live traffic. Verifies automatic client reconnection, worker backpressure, and durable state resumption.
256
+ - **High-Throughput Load Testing (`tests/chaos/load.test.ts`)**: Stressed with bursts of **10,000+ notifications** across parallel worker pools, verifying queue drain velocity, sliding-window rate limiters, and flat memory profiles without leaks.
257
+ - **Race Conditions & Concurrency (`tests/race-conditions.test.ts`, `tests/idempotency.test.ts`)**: Hardened against concurrent duplicate dispatches, overlapping quiet-hour boundary evaluations, atomic user updates, and 24-hour idempotency key deduplication.
258
+ - **100% Real Ephemeral Containers**: Unit, integration, and chaos test suites execute against real PostgreSQL and Redis containers via [Testcontainers](https://testcontainers.com), eliminating mocks for core storage and streaming primitives.
256
259
 
257
- - **Send & dispatch** — Send one-off notifications or campaigns to users, lists, and segments (`send_notification`, `send_campaign`)
258
- - **Investigate & triage** — Diagnose delivery issues by inspecting message histories, provider responses, and quiet hours (`get_delivery_logs`, `get_notification`)
259
- - **Schedule & cancel** — Schedule future sends and cancel pending notifications (`list_scheduled`, `cancel_notification`)
260
- - **Campaign analytics** — Check delivery, open, click, bounce, and complaint metrics (`list_campaigns`, `get_campaign_stats`)
261
- - **Template management** — List, preview, and update templates with sample data (`list_templates`, `preview_template`, `upsert_template`)
262
- - **Users & preferences** — Look up users, contacts, preferences, and segment membership (`list_users`, `get_user_preferences`, `update_user_preferences`)
263
- - **Workflow operations** — Trigger workflows and inspect workflow runs (`create_workflow`, `trigger_workflow`, `get_workflow_run`)
264
- - **Suppressions & health** — Manage bounce suppressions, check system queues, and replay dead-letter messages (`list_suppressions`, `get_dead_letters`, `replay_dead_letter`)
260
+ ---
265
261
 
266
- ### From “write a script” to “just ask”
262
+ ## What you get
267
263
 
268
- | Without an agent | With NotifKit MCP |
269
- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
270
- | Jump into the DB to find contact info → open Twilio/Resend or write a throwaway script → format the payload → check their timezone manually → fire it off → hope it delivered | **You:** _“Send an urgent update to alex@acme.com that his package was lost in transit and support is rushing a replacement — text him if push doesn't deliver.”_<br><br>**Agent:** Looks up `alex@acme.com` → renders template → dispatches push with SMS fallback → bypasses quiet hours for urgent delivery → tracks delivery status → confirms it hit his phone |
264
+ | The problem you don't want to build | How notifkit solves it |
265
+ | :------------------------------------------------------- | :------------------------------------------------------------------- |
266
+ | **“Should this user receive it?”** | User preferences, topic opt-outs, and consent gates |
267
+ | **“Is this a bad time to send?”** | Timezone-aware quiet hours that defer non-urgent sends |
268
+ | **“What if push fails?”** | Automatic ordered multi-channel fallback (`push` → `email` → `sms`) |
269
+ | **“What if my worker crashes?”** | Redis Streams consumer groups, retries, and durable idempotency |
270
+ | **“What if an event fires twice?”** | 24-hour deduplication via idempotency keys |
271
+ | **“Can I send this later?”** | Priority scheduling with `sendAt` and cancellation before dispatch |
272
+ | **“Can I send this 3 days after signup?”** | Stateful multi-step workflows with `wait` and `waitForEvent` |
273
+ | **“How do I know what happened?”** | Queryable delivery logs, Prometheus metrics, and campaign reporting |
274
+ | **“What happens when a provider goes down?”** | Circuit breakers, exponential backoff, and DLQ replay |
275
+ | **“What about bounces and spam complaints?”** | RFC 8058 one-click unsubscribe and automatic hard-bounce suppression |
276
+ | **“What if I don't want another SaaS holding my data?”** | 100% self-hosted on your PostgreSQL and Redis |
271
277
 
272
- [Set up MCP](https://notifkit.dev/docs/mcp.html) · [MCP documentation](https://notifkit.dev/docs/mcp.html)
278
+ > **The idea is simple:** You decide what to say. **notifkit handles getting it there reliably.**
273
279
 
274
280
  ---
275
281
 
276
- ## AI-assisted migration
282
+ ## What notifkit is — and what it isn't
277
283
 
278
- Already have notification code scattered across your application?
284
+ **What it is:** the durable notification infrastructure layer running directly inside your own stack.
279
285
 
280
- Point your coding agent at:
286
+ **What it isn't:** a marketing automation suite.
281
287
 
282
- ```text
283
- https://notifkit.dev/llms-full.txt
284
- ```
288
+ notifkit is not Customer.io, OneSignal, or SendGrid. You bring your own provider accounts — your keys, your billing, your deliverability.
285
289
 
286
- It can understand notifkit's API and help identify ad-hoc notification code in your repository and refactor it into durable notifkit calls.
290
+ First-party providers ship for Resend and Firebase Cloud Messaging. Anything else is a simple `Transport` class with a `send()` method.
287
291
 
288
292
  ---
289
293
 
@@ -291,7 +295,7 @@ It can understand notifkit's API and help identify ad-hoc notification code in y
291
295
 
292
296
  | | |
293
297
  | :------------------ | :------------------------------------------------------------------------------------- |
294
- | **Channels** | `email`, `sms`, `push`, `webhook` |
298
+ | **Channels** | `email`, `sms`, `push`, `webhook`, `telegram`, `discord`, `whatsapp`, `slack` |
295
299
  | **Targeting** | A user, a list of users, a segment, or a topic |
296
300
  | **Priorities** | `low`, `normal`, `high`, `critical` — separate stream lanes |
297
301
  | **Scheduling** | Future sends with `sendAt`, quiet-hours deferral, cancellation |
@@ -316,13 +320,18 @@ First-party packages:
316
320
 
317
321
  - [`@notifkit/provider-resend`](./packages/provider-resend) — transactional email via Resend
318
322
  - [`@notifkit/provider-fcm`](./packages/provider-fcm) — push notifications via Firebase Cloud Messaging
323
+ - [`@notifkit/provider-slack`](./packages/provider-slack) — Slack messages via Incoming Webhooks or the Web API
324
+ - [`@notifkit/provider-twilio`](./packages/provider-twilio) — SMS via Twilio, with signature-verified delivery status callbacks
325
+ - [`@notifkit/provider-telegram`](./packages/provider-telegram) — messages via a Telegram bot
326
+ - [`@notifkit/provider-discord`](./packages/provider-discord) — messages via a Discord webhook
327
+ - [`@notifkit/provider-whatsapp`](./packages/provider-whatsapp) — messages via Meta's WhatsApp Cloud API
319
328
 
320
329
  For anything else, implement a simple `Transport`:
321
330
 
322
331
  ```ts
323
332
  class MyTransport implements Transport {
324
333
  async send(message) {
325
- // Send through Twilio, SES, Postmark, APNs,
334
+ // Send through SES, Postmark, APNs,
326
335
  // SendGrid, a custom webhook, or anything else.
327
336
  }
328
337
  }
@@ -382,6 +391,13 @@ npm test
382
391
 
383
392
  The test suite starts its own PostgreSQL and Redis containers, so Docker is the only thing you need running.
384
393
 
394
+ ## Contact
395
+
396
+ Questions, bugs, or ideas — mail me. I run this on my own company, which delivers a lot of notifications daily (100K+/day).
397
+
398
+ - **Email:** [contact.devkitshq@gmail.com](mailto:contact.devkitshq@gmail.com)
399
+ - **Book a 30-min call:** [calendly.com/contact-devkitshq/30min](https://calendly.com/contact-devkitshq/30min)
400
+
385
401
  ## License
386
402
 
387
403
  MIT. Do what you like with it, including commercially. See [LICENSE](./LICENSE).