@kirimdev/sdk 2.0.1 → 3.0.1
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 +42 -8
- package/dist/client.js +1 -1
- package/dist/client.js.map +1 -1
- package/dist/errors.d.ts +12 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +12 -1
- package/dist/errors.js.map +1 -1
- package/dist/webhooks.d.ts +84 -83
- package/dist/webhooks.d.ts.map +1 -1
- package/dist/webhooks.js +102 -41
- package/dist/webhooks.js.map +1 -1
- package/openapi.json +68 -47
- package/package.json +63 -63
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @kirimdev/sdk
|
|
2
2
|
|
|
3
|
-
Official TypeScript SDK for the [
|
|
3
|
+
Official TypeScript SDK for the [Kirimdev](https://kirimdev.com) Public API.
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
@@ -17,27 +17,61 @@ import { Kirim } from '@kirimdev/sdk'
|
|
|
17
17
|
|
|
18
18
|
const kirim = new Kirim({ apiKey: process.env.KIRIM_API_KEY! })
|
|
19
19
|
|
|
20
|
+
// Scope to a WhatsApp phone number (Meta `business_phone_number_id`).
|
|
21
|
+
// Look it up via `kirim.accounts.list()` if you don't have it handy.
|
|
22
|
+
const phone = kirim.phoneNumbers('106540352242922')
|
|
23
|
+
|
|
20
24
|
// Send a message
|
|
21
|
-
const msg = await
|
|
25
|
+
const msg = await phone.messages.send({
|
|
22
26
|
to: '628123456789',
|
|
23
27
|
type: 'text',
|
|
24
28
|
text: { body: 'Halo dari SDK!' },
|
|
25
29
|
})
|
|
26
30
|
|
|
27
31
|
// Paginate
|
|
28
|
-
for await (const m of
|
|
32
|
+
for await (const m of phone.messages.list({ limit: 50 })) {
|
|
29
33
|
console.log(m.id, m.status)
|
|
30
34
|
}
|
|
35
|
+
```
|
|
31
36
|
|
|
32
|
-
|
|
33
|
-
import { verifyWebhookSignature } from '@kirimdev/sdk/webhooks'
|
|
37
|
+
## Webhook verification
|
|
34
38
|
|
|
35
|
-
|
|
39
|
+
`verifyWebhookSignature` parses the `X-Kirim-Signature` header (Stripe-style
|
|
40
|
+
`t=<unix>,v1=<hex>` format), checks the timestamp against a tolerance window,
|
|
41
|
+
verifies the HMAC-SHA256 against one or more active secrets (supports rotation),
|
|
42
|
+
and returns the parsed JSON body. It **throws** on every failure mode — never
|
|
43
|
+
returns `false`. Uses Web Crypto so it runs unchanged on Node 18+, Bun, Deno,
|
|
44
|
+
and edge runtimes.
|
|
45
|
+
|
|
46
|
+
```ts
|
|
47
|
+
import { verifyWebhookSignature, InvalidSignatureError } from '@kirimdev/sdk/webhooks'
|
|
48
|
+
|
|
49
|
+
export async function POST(req: Request) {
|
|
50
|
+
const rawBody = await req.text()
|
|
51
|
+
try {
|
|
52
|
+
const event = await verifyWebhookSignature({
|
|
53
|
+
rawBody,
|
|
54
|
+
signatureHeader: req.headers.get('x-kirim-signature'),
|
|
55
|
+
secrets: [process.env.KIRIM_WEBHOOK_SECRET!],
|
|
56
|
+
})
|
|
57
|
+
// event is KirimWebhookEvent — narrow on event.type or event.object
|
|
58
|
+
return new Response('ok')
|
|
59
|
+
} catch (err) {
|
|
60
|
+
if (err instanceof InvalidSignatureError) return new Response('bad sig', { status: 401 })
|
|
61
|
+
throw err
|
|
62
|
+
}
|
|
63
|
+
}
|
|
36
64
|
```
|
|
37
65
|
|
|
66
|
+
Errors thrown (all extend `KirimWebhookError`):
|
|
67
|
+
|
|
68
|
+
- `InvalidSignatureError` — header missing/malformed, or no `v1=` matched any provided secret
|
|
69
|
+
- `SignatureExpiredError` — `|now - t|` exceeds `toleranceSeconds` (default 300s)
|
|
70
|
+
- `MalformedPayloadError` — signature matched but body is not valid JSON
|
|
71
|
+
|
|
38
72
|
## Features
|
|
39
73
|
|
|
40
|
-
- Full coverage of the
|
|
74
|
+
- Full coverage of the Kirimdev `/v1` API (~35 endpoints)
|
|
41
75
|
- Type-safe — generated from the live OpenAPI 3.1 spec
|
|
42
76
|
- Automatic retries with exponential backoff (429, 5xx, network errors)
|
|
43
77
|
- Automatic `Idempotency-Key` injection for POST requests
|
|
@@ -51,7 +85,7 @@ const ok = verifyWebhookSignature(rawBody, req.headers['x-kirim-signature'], sec
|
|
|
51
85
|
```ts
|
|
52
86
|
new Kirim({
|
|
53
87
|
apiKey: 'kdv_live_...', // required
|
|
54
|
-
baseUrl: 'https://api.
|
|
88
|
+
baseUrl: 'https://api.kirimdev.com/v1', // optional
|
|
55
89
|
timeout: 30_000, // ms, default 30s
|
|
56
90
|
maxRetries: 2, // default 2
|
|
57
91
|
fetch: globalThis.fetch, // injectable for testing
|
package/dist/client.js
CHANGED
|
@@ -24,7 +24,7 @@ import { PhoneNumberClient } from './resources/phone-number.js';
|
|
|
24
24
|
import { WebhookDeliveriesResource } from './resources/webhook-deliveries.js';
|
|
25
25
|
import { WebhookSubscriptionsResource } from './resources/webhook-subscriptions.js';
|
|
26
26
|
export const SDK_VERSION = '2.0.0';
|
|
27
|
-
const DEFAULT_BASE_URL = 'https://api.
|
|
27
|
+
const DEFAULT_BASE_URL = 'https://api.kirimdev.com/v1';
|
|
28
28
|
const DEFAULT_TIMEOUT_MS = 30_000;
|
|
29
29
|
const DEFAULT_MAX_RETRIES = 2;
|
|
30
30
|
export class Kirim {
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EAAE,UAAU,EAA0C,MAAM,WAAW,CAAA;AAC9E,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAA;AAC/D,OAAO,EAAE,yBAAyB,EAAE,MAAM,mCAAmC,CAAA;AAC7E,OAAO,EAAE,4BAA4B,EAAE,MAAM,sCAAsC,CAAA;AAGnF,MAAM,CAAC,MAAM,WAAW,GAAG,OAAO,CAAA;AAClC,MAAM,gBAAgB,GAAG,
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/errors.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* HTTP error class hierarchy for `@kirimdev/sdk`.
|
|
3
3
|
*
|
|
4
4
|
* Every HTTP error from the Kirim API is mapped to a subclass of
|
|
5
5
|
* `KirimError`. Network/timeout failures throw `ConnectionError`. The
|
|
@@ -8,6 +8,17 @@
|
|
|
8
8
|
* specific stable identifier.
|
|
9
9
|
*
|
|
10
10
|
* Source of truth for codes: `apps/api/src/lib/api-error.ts` (ERROR_CATALOG).
|
|
11
|
+
*
|
|
12
|
+
* NOTE: Webhook signature verification errors live in a SEPARATE hierarchy
|
|
13
|
+
* rooted at `KirimWebhookError` (see `@kirimdev/sdk/webhooks`). They do
|
|
14
|
+
* not extend `KirimError` because they carry no HTTP shape — no
|
|
15
|
+
* `requestId`, `status`, or `type`. Consumers wanting to catch both must
|
|
16
|
+
* catch each base class separately, or use a union check:
|
|
17
|
+
*
|
|
18
|
+
* catch (e) {
|
|
19
|
+
* if (e instanceof KirimError) {...}
|
|
20
|
+
* else if (e instanceof KirimWebhookError) {...}
|
|
21
|
+
* }
|
|
11
22
|
*/
|
|
12
23
|
export type KirimErrorType = 'invalid_request_error' | 'authentication_error' | 'permission_error' | 'not_found' | 'conflict' | 'rate_limit_error' | 'api_error' | 'connection_error';
|
|
13
24
|
export interface KirimErrorPayload {
|
package/dist/errors.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,MAAM,MAAM,cAAc,GACtB,uBAAuB,GACvB,sBAAsB,GACtB,kBAAkB,GAClB,WAAW,GACX,UAAU,GACV,kBAAkB,GAClB,WAAW,GACX,kBAAkB,CAAA;AAEtB,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,cAAc,CAAA;IACpB,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC1B,6CAA6C;IAC7C,GAAG,CAAC,EAAE,OAAO,CAAA;CACd;AAED,4DAA4D;AAC5D,qBAAa,UAAW,SAAQ,KAAK;IACnC,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAA;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACjC,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAA;IAClC,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAA;gBAET,OAAO,EAAE,iBAAiB;CAUvC;AAED,qBAAa,mBAAoB,SAAQ,UAAU;gBACrC,OAAO,EAAE,iBAAiB;CAIvC;AAED,qBAAa,mBAAoB,SAAQ,UAAU;gBACrC,OAAO,EAAE,iBAAiB;CAIvC;AAED,qBAAa,eAAgB,SAAQ,UAAU;gBACjC,OAAO,EAAE,iBAAiB;CAIvC;AAED,qBAAa,aAAc,SAAQ,UAAU;gBAC/B,OAAO,EAAE,iBAAiB;CAIvC;AAED,qBAAa,aAAc,SAAQ,UAAU;gBAC/B,OAAO,EAAE,iBAAiB;CAIvC;AAED,qBAAa,cAAe,SAAQ,UAAU;IAC5C,yEAAyE;IACzE,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;gBACtB,OAAO,EAAE,iBAAiB,GAAG;QAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE;CAKvE;AAED,qBAAa,cAAe,SAAQ,UAAU;gBAChC,OAAO,EAAE,iBAAiB;CAIvC;AAED,6DAA6D;AAC7D,qBAAa,eAAgB,SAAQ,UAAU;IAC7C,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;gBACX,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO;CAW5C;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,OAAO,EACb,SAAS,EAAE,MAAM,GAAG,IAAI,EACxB,iBAAiB,EAAE,MAAM,GAAG,IAAI,GAC/B,UAAU,CAiCZ"}
|
package/dist/errors.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* HTTP error class hierarchy for `@kirimdev/sdk`.
|
|
3
3
|
*
|
|
4
4
|
* Every HTTP error from the Kirim API is mapped to a subclass of
|
|
5
5
|
* `KirimError`. Network/timeout failures throw `ConnectionError`. The
|
|
@@ -8,6 +8,17 @@
|
|
|
8
8
|
* specific stable identifier.
|
|
9
9
|
*
|
|
10
10
|
* Source of truth for codes: `apps/api/src/lib/api-error.ts` (ERROR_CATALOG).
|
|
11
|
+
*
|
|
12
|
+
* NOTE: Webhook signature verification errors live in a SEPARATE hierarchy
|
|
13
|
+
* rooted at `KirimWebhookError` (see `@kirimdev/sdk/webhooks`). They do
|
|
14
|
+
* not extend `KirimError` because they carry no HTTP shape — no
|
|
15
|
+
* `requestId`, `status`, or `type`. Consumers wanting to catch both must
|
|
16
|
+
* catch each base class separately, or use a union check:
|
|
17
|
+
*
|
|
18
|
+
* catch (e) {
|
|
19
|
+
* if (e instanceof KirimError) {...}
|
|
20
|
+
* else if (e instanceof KirimWebhookError) {...}
|
|
21
|
+
* }
|
|
11
22
|
*/
|
|
12
23
|
/** Base class. All errors thrown by the SDK extend this. */
|
|
13
24
|
export class KirimError extends Error {
|
package/dist/errors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
|
package/dist/webhooks.d.ts
CHANGED
|
@@ -1,100 +1,101 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Webhook HMAC verification + typed event payloads.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* header. This module exposes a constant-time verifier using Web Crypto
|
|
7
|
-
* (`crypto.subtle`) so it runs on Node 18+, Bun, Deno, and edge runtimes.
|
|
4
|
+
* Kirim signs outbound webhook deliveries using a Stripe-style header
|
|
5
|
+
* format mirroring `apps/worker/src/jobs/webhook-delivery/sign.ts`:
|
|
8
6
|
*
|
|
9
|
-
*
|
|
7
|
+
* X-Kirim-Signature: t=<unix_seconds>,v1=<hex>[,v1=<hex>...]
|
|
10
8
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
9
|
+
* - `t` is the time the signature was computed; callers reject when
|
|
10
|
+
* |now - t| exceeds `toleranceSeconds` (default 5 minutes).
|
|
11
|
+
* - Each `v1=` is HMAC-SHA256 of `${t}.${rawBody}` under one ACTIVE
|
|
12
|
+
* signing secret. During rotation a subscription may have multiple
|
|
13
|
+
* active secrets and the header carries one `v1=` per secret —
|
|
14
|
+
* verification passes if ANY caller-supplied secret matches ANY
|
|
15
|
+
* `v1=` value.
|
|
13
16
|
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* req.headers.get('x-kirim-signature') ?? '',
|
|
17
|
-
* process.env.KIRIM_WEBHOOK_SECRET!,
|
|
18
|
-
* )
|
|
19
|
-
* if (!ok) return new Response('bad signature', { status: 401 })
|
|
20
|
-
*/
|
|
21
|
-
/**
|
|
22
|
-
* Verify a Kirim webhook signature.
|
|
23
|
-
*
|
|
24
|
-
* MUST be called with the raw request body (the same bytes Kirim signed —
|
|
25
|
-
* re-serializing JSON will break the signature). Returns `false` (never
|
|
26
|
-
* throws) when the header is absent / malformed / mismatched. The caller
|
|
27
|
-
* MUST reject the request when this returns `false` (fail-closed).
|
|
28
|
-
*/
|
|
29
|
-
export declare function verifyWebhookSignature(body: string, signatureHeader: string | null | undefined, secret: string): Promise<boolean>;
|
|
30
|
-
/**
|
|
31
|
-
* Discriminated union of all event types Kirim can deliver to a webhook
|
|
32
|
-
* subscription. The `type` literal is the discriminator.
|
|
17
|
+
* Uses Web Crypto (`crypto.subtle`) so this module runs unchanged on
|
|
18
|
+
* Node 18+, Bun, Deno, and edge runtimes.
|
|
33
19
|
*
|
|
34
|
-
* The
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
* `
|
|
20
|
+
* The error classes in this module (`KirimWebhookError`,
|
|
21
|
+
* `InvalidSignatureError`, `SignatureExpiredError`,
|
|
22
|
+
* `MalformedPayloadError`) form a SEPARATE hierarchy from the HTTP
|
|
23
|
+
* `KirimError` tree in `@kirimdev/sdk` — webhook errors carry no
|
|
24
|
+
* `requestId` / `status` / `code` because they fire before any HTTP
|
|
25
|
+
* round-trip. Consumers wanting a single catch surface should branch
|
|
26
|
+
* on `instanceof KirimWebhookError` separately from `instanceof
|
|
27
|
+
* KirimError`.
|
|
38
28
|
*/
|
|
39
|
-
export
|
|
40
|
-
|
|
41
|
-
id: string;
|
|
42
|
-
created_at: string;
|
|
43
|
-
/** Subscription id that triggered the delivery. */
|
|
44
|
-
subscription_id: string;
|
|
29
|
+
export declare class KirimWebhookError extends Error {
|
|
30
|
+
constructor(message: string);
|
|
45
31
|
}
|
|
46
|
-
export
|
|
47
|
-
|
|
48
|
-
data: {
|
|
49
|
-
id: string;
|
|
50
|
-
object: 'message';
|
|
51
|
-
conversation_id?: string;
|
|
52
|
-
to: string;
|
|
53
|
-
type: string;
|
|
54
|
-
status: string;
|
|
55
|
-
created_at: string;
|
|
56
|
-
};
|
|
32
|
+
export declare class InvalidSignatureError extends KirimWebhookError {
|
|
33
|
+
constructor(message?: string);
|
|
57
34
|
}
|
|
58
|
-
export
|
|
59
|
-
|
|
60
|
-
data: {
|
|
61
|
-
id: string;
|
|
62
|
-
object: 'message';
|
|
63
|
-
status: 'sent' | 'delivered' | 'read' | 'failed' | 'queued' | 'pending';
|
|
64
|
-
error?: {
|
|
65
|
-
code: string;
|
|
66
|
-
message: string;
|
|
67
|
-
provider_code: number | null;
|
|
68
|
-
};
|
|
69
|
-
};
|
|
35
|
+
export declare class SignatureExpiredError extends KirimWebhookError {
|
|
36
|
+
constructor(message?: string);
|
|
70
37
|
}
|
|
71
|
-
export
|
|
72
|
-
|
|
73
|
-
data: {
|
|
74
|
-
id: string;
|
|
75
|
-
object: 'conversation';
|
|
76
|
-
};
|
|
38
|
+
export declare class MalformedPayloadError extends KirimWebhookError {
|
|
39
|
+
constructor(message?: string);
|
|
77
40
|
}
|
|
78
|
-
export interface
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
41
|
+
export interface VerifyOptions {
|
|
42
|
+
rawBody: string;
|
|
43
|
+
signatureHeader: string | null | undefined;
|
|
44
|
+
secrets: string[];
|
|
45
|
+
/** Default 300 seconds (5 minutes). */
|
|
46
|
+
toleranceSeconds?: number;
|
|
47
|
+
/** Override the wall clock — primarily for tests. */
|
|
48
|
+
nowSeconds?: () => number;
|
|
84
49
|
}
|
|
85
|
-
export
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
50
|
+
export declare function verifyWebhookSignature(opts: VerifyOptions): Promise<unknown>;
|
|
51
|
+
/**
|
|
52
|
+
* Native Kirim event envelope (server emits `conversation.*` and
|
|
53
|
+
* `contact.*` in this shape). The `message.received` and `message.status`
|
|
54
|
+
* events are forwarded VERBATIM from Meta's webhook body and do NOT use
|
|
55
|
+
* this envelope — see `MetaPassthroughBody` below.
|
|
56
|
+
*/
|
|
57
|
+
export interface KirimEventEnvelope<TType extends string, TData> {
|
|
58
|
+
id: string;
|
|
59
|
+
type: TType;
|
|
60
|
+
created_at: string;
|
|
61
|
+
data: TData;
|
|
91
62
|
}
|
|
92
|
-
export
|
|
93
|
-
|
|
94
|
-
|
|
63
|
+
export type ConversationAssignedEvent = KirimEventEnvelope<'conversation.assigned', {
|
|
64
|
+
id: string;
|
|
65
|
+
object: 'conversation';
|
|
66
|
+
[k: string]: unknown;
|
|
67
|
+
}>;
|
|
68
|
+
export type ConversationClosedEvent = KirimEventEnvelope<'conversation.closed', {
|
|
69
|
+
id: string;
|
|
70
|
+
object: 'conversation';
|
|
71
|
+
[k: string]: unknown;
|
|
72
|
+
}>;
|
|
73
|
+
export type ContactCreatedEvent = KirimEventEnvelope<'contact.created', {
|
|
74
|
+
id: string;
|
|
75
|
+
object: 'contact';
|
|
76
|
+
[k: string]: unknown;
|
|
77
|
+
}>;
|
|
78
|
+
export type ContactUpdatedEvent = KirimEventEnvelope<'contact.updated', {
|
|
79
|
+
id: string;
|
|
80
|
+
object: 'contact';
|
|
81
|
+
[k: string]: unknown;
|
|
82
|
+
}>;
|
|
83
|
+
export type KirimNativeWebhookEvent = ConversationAssignedEvent | ConversationClosedEvent | ContactCreatedEvent | ContactUpdatedEvent;
|
|
84
|
+
/**
|
|
85
|
+
* Meta passthrough body — `message.received` and `message.status`
|
|
86
|
+
* deliveries forward Meta's WhatsApp Cloud webhook payload unchanged.
|
|
87
|
+
* Callers should branch on `X-Kirim-Event` to decide whether to parse
|
|
88
|
+
* the body as `KirimNativeWebhookEvent` or `MetaPassthroughBody`.
|
|
89
|
+
*/
|
|
90
|
+
export interface MetaPassthroughBody {
|
|
91
|
+
object: 'whatsapp_business_account';
|
|
92
|
+
entry: Array<{
|
|
95
93
|
id: string;
|
|
96
|
-
|
|
97
|
-
|
|
94
|
+
changes: Array<{
|
|
95
|
+
value: unknown;
|
|
96
|
+
field: 'messages' | string;
|
|
97
|
+
}>;
|
|
98
|
+
}>;
|
|
98
99
|
}
|
|
99
|
-
export
|
|
100
|
+
export type KirimWebhookEvent = KirimNativeWebhookEvent | MetaPassthroughBody;
|
|
100
101
|
//# sourceMappingURL=webhooks.d.ts.map
|
package/dist/webhooks.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webhooks.d.ts","sourceRoot":"","sources":["../src/webhooks.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"webhooks.d.ts","sourceRoot":"","sources":["../src/webhooks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,qBAAa,iBAAkB,SAAQ,KAAK;gBAC9B,OAAO,EAAE,MAAM;CAI5B;AAED,qBAAa,qBAAsB,SAAQ,iBAAiB;gBAC9C,OAAO,SAA8B;CAIlD;AAED,qBAAa,qBAAsB,SAAQ,iBAAiB;gBAC9C,OAAO,SAAyD;CAI7E;AAED,qBAAa,qBAAsB,SAAQ,iBAAiB;gBAC9C,OAAO,SAAsC;CAI1D;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAA;IACf,eAAe,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAA;IAC1C,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,uCAAuC;IACvC,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,qDAAqD;IACrD,UAAU,CAAC,EAAE,MAAM,MAAM,CAAA;CAC1B;AA8BD,wBAAsB,sBAAsB,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC,CAyBlF;AAgCD;;;;;GAKG;AACH,MAAM,WAAW,kBAAkB,CAAC,KAAK,SAAS,MAAM,EAAE,KAAK;IAC7D,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,KAAK,CAAA;IACX,UAAU,EAAE,MAAM,CAAA;IAClB,IAAI,EAAE,KAAK,CAAA;CACZ;AAED,MAAM,MAAM,yBAAyB,GAAG,kBAAkB,CACxD,uBAAuB,EACvB;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,cAAc,CAAC;IAAC,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;CAAE,CAC7D,CAAA;AAED,MAAM,MAAM,uBAAuB,GAAG,kBAAkB,CACtD,qBAAqB,EACrB;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,cAAc,CAAC;IAAC,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;CAAE,CAC7D,CAAA;AAED,MAAM,MAAM,mBAAmB,GAAG,kBAAkB,CAClD,iBAAiB,EACjB;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,SAAS,CAAC;IAAC,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;CAAE,CACxD,CAAA;AAED,MAAM,MAAM,mBAAmB,GAAG,kBAAkB,CAClD,iBAAiB,EACjB;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,SAAS,CAAC;IAAC,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;CAAE,CACxD,CAAA;AAED,MAAM,MAAM,uBAAuB,GAC/B,yBAAyB,GACzB,uBAAuB,GACvB,mBAAmB,GACnB,mBAAmB,CAAA;AAEvB;;;;;GAKG;AACH,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,2BAA2B,CAAA;IACnC,KAAK,EAAE,KAAK,CAAC;QACX,EAAE,EAAE,MAAM,CAAA;QACV,OAAO,EAAE,KAAK,CAAC;YAAE,KAAK,EAAE,OAAO,CAAC;YAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAAA;SAAE,CAAC,CAAA;KAC/D,CAAC,CAAA;CACH;AAED,MAAM,MAAM,iBAAiB,GAAG,uBAAuB,GAAG,mBAAmB,CAAA"}
|
package/dist/webhooks.js
CHANGED
|
@@ -1,64 +1,125 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Webhook HMAC verification + typed event payloads.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* header. This module exposes a constant-time verifier using Web Crypto
|
|
7
|
-
* (`crypto.subtle`) so it runs on Node 18+, Bun, Deno, and edge runtimes.
|
|
4
|
+
* Kirim signs outbound webhook deliveries using a Stripe-style header
|
|
5
|
+
* format mirroring `apps/worker/src/jobs/webhook-delivery/sign.ts`:
|
|
8
6
|
*
|
|
9
|
-
*
|
|
7
|
+
* X-Kirim-Signature: t=<unix_seconds>,v1=<hex>[,v1=<hex>...]
|
|
10
8
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
9
|
+
* - `t` is the time the signature was computed; callers reject when
|
|
10
|
+
* |now - t| exceeds `toleranceSeconds` (default 5 minutes).
|
|
11
|
+
* - Each `v1=` is HMAC-SHA256 of `${t}.${rawBody}` under one ACTIVE
|
|
12
|
+
* signing secret. During rotation a subscription may have multiple
|
|
13
|
+
* active secrets and the header carries one `v1=` per secret —
|
|
14
|
+
* verification passes if ANY caller-supplied secret matches ANY
|
|
15
|
+
* `v1=` value.
|
|
13
16
|
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* req.headers.get('x-kirim-signature') ?? '',
|
|
17
|
-
* process.env.KIRIM_WEBHOOK_SECRET!,
|
|
18
|
-
* )
|
|
19
|
-
* if (!ok) return new Response('bad signature', { status: 401 })
|
|
20
|
-
*/
|
|
21
|
-
/**
|
|
22
|
-
* Verify a Kirim webhook signature.
|
|
17
|
+
* Uses Web Crypto (`crypto.subtle`) so this module runs unchanged on
|
|
18
|
+
* Node 18+, Bun, Deno, and edge runtimes.
|
|
23
19
|
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
20
|
+
* The error classes in this module (`KirimWebhookError`,
|
|
21
|
+
* `InvalidSignatureError`, `SignatureExpiredError`,
|
|
22
|
+
* `MalformedPayloadError`) form a SEPARATE hierarchy from the HTTP
|
|
23
|
+
* `KirimError` tree in `@kirimdev/sdk` — webhook errors carry no
|
|
24
|
+
* `requestId` / `status` / `code` because they fire before any HTTP
|
|
25
|
+
* round-trip. Consumers wanting a single catch surface should branch
|
|
26
|
+
* on `instanceof KirimWebhookError` separately from `instanceof
|
|
27
|
+
* KirimError`.
|
|
28
28
|
*/
|
|
29
|
-
export
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
29
|
+
export class KirimWebhookError extends Error {
|
|
30
|
+
constructor(message) {
|
|
31
|
+
super(message);
|
|
32
|
+
this.name = 'KirimWebhookError';
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
export class InvalidSignatureError extends KirimWebhookError {
|
|
36
|
+
constructor(message = 'Invalid webhook signature') {
|
|
37
|
+
super(message);
|
|
38
|
+
this.name = 'InvalidSignatureError';
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
export class SignatureExpiredError extends KirimWebhookError {
|
|
42
|
+
constructor(message = 'Webhook signature timestamp outside tolerance window') {
|
|
43
|
+
super(message);
|
|
44
|
+
this.name = 'SignatureExpiredError';
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
export class MalformedPayloadError extends KirimWebhookError {
|
|
48
|
+
constructor(message = 'Webhook payload is not valid JSON') {
|
|
49
|
+
super(message);
|
|
50
|
+
this.name = 'MalformedPayloadError';
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
function parseHeader(header) {
|
|
54
|
+
const parts = header.split(',').map((s) => s.trim()).filter(Boolean);
|
|
55
|
+
let t = null;
|
|
56
|
+
const v1 = [];
|
|
57
|
+
for (const part of parts) {
|
|
58
|
+
const eq = part.indexOf('=');
|
|
59
|
+
if (eq <= 0)
|
|
60
|
+
return null;
|
|
61
|
+
const k = part.slice(0, eq);
|
|
62
|
+
const v = part.slice(eq + 1);
|
|
63
|
+
if (k === 't') {
|
|
64
|
+
const n = Number(v);
|
|
65
|
+
if (!Number.isFinite(n) || n <= 0)
|
|
66
|
+
return null;
|
|
67
|
+
t = n;
|
|
68
|
+
}
|
|
69
|
+
else if (k === 'v1') {
|
|
70
|
+
if (!/^[0-9a-f]+$/i.test(v))
|
|
71
|
+
return null;
|
|
72
|
+
v1.push(v.toLowerCase());
|
|
73
|
+
}
|
|
74
|
+
// Unknown scheme tokens (future-proof: e.g. v2=) are ignored.
|
|
75
|
+
}
|
|
76
|
+
if (t === null || v1.length === 0)
|
|
77
|
+
return null;
|
|
78
|
+
return { t, v1 };
|
|
79
|
+
}
|
|
80
|
+
export async function verifyWebhookSignature(opts) {
|
|
81
|
+
const tolerance = opts.toleranceSeconds ?? 300;
|
|
82
|
+
const now = (opts.nowSeconds ?? (() => Math.floor(Date.now() / 1000)))();
|
|
83
|
+
if (!opts.signatureHeader || opts.secrets.length === 0) {
|
|
84
|
+
throw new InvalidSignatureError('Missing signature header or secrets');
|
|
85
|
+
}
|
|
86
|
+
const parsed = parseHeader(opts.signatureHeader);
|
|
87
|
+
if (!parsed)
|
|
88
|
+
throw new InvalidSignatureError('Malformed signature header');
|
|
89
|
+
if (Math.abs(now - parsed.t) > tolerance) {
|
|
90
|
+
throw new SignatureExpiredError();
|
|
91
|
+
}
|
|
92
|
+
const signedString = `${parsed.t}.${opts.rawBody}`;
|
|
93
|
+
for (const secret of opts.secrets) {
|
|
94
|
+
const expected = await hmacSha256Hex(secret, signedString);
|
|
95
|
+
for (const candidate of parsed.v1) {
|
|
96
|
+
if (expected.length === candidate.length && timingSafeEqualHex(expected, candidate)) {
|
|
97
|
+
try {
|
|
98
|
+
return JSON.parse(opts.rawBody);
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
throw new MalformedPayloadError();
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
throw new InvalidSignatureError('No v1 signature matched any provided secret');
|
|
42
107
|
}
|
|
43
108
|
async function hmacSha256Hex(secret, body) {
|
|
44
109
|
const enc = new TextEncoder();
|
|
45
110
|
const key = await crypto.subtle.importKey('raw', enc.encode(secret), { name: 'HMAC', hash: 'SHA-256' }, false, ['sign']);
|
|
46
111
|
const buf = await crypto.subtle.sign('HMAC', key, enc.encode(body));
|
|
47
|
-
return bufferToHex(new Uint8Array(buf));
|
|
48
|
-
}
|
|
49
|
-
function bufferToHex(buf) {
|
|
50
112
|
let out = '';
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
out +=
|
|
113
|
+
const view = new Uint8Array(buf);
|
|
114
|
+
for (let i = 0; i < view.length; i++) {
|
|
115
|
+
out += (view[i] ?? 0).toString(16).padStart(2, '0');
|
|
54
116
|
}
|
|
55
117
|
return out;
|
|
56
118
|
}
|
|
57
|
-
/** Constant-time string comparison. Inputs MUST be equal length. */
|
|
58
119
|
function timingSafeEqualHex(a, b) {
|
|
59
120
|
let diff = 0;
|
|
60
121
|
for (let i = 0; i < a.length; i++) {
|
|
61
|
-
diff |=
|
|
122
|
+
diff |= a.charCodeAt(i) ^ b.charCodeAt(i);
|
|
62
123
|
}
|
|
63
124
|
return diff === 0;
|
|
64
125
|
}
|
package/dist/webhooks.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webhooks.js","sourceRoot":"","sources":["../src/webhooks.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"webhooks.js","sourceRoot":"","sources":["../src/webhooks.ts"],"names":[],"mappings":"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"}
|
package/openapi.json
CHANGED
|
@@ -3,15 +3,15 @@
|
|
|
3
3
|
"info": {
|
|
4
4
|
"title": "Kirim Public API",
|
|
5
5
|
"version": "1.0.0",
|
|
6
|
-
"description": "Self-service REST API for sending WhatsApp messages, subscribing to events, and managing your inbox programmatically. See docs.
|
|
6
|
+
"description": "Self-service REST API for sending WhatsApp messages, subscribing to events, and managing your inbox programmatically. See docs.kirimdev.com for guides and reference.",
|
|
7
7
|
"contact": {
|
|
8
|
-
"name": "
|
|
9
|
-
"url": "https://
|
|
8
|
+
"name": "Kirimdev Support",
|
|
9
|
+
"url": "https://kirimdev.com"
|
|
10
10
|
}
|
|
11
11
|
},
|
|
12
12
|
"servers": [
|
|
13
13
|
{
|
|
14
|
-
"url": "https://api.
|
|
14
|
+
"url": "https://api.kirimdev.com/v1",
|
|
15
15
|
"description": "Production"
|
|
16
16
|
}
|
|
17
17
|
],
|
|
@@ -263,8 +263,8 @@
|
|
|
263
263
|
"string",
|
|
264
264
|
"null"
|
|
265
265
|
],
|
|
266
|
-
"
|
|
267
|
-
"
|
|
266
|
+
"example": "106540352242922",
|
|
267
|
+
"description": "Meta WhatsApp Business `phone_number_id`. Use as the `{phone_number_id}` path parameter in `/v1/{phone_number_id}/...` endpoints. Nullable while onboarding is in flight."
|
|
268
268
|
},
|
|
269
269
|
"phone_number": {
|
|
270
270
|
"type": [
|
|
@@ -282,8 +282,8 @@
|
|
|
282
282
|
},
|
|
283
283
|
"status": {
|
|
284
284
|
"type": "string",
|
|
285
|
-
"
|
|
286
|
-
"
|
|
285
|
+
"example": "connected",
|
|
286
|
+
"description": "Lifecycle state of the account (e.g. `connected`, `disconnected`, `degraded`, `onboarding`)."
|
|
287
287
|
}
|
|
288
288
|
},
|
|
289
289
|
"required": [
|
|
@@ -2012,10 +2012,11 @@
|
|
|
2012
2012
|
"schema": {
|
|
2013
2013
|
"type": "string",
|
|
2014
2014
|
"pattern": "^\\d{6,20}$",
|
|
2015
|
-
"
|
|
2016
|
-
"
|
|
2015
|
+
"example": "106540352242922",
|
|
2016
|
+
"description": "Meta WhatsApp Business `phone_number_id` of the connected account that should send / own this resource. Discoverable via `GET /v1/accounts` (returned as `phone_number_id` on each row)."
|
|
2017
2017
|
},
|
|
2018
2018
|
"required": true,
|
|
2019
|
+
"description": "Meta WhatsApp Business `phone_number_id` of the connected account that should send / own this resource. Discoverable via `GET /v1/accounts` (returned as `phone_number_id` on each row).",
|
|
2019
2020
|
"name": "phone_number_id",
|
|
2020
2021
|
"in": "path"
|
|
2021
2022
|
},
|
|
@@ -2025,6 +2026,7 @@
|
|
|
2025
2026
|
"description": "Optional idempotency token. See /docs/idempotency."
|
|
2026
2027
|
},
|
|
2027
2028
|
"required": false,
|
|
2029
|
+
"description": "Optional idempotency token. See /docs/idempotency.",
|
|
2028
2030
|
"name": "idempotency-key",
|
|
2029
2031
|
"in": "header"
|
|
2030
2032
|
}
|
|
@@ -2397,7 +2399,8 @@
|
|
|
2397
2399
|
},
|
|
2398
2400
|
"required": [
|
|
2399
2401
|
"type"
|
|
2400
|
-
]
|
|
2402
|
+
],
|
|
2403
|
+
"additionalProperties": {}
|
|
2401
2404
|
}
|
|
2402
2405
|
}
|
|
2403
2406
|
},
|
|
@@ -3002,10 +3005,11 @@
|
|
|
3002
3005
|
"schema": {
|
|
3003
3006
|
"type": "string",
|
|
3004
3007
|
"pattern": "^\\d{6,20}$",
|
|
3005
|
-
"
|
|
3006
|
-
"
|
|
3008
|
+
"example": "106540352242922",
|
|
3009
|
+
"description": "Meta WhatsApp Business `phone_number_id` of the connected account that should send / own this resource. Discoverable via `GET /v1/accounts` (returned as `phone_number_id` on each row)."
|
|
3007
3010
|
},
|
|
3008
3011
|
"required": true,
|
|
3012
|
+
"description": "Meta WhatsApp Business `phone_number_id` of the connected account that should send / own this resource. Discoverable via `GET /v1/accounts` (returned as `phone_number_id` on each row).",
|
|
3009
3013
|
"name": "phone_number_id",
|
|
3010
3014
|
"in": "path"
|
|
3011
3015
|
},
|
|
@@ -3171,10 +3175,11 @@
|
|
|
3171
3175
|
"schema": {
|
|
3172
3176
|
"type": "string",
|
|
3173
3177
|
"pattern": "^\\d{6,20}$",
|
|
3174
|
-
"
|
|
3175
|
-
"
|
|
3178
|
+
"example": "106540352242922",
|
|
3179
|
+
"description": "Meta WhatsApp Business `phone_number_id` of the connected account that should send / own this resource. Discoverable via `GET /v1/accounts` (returned as `phone_number_id` on each row)."
|
|
3176
3180
|
},
|
|
3177
3181
|
"required": true,
|
|
3182
|
+
"description": "Meta WhatsApp Business `phone_number_id` of the connected account that should send / own this resource. Discoverable via `GET /v1/accounts` (returned as `phone_number_id` on each row).",
|
|
3178
3183
|
"name": "phone_number_id",
|
|
3179
3184
|
"in": "path"
|
|
3180
3185
|
},
|
|
@@ -3279,10 +3284,11 @@
|
|
|
3279
3284
|
"schema": {
|
|
3280
3285
|
"type": "string",
|
|
3281
3286
|
"pattern": "^\\d{6,20}$",
|
|
3282
|
-
"
|
|
3283
|
-
"
|
|
3287
|
+
"example": "106540352242922",
|
|
3288
|
+
"description": "Meta WhatsApp Business `phone_number_id` of the connected account that should send / own this resource. Discoverable via `GET /v1/accounts` (returned as `phone_number_id` on each row)."
|
|
3284
3289
|
},
|
|
3285
3290
|
"required": true,
|
|
3291
|
+
"description": "Meta WhatsApp Business `phone_number_id` of the connected account that should send / own this resource. Discoverable via `GET /v1/accounts` (returned as `phone_number_id` on each row).",
|
|
3286
3292
|
"name": "phone_number_id",
|
|
3287
3293
|
"in": "path"
|
|
3288
3294
|
},
|
|
@@ -3419,10 +3425,11 @@
|
|
|
3419
3425
|
"schema": {
|
|
3420
3426
|
"type": "string",
|
|
3421
3427
|
"pattern": "^\\d{6,20}$",
|
|
3422
|
-
"
|
|
3423
|
-
"
|
|
3428
|
+
"example": "106540352242922",
|
|
3429
|
+
"description": "Meta WhatsApp Business `phone_number_id` of the connected account that should send / own this resource. Discoverable via `GET /v1/accounts` (returned as `phone_number_id` on each row)."
|
|
3424
3430
|
},
|
|
3425
3431
|
"required": true,
|
|
3432
|
+
"description": "Meta WhatsApp Business `phone_number_id` of the connected account that should send / own this resource. Discoverable via `GET /v1/accounts` (returned as `phone_number_id` on each row).",
|
|
3426
3433
|
"name": "phone_number_id",
|
|
3427
3434
|
"in": "path"
|
|
3428
3435
|
},
|
|
@@ -4718,10 +4725,11 @@
|
|
|
4718
4725
|
"schema": {
|
|
4719
4726
|
"type": "string",
|
|
4720
4727
|
"pattern": "^\\d{6,20}$",
|
|
4721
|
-
"
|
|
4722
|
-
"
|
|
4728
|
+
"example": "106540352242922",
|
|
4729
|
+
"description": "Meta WhatsApp Business `phone_number_id` of the connected account that should send / own this resource. Discoverable via `GET /v1/accounts` (returned as `phone_number_id` on each row)."
|
|
4723
4730
|
},
|
|
4724
4731
|
"required": true,
|
|
4732
|
+
"description": "Meta WhatsApp Business `phone_number_id` of the connected account that should send / own this resource. Discoverable via `GET /v1/accounts` (returned as `phone_number_id` on each row).",
|
|
4725
4733
|
"name": "phone_number_id",
|
|
4726
4734
|
"in": "path"
|
|
4727
4735
|
},
|
|
@@ -4855,10 +4863,11 @@
|
|
|
4855
4863
|
"schema": {
|
|
4856
4864
|
"type": "string",
|
|
4857
4865
|
"pattern": "^\\d{6,20}$",
|
|
4858
|
-
"
|
|
4859
|
-
"
|
|
4866
|
+
"example": "106540352242922",
|
|
4867
|
+
"description": "Meta WhatsApp Business `phone_number_id` of the connected account that should send / own this resource. Discoverable via `GET /v1/accounts` (returned as `phone_number_id` on each row)."
|
|
4860
4868
|
},
|
|
4861
4869
|
"required": true,
|
|
4870
|
+
"description": "Meta WhatsApp Business `phone_number_id` of the connected account that should send / own this resource. Discoverable via `GET /v1/accounts` (returned as `phone_number_id` on each row).",
|
|
4862
4871
|
"name": "phone_number_id",
|
|
4863
4872
|
"in": "path"
|
|
4864
4873
|
},
|
|
@@ -4961,10 +4970,11 @@
|
|
|
4961
4970
|
"schema": {
|
|
4962
4971
|
"type": "string",
|
|
4963
4972
|
"pattern": "^\\d{6,20}$",
|
|
4964
|
-
"
|
|
4965
|
-
"
|
|
4973
|
+
"example": "106540352242922",
|
|
4974
|
+
"description": "Meta WhatsApp Business `phone_number_id` of the connected account that should send / own this resource. Discoverable via `GET /v1/accounts` (returned as `phone_number_id` on each row)."
|
|
4966
4975
|
},
|
|
4967
4976
|
"required": true,
|
|
4977
|
+
"description": "Meta WhatsApp Business `phone_number_id` of the connected account that should send / own this resource. Discoverable via `GET /v1/accounts` (returned as `phone_number_id` on each row).",
|
|
4968
4978
|
"name": "phone_number_id",
|
|
4969
4979
|
"in": "path"
|
|
4970
4980
|
},
|
|
@@ -5096,10 +5106,11 @@
|
|
|
5096
5106
|
"schema": {
|
|
5097
5107
|
"type": "string",
|
|
5098
5108
|
"pattern": "^\\d{6,20}$",
|
|
5099
|
-
"
|
|
5100
|
-
"
|
|
5109
|
+
"example": "106540352242922",
|
|
5110
|
+
"description": "Meta WhatsApp Business `phone_number_id` of the connected account that should send / own this resource. Discoverable via `GET /v1/accounts` (returned as `phone_number_id` on each row)."
|
|
5101
5111
|
},
|
|
5102
5112
|
"required": true,
|
|
5113
|
+
"description": "Meta WhatsApp Business `phone_number_id` of the connected account that should send / own this resource. Discoverable via `GET /v1/accounts` (returned as `phone_number_id` on each row).",
|
|
5103
5114
|
"name": "phone_number_id",
|
|
5104
5115
|
"in": "path"
|
|
5105
5116
|
},
|
|
@@ -5228,10 +5239,11 @@
|
|
|
5228
5239
|
"schema": {
|
|
5229
5240
|
"type": "string",
|
|
5230
5241
|
"pattern": "^\\d{6,20}$",
|
|
5231
|
-
"
|
|
5232
|
-
"
|
|
5242
|
+
"example": "106540352242922",
|
|
5243
|
+
"description": "Meta WhatsApp Business `phone_number_id` of the connected account that should send / own this resource. Discoverable via `GET /v1/accounts` (returned as `phone_number_id` on each row)."
|
|
5233
5244
|
},
|
|
5234
5245
|
"required": true,
|
|
5246
|
+
"description": "Meta WhatsApp Business `phone_number_id` of the connected account that should send / own this resource. Discoverable via `GET /v1/accounts` (returned as `phone_number_id` on each row).",
|
|
5235
5247
|
"name": "phone_number_id",
|
|
5236
5248
|
"in": "path"
|
|
5237
5249
|
}
|
|
@@ -5360,10 +5372,11 @@
|
|
|
5360
5372
|
"schema": {
|
|
5361
5373
|
"type": "string",
|
|
5362
5374
|
"pattern": "^\\d{6,20}$",
|
|
5363
|
-
"
|
|
5364
|
-
"
|
|
5375
|
+
"example": "106540352242922",
|
|
5376
|
+
"description": "Meta WhatsApp Business `phone_number_id` of the connected account that should send / own this resource. Discoverable via `GET /v1/accounts` (returned as `phone_number_id` on each row)."
|
|
5365
5377
|
},
|
|
5366
5378
|
"required": true,
|
|
5379
|
+
"description": "Meta WhatsApp Business `phone_number_id` of the connected account that should send / own this resource. Discoverable via `GET /v1/accounts` (returned as `phone_number_id` on each row).",
|
|
5367
5380
|
"name": "phone_number_id",
|
|
5368
5381
|
"in": "path"
|
|
5369
5382
|
},
|
|
@@ -5466,10 +5479,11 @@
|
|
|
5466
5479
|
"schema": {
|
|
5467
5480
|
"type": "string",
|
|
5468
5481
|
"pattern": "^\\d{6,20}$",
|
|
5469
|
-
"
|
|
5470
|
-
"
|
|
5482
|
+
"example": "106540352242922",
|
|
5483
|
+
"description": "Meta WhatsApp Business `phone_number_id` of the connected account that should send / own this resource. Discoverable via `GET /v1/accounts` (returned as `phone_number_id` on each row)."
|
|
5471
5484
|
},
|
|
5472
5485
|
"required": true,
|
|
5486
|
+
"description": "Meta WhatsApp Business `phone_number_id` of the connected account that should send / own this resource. Discoverable via `GET /v1/accounts` (returned as `phone_number_id` on each row).",
|
|
5473
5487
|
"name": "phone_number_id",
|
|
5474
5488
|
"in": "path"
|
|
5475
5489
|
},
|
|
@@ -5616,10 +5630,11 @@
|
|
|
5616
5630
|
"schema": {
|
|
5617
5631
|
"type": "string",
|
|
5618
5632
|
"pattern": "^\\d{6,20}$",
|
|
5619
|
-
"
|
|
5620
|
-
"
|
|
5633
|
+
"example": "106540352242922",
|
|
5634
|
+
"description": "Meta WhatsApp Business `phone_number_id` of the connected account that should send / own this resource. Discoverable via `GET /v1/accounts` (returned as `phone_number_id` on each row)."
|
|
5621
5635
|
},
|
|
5622
5636
|
"required": true,
|
|
5637
|
+
"description": "Meta WhatsApp Business `phone_number_id` of the connected account that should send / own this resource. Discoverable via `GET /v1/accounts` (returned as `phone_number_id` on each row).",
|
|
5623
5638
|
"name": "phone_number_id",
|
|
5624
5639
|
"in": "path"
|
|
5625
5640
|
},
|
|
@@ -5724,10 +5739,11 @@
|
|
|
5724
5739
|
"schema": {
|
|
5725
5740
|
"type": "string",
|
|
5726
5741
|
"pattern": "^\\d{6,20}$",
|
|
5727
|
-
"
|
|
5728
|
-
"
|
|
5742
|
+
"example": "106540352242922",
|
|
5743
|
+
"description": "Meta WhatsApp Business `phone_number_id` of the connected account that should send / own this resource. Discoverable via `GET /v1/accounts` (returned as `phone_number_id` on each row)."
|
|
5729
5744
|
},
|
|
5730
5745
|
"required": true,
|
|
5746
|
+
"description": "Meta WhatsApp Business `phone_number_id` of the connected account that should send / own this resource. Discoverable via `GET /v1/accounts` (returned as `phone_number_id` on each row).",
|
|
5731
5747
|
"name": "phone_number_id",
|
|
5732
5748
|
"in": "path"
|
|
5733
5749
|
},
|
|
@@ -5833,10 +5849,11 @@
|
|
|
5833
5849
|
"schema": {
|
|
5834
5850
|
"type": "string",
|
|
5835
5851
|
"pattern": "^\\d{6,20}$",
|
|
5836
|
-
"
|
|
5837
|
-
"
|
|
5852
|
+
"example": "106540352242922",
|
|
5853
|
+
"description": "Meta WhatsApp Business `phone_number_id` of the connected account that should send / own this resource. Discoverable via `GET /v1/accounts` (returned as `phone_number_id` on each row)."
|
|
5838
5854
|
},
|
|
5839
5855
|
"required": true,
|
|
5856
|
+
"description": "Meta WhatsApp Business `phone_number_id` of the connected account that should send / own this resource. Discoverable via `GET /v1/accounts` (returned as `phone_number_id` on each row).",
|
|
5840
5857
|
"name": "phone_number_id",
|
|
5841
5858
|
"in": "path"
|
|
5842
5859
|
},
|
|
@@ -5958,10 +5975,11 @@
|
|
|
5958
5975
|
"schema": {
|
|
5959
5976
|
"type": "string",
|
|
5960
5977
|
"pattern": "^\\d{6,20}$",
|
|
5961
|
-
"
|
|
5962
|
-
"
|
|
5978
|
+
"example": "106540352242922",
|
|
5979
|
+
"description": "Meta WhatsApp Business `phone_number_id` of the connected account that should send / own this resource. Discoverable via `GET /v1/accounts` (returned as `phone_number_id` on each row)."
|
|
5963
5980
|
},
|
|
5964
5981
|
"required": true,
|
|
5982
|
+
"description": "Meta WhatsApp Business `phone_number_id` of the connected account that should send / own this resource. Discoverable via `GET /v1/accounts` (returned as `phone_number_id` on each row).",
|
|
5965
5983
|
"name": "phone_number_id",
|
|
5966
5984
|
"in": "path"
|
|
5967
5985
|
},
|
|
@@ -6075,10 +6093,11 @@
|
|
|
6075
6093
|
"schema": {
|
|
6076
6094
|
"type": "string",
|
|
6077
6095
|
"pattern": "^\\d{6,20}$",
|
|
6078
|
-
"
|
|
6079
|
-
"
|
|
6096
|
+
"example": "106540352242922",
|
|
6097
|
+
"description": "Meta WhatsApp Business `phone_number_id` of the connected account that should send / own this resource. Discoverable via `GET /v1/accounts` (returned as `phone_number_id` on each row)."
|
|
6080
6098
|
},
|
|
6081
6099
|
"required": true,
|
|
6100
|
+
"description": "Meta WhatsApp Business `phone_number_id` of the connected account that should send / own this resource. Discoverable via `GET /v1/accounts` (returned as `phone_number_id` on each row).",
|
|
6082
6101
|
"name": "phone_number_id",
|
|
6083
6102
|
"in": "path"
|
|
6084
6103
|
}
|
|
@@ -6209,10 +6228,11 @@
|
|
|
6209
6228
|
"schema": {
|
|
6210
6229
|
"type": "string",
|
|
6211
6230
|
"pattern": "^\\d{6,20}$",
|
|
6212
|
-
"
|
|
6213
|
-
"
|
|
6231
|
+
"example": "106540352242922",
|
|
6232
|
+
"description": "Meta WhatsApp Business `phone_number_id` of the connected account that should send / own this resource. Discoverable via `GET /v1/accounts` (returned as `phone_number_id` on each row)."
|
|
6214
6233
|
},
|
|
6215
6234
|
"required": true,
|
|
6235
|
+
"description": "Meta WhatsApp Business `phone_number_id` of the connected account that should send / own this resource. Discoverable via `GET /v1/accounts` (returned as `phone_number_id` on each row).",
|
|
6216
6236
|
"name": "phone_number_id",
|
|
6217
6237
|
"in": "path"
|
|
6218
6238
|
},
|
|
@@ -6334,10 +6354,11 @@
|
|
|
6334
6354
|
"schema": {
|
|
6335
6355
|
"type": "string",
|
|
6336
6356
|
"pattern": "^\\d{6,20}$",
|
|
6337
|
-
"
|
|
6338
|
-
"
|
|
6357
|
+
"example": "106540352242922",
|
|
6358
|
+
"description": "Meta WhatsApp Business `phone_number_id` of the connected account that should send / own this resource. Discoverable via `GET /v1/accounts` (returned as `phone_number_id` on each row)."
|
|
6339
6359
|
},
|
|
6340
6360
|
"required": true,
|
|
6361
|
+
"description": "Meta WhatsApp Business `phone_number_id` of the connected account that should send / own this resource. Discoverable via `GET /v1/accounts` (returned as `phone_number_id` on each row).",
|
|
6341
6362
|
"name": "phone_number_id",
|
|
6342
6363
|
"in": "path"
|
|
6343
6364
|
},
|
package/package.json
CHANGED
|
@@ -1,63 +1,63 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@kirimdev/sdk",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "Official TypeScript SDK for the
|
|
5
|
-
"type": "module",
|
|
6
|
-
"license": "MIT",
|
|
7
|
-
"publishConfig": {
|
|
8
|
-
"access": "public",
|
|
9
|
-
"registry": "https://registry.npmjs.org/"
|
|
10
|
-
},
|
|
11
|
-
"keywords": [
|
|
12
|
-
"kirim",
|
|
13
|
-
"whatsapp",
|
|
14
|
-
"whatsapp-business",
|
|
15
|
-
"sdk",
|
|
16
|
-
"api-client"
|
|
17
|
-
],
|
|
18
|
-
"files": [
|
|
19
|
-
"dist",
|
|
20
|
-
"openapi.json",
|
|
21
|
-
"README.md",
|
|
22
|
-
"LICENSE"
|
|
23
|
-
],
|
|
24
|
-
"main": "./dist/index.js",
|
|
25
|
-
"module": "./dist/index.js",
|
|
26
|
-
"types": "./dist/index.d.ts",
|
|
27
|
-
"exports": {
|
|
28
|
-
".": {
|
|
29
|
-
"types": "./dist/index.d.ts",
|
|
30
|
-
"import": "./dist/index.js"
|
|
31
|
-
},
|
|
32
|
-
"./webhooks": {
|
|
33
|
-
"types": "./dist/webhooks.d.ts",
|
|
34
|
-
"import": "./dist/webhooks.js"
|
|
35
|
-
},
|
|
36
|
-
"./package.json": "./package.json"
|
|
37
|
-
},
|
|
38
|
-
"engines": {
|
|
39
|
-
"node": ">=18"
|
|
40
|
-
},
|
|
41
|
-
"scripts": {
|
|
42
|
-
"prebuild": "bun scripts/ensure-types.ts",
|
|
43
|
-
"build": "tsc -p tsconfig.build.json",
|
|
44
|
-
"pretypecheck": "bun scripts/ensure-types.ts",
|
|
45
|
-
"typecheck": "tsc --noEmit",
|
|
46
|
-
"pretest": "bun scripts/ensure-types.ts",
|
|
47
|
-
"test": "bun test",
|
|
48
|
-
"lint": "tsc --noEmit",
|
|
49
|
-
"sync": "bun scripts/sync-openapi.ts && bun scripts/generate-types.ts",
|
|
50
|
-
"generate-types": "bun scripts/generate-types.ts",
|
|
51
|
-
"check:drift": "bun scripts/check-drift.ts",
|
|
52
|
-
"prepublishOnly": "bun run typecheck && bun run test && bun run build"
|
|
53
|
-
},
|
|
54
|
-
"dependencies": {
|
|
55
|
-
"openapi-fetch": "^0.13.0"
|
|
56
|
-
},
|
|
57
|
-
"devDependencies": {
|
|
58
|
-
"@
|
|
59
|
-
"@types/bun": "latest",
|
|
60
|
-
"openapi-typescript": "^7.4.0",
|
|
61
|
-
"typescript": "^5.8.0"
|
|
62
|
-
}
|
|
63
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@kirimdev/sdk",
|
|
3
|
+
"version": "3.0.1",
|
|
4
|
+
"description": "Official TypeScript SDK for the Kirimdev Public API.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"publishConfig": {
|
|
8
|
+
"access": "public",
|
|
9
|
+
"registry": "https://registry.npmjs.org/"
|
|
10
|
+
},
|
|
11
|
+
"keywords": [
|
|
12
|
+
"kirim",
|
|
13
|
+
"whatsapp",
|
|
14
|
+
"whatsapp-business",
|
|
15
|
+
"sdk",
|
|
16
|
+
"api-client"
|
|
17
|
+
],
|
|
18
|
+
"files": [
|
|
19
|
+
"dist",
|
|
20
|
+
"openapi.json",
|
|
21
|
+
"README.md",
|
|
22
|
+
"LICENSE"
|
|
23
|
+
],
|
|
24
|
+
"main": "./dist/index.js",
|
|
25
|
+
"module": "./dist/index.js",
|
|
26
|
+
"types": "./dist/index.d.ts",
|
|
27
|
+
"exports": {
|
|
28
|
+
".": {
|
|
29
|
+
"types": "./dist/index.d.ts",
|
|
30
|
+
"import": "./dist/index.js"
|
|
31
|
+
},
|
|
32
|
+
"./webhooks": {
|
|
33
|
+
"types": "./dist/webhooks.d.ts",
|
|
34
|
+
"import": "./dist/webhooks.js"
|
|
35
|
+
},
|
|
36
|
+
"./package.json": "./package.json"
|
|
37
|
+
},
|
|
38
|
+
"engines": {
|
|
39
|
+
"node": ">=18"
|
|
40
|
+
},
|
|
41
|
+
"scripts": {
|
|
42
|
+
"prebuild": "bun scripts/ensure-types.ts",
|
|
43
|
+
"build": "tsc -p tsconfig.build.json",
|
|
44
|
+
"pretypecheck": "bun scripts/ensure-types.ts",
|
|
45
|
+
"typecheck": "tsc --noEmit",
|
|
46
|
+
"pretest": "bun scripts/ensure-types.ts",
|
|
47
|
+
"test": "bun test",
|
|
48
|
+
"lint": "tsc --noEmit",
|
|
49
|
+
"sync": "bun scripts/sync-openapi.ts && bun scripts/generate-types.ts",
|
|
50
|
+
"generate-types": "bun scripts/generate-types.ts",
|
|
51
|
+
"check:drift": "bun scripts/check-drift.ts",
|
|
52
|
+
"prepublishOnly": "bun run typecheck && bun run test && bun run build"
|
|
53
|
+
},
|
|
54
|
+
"dependencies": {
|
|
55
|
+
"openapi-fetch": "^0.13.0"
|
|
56
|
+
},
|
|
57
|
+
"devDependencies": {
|
|
58
|
+
"@kirimdev/tsconfig": "workspace:*",
|
|
59
|
+
"@types/bun": "latest",
|
|
60
|
+
"openapi-typescript": "^7.4.0",
|
|
61
|
+
"typescript": "^5.8.0"
|
|
62
|
+
}
|
|
63
|
+
}
|