@notik-app/node 0.1.0

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.
package/README.md ADDED
@@ -0,0 +1,106 @@
1
+ # @notik-app/node
2
+
3
+ Official Node.js SDK for [Notik](https://notik.app) — notification workflow platform.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @notik-app/node
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ ```typescript
14
+ import Notik from "@notik-app/node";
15
+
16
+ const notik = new Notik({ apiKey: "nk_live_..." });
17
+
18
+ // Trigger a workflow
19
+ const { executionId } = await notik.trigger({
20
+ workflow: "YOUR_WORKFLOW_ID",
21
+ data: {
22
+ driver_name: "Juan Garcia",
23
+ driver_phone: "+528331889752",
24
+ pickup_address: "Av. Constitución 500, Monterrey",
25
+ },
26
+ });
27
+
28
+ console.log(`Workflow triggered: ${executionId}`);
29
+ ```
30
+
31
+ ## Usage
32
+
33
+ ### API Key Trigger
34
+
35
+ The primary way to trigger workflows. Requires an API key from **Settings → API Keys** in the Notik dashboard.
36
+
37
+ ```typescript
38
+ const notik = new Notik({ apiKey: "nk_live_..." });
39
+
40
+ await notik.trigger({
41
+ workflow: "WORKFLOW_ID",
42
+ data: {
43
+ customer_name: "María López",
44
+ order_id: "ORD-5678",
45
+ delivery_eta: "2:30 PM",
46
+ },
47
+ });
48
+ ```
49
+
50
+ ### Webhook Trigger
51
+
52
+ Trigger webhook-type workflows directly. Supports optional HMAC-SHA256 signing.
53
+
54
+ ```typescript
55
+ await notik.triggerWebhook("WORKFLOW_ID", {
56
+ data: {
57
+ event: "order.shipped",
58
+ order_id: "ORD-1234",
59
+ tracking_url: "https://tracking.example.com/1234",
60
+ },
61
+ secret: "whsec_...", // optional, from workflow trigger config
62
+ });
63
+ ```
64
+
65
+ ## Configuration
66
+
67
+ ```typescript
68
+ const notik = new Notik({
69
+ apiKey: "nk_live_...", // Required
70
+ baseUrl: "https://notik.app", // Optional, defaults to https://notik.app
71
+ timeout: 30000, // Optional, request timeout in ms
72
+ });
73
+ ```
74
+
75
+ ## Error Handling
76
+
77
+ ```typescript
78
+ import Notik, { NotikAPIError } from "@notik-app/node";
79
+
80
+ try {
81
+ await notik.trigger({ workflow: "wf-123", data: {} });
82
+ } catch (err) {
83
+ if (err instanceof NotikAPIError) {
84
+ console.error(err.message); // "Rate limit exceeded"
85
+ console.error(err.status); // 429
86
+ console.error(err.code); // "RATE_LIMITED"
87
+ }
88
+ }
89
+ ```
90
+
91
+ ### Error Codes
92
+
93
+ | Code | Status | Description |
94
+ |------|--------|-------------|
95
+ | `UNAUTHORIZED` | 401 | Invalid or missing API key |
96
+ | `RATE_LIMITED` | 429 | Too many requests |
97
+ | `API_ERROR` | 4xx/5xx | Other API errors |
98
+
99
+ ## Requirements
100
+
101
+ - Node.js 18+ (uses native `fetch`)
102
+ - No external dependencies
103
+
104
+ ## License
105
+
106
+ MIT
@@ -0,0 +1,74 @@
1
+ export interface NotikConfig {
2
+ /** API key from Notik dashboard (Settings → API Keys) */
3
+ apiKey: string;
4
+ /** Base URL of your Notik instance. Defaults to https://notik.app */
5
+ baseUrl?: string;
6
+ /** Request timeout in milliseconds. Defaults to 30000 */
7
+ timeout?: number;
8
+ }
9
+ export interface TriggerOptions {
10
+ /** Workflow ID to trigger */
11
+ workflow: string;
12
+ /** Data payload — available as {{triggerData.fieldName}} in templates */
13
+ data: Record<string, unknown>;
14
+ }
15
+ export interface WebhookTriggerOptions {
16
+ /** Data payload */
17
+ data: Record<string, unknown>;
18
+ /** Webhook secret for HMAC signing (from workflow trigger config) */
19
+ secret?: string;
20
+ }
21
+ export interface TriggerResponse {
22
+ executionId: string;
23
+ }
24
+ export interface NotikError {
25
+ error: string;
26
+ status: number;
27
+ }
28
+ export declare class NotikAPIError extends Error {
29
+ status: number;
30
+ code: string;
31
+ constructor(message: string, status: number);
32
+ }
33
+ export declare class Notik {
34
+ private apiKey;
35
+ private baseUrl;
36
+ private timeout;
37
+ constructor(config: NotikConfig);
38
+ /**
39
+ * Trigger a workflow via API key authentication.
40
+ *
41
+ * @example
42
+ * ```typescript
43
+ * const notik = new Notik({ apiKey: "nk_live_..." });
44
+ *
45
+ * const { executionId } = await notik.trigger({
46
+ * workflow: "682abc123def456",
47
+ * data: {
48
+ * driver_name: "Juan Garcia",
49
+ * driver_phone: "+528331889752",
50
+ * pickup_address: "Av. Constitución 500, Monterrey"
51
+ * }
52
+ * });
53
+ * ```
54
+ */
55
+ trigger(options: TriggerOptions): Promise<TriggerResponse>;
56
+ /**
57
+ * Trigger a webhook workflow directly by workflow ID.
58
+ * Optionally signs the request with HMAC-SHA256.
59
+ *
60
+ * @example
61
+ * ```typescript
62
+ * const notik = new Notik({ apiKey: "nk_live_..." });
63
+ *
64
+ * const { executionId } = await notik.triggerWebhook("682abc123def456", {
65
+ * data: { order_id: "ORD-1234", status: "shipped" },
66
+ * secret: "whsec_..." // optional
67
+ * });
68
+ * ```
69
+ */
70
+ triggerWebhook(workflowId: string, options: WebhookTriggerOptions): Promise<TriggerResponse>;
71
+ private request;
72
+ }
73
+ export default Notik;
74
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,WAAW;IAC1B,yDAAyD;IACzD,MAAM,EAAE,MAAM,CAAC;IACf,qEAAqE;IACrE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,yDAAyD;IACzD,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,6BAA6B;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,yEAAyE;IACzE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B;AAED,MAAM,WAAW,qBAAqB;IACpC,mBAAmB;IACnB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,qEAAqE;IACrE,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,aAAc,SAAQ,KAAK;IACtC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;gBAED,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;CAM5C;AAED,qBAAa,KAAK;IAChB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,OAAO,CAAS;gBAEZ,MAAM,EAAE,WAAW;IAU/B;;;;;;;;;;;;;;;;OAgBG;IACG,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,CAAC;IAgBhE;;;;;;;;;;;;;OAaG;IACG,cAAc,CAClB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,eAAe,CAAC;YAuBb,OAAO;CA0CtB;AAED,eAAe,KAAK,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,129 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.Notik = exports.NotikAPIError = void 0;
7
+ const crypto_1 = __importDefault(require("crypto"));
8
+ class NotikAPIError extends Error {
9
+ status;
10
+ code;
11
+ constructor(message, status) {
12
+ super(message);
13
+ this.name = "NotikAPIError";
14
+ this.status = status;
15
+ this.code = status === 429 ? "RATE_LIMITED" : status === 401 ? "UNAUTHORIZED" : "API_ERROR";
16
+ }
17
+ }
18
+ exports.NotikAPIError = NotikAPIError;
19
+ class Notik {
20
+ apiKey;
21
+ baseUrl;
22
+ timeout;
23
+ constructor(config) {
24
+ if (!config.apiKey) {
25
+ throw new Error("Notik: apiKey is required");
26
+ }
27
+ this.apiKey = config.apiKey;
28
+ this.baseUrl = (config.baseUrl || "https://notik.app").replace(/\/$/, "");
29
+ this.timeout = config.timeout || 30_000;
30
+ }
31
+ /**
32
+ * Trigger a workflow via API key authentication.
33
+ *
34
+ * @example
35
+ * ```typescript
36
+ * const notik = new Notik({ apiKey: "nk_live_..." });
37
+ *
38
+ * const { executionId } = await notik.trigger({
39
+ * workflow: "682abc123def456",
40
+ * data: {
41
+ * driver_name: "Juan Garcia",
42
+ * driver_phone: "+528331889752",
43
+ * pickup_address: "Av. Constitución 500, Monterrey"
44
+ * }
45
+ * });
46
+ * ```
47
+ */
48
+ async trigger(options) {
49
+ const res = await this.request("/api/v1/trigger", {
50
+ method: "POST",
51
+ headers: {
52
+ "Content-Type": "application/json",
53
+ Authorization: `Bearer ${this.apiKey}`,
54
+ },
55
+ body: JSON.stringify({
56
+ workflow: options.workflow,
57
+ payload: options.data,
58
+ }),
59
+ });
60
+ return res;
61
+ }
62
+ /**
63
+ * Trigger a webhook workflow directly by workflow ID.
64
+ * Optionally signs the request with HMAC-SHA256.
65
+ *
66
+ * @example
67
+ * ```typescript
68
+ * const notik = new Notik({ apiKey: "nk_live_..." });
69
+ *
70
+ * const { executionId } = await notik.triggerWebhook("682abc123def456", {
71
+ * data: { order_id: "ORD-1234", status: "shipped" },
72
+ * secret: "whsec_..." // optional
73
+ * });
74
+ * ```
75
+ */
76
+ async triggerWebhook(workflowId, options) {
77
+ const body = JSON.stringify(options.data);
78
+ const headers = {
79
+ "Content-Type": "application/json",
80
+ };
81
+ if (options.secret) {
82
+ const signature = crypto_1.default
83
+ .createHmac("sha256", options.secret)
84
+ .update(body)
85
+ .digest("hex");
86
+ headers["x-notik-signature"] = signature;
87
+ }
88
+ const res = await this.request(`/api/webhooks/${workflowId}`, {
89
+ method: "POST",
90
+ headers,
91
+ body,
92
+ });
93
+ return res;
94
+ }
95
+ async request(path, init) {
96
+ const url = `${this.baseUrl}${path}`;
97
+ const controller = new AbortController();
98
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
99
+ try {
100
+ const res = await fetch(url, {
101
+ ...init,
102
+ signal: controller.signal,
103
+ headers: {
104
+ "User-Agent": "notik-node/0.1.0",
105
+ ...init.headers,
106
+ },
107
+ });
108
+ const data = (await res.json());
109
+ if (!res.ok) {
110
+ throw new NotikAPIError(data.error || `Request failed with status ${res.status}`, res.status);
111
+ }
112
+ return data;
113
+ }
114
+ catch (err) {
115
+ if (err instanceof NotikAPIError)
116
+ throw err;
117
+ if (err instanceof Error && err.name === "AbortError") {
118
+ throw new NotikAPIError("Request timed out", 408);
119
+ }
120
+ throw new NotikAPIError(err instanceof Error ? err.message : "Unknown error", 500);
121
+ }
122
+ finally {
123
+ clearTimeout(timeoutId);
124
+ }
125
+ }
126
+ }
127
+ exports.Notik = Notik;
128
+ exports.default = Notik;
129
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "@notik-app/node",
3
+ "version": "0.1.0",
4
+ "description": "Official Node.js SDK for Notik — notification workflow platform",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "files": [
8
+ "dist"
9
+ ],
10
+ "scripts": {
11
+ "build": "tsc",
12
+ "prepublishOnly": "npm run build",
13
+ "test": "vitest run"
14
+ },
15
+ "keywords": [
16
+ "notik",
17
+ "notifications",
18
+ "whatsapp",
19
+ "email",
20
+ "push",
21
+ "workflows"
22
+ ],
23
+ "author": "Notik <hello@notik.app>",
24
+ "license": "MIT",
25
+ "repository": {
26
+ "type": "git",
27
+ "url": "https://github.com/notik-app/notik-node.git"
28
+ },
29
+ "homepage": "https://notik.app",
30
+ "engines": {
31
+ "node": ">=18.0.0"
32
+ },
33
+ "devDependencies": {
34
+ "@types/node": "^25.3.3",
35
+ "typescript": "^5.7.0",
36
+ "vitest": "^3.0.0"
37
+ }
38
+ }