@zindua/sdk 1.2.9 → 1.3.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 CHANGED
@@ -58,6 +58,7 @@ await zindua.send({
58
58
  });
59
59
 
60
60
  // WhatsApp — E.164 phone with + (channel is required for WhatsApp)
61
+ // Works for OTP, alerts, receipts — any template.
61
62
  await zindua.send({
62
63
  to: "+243812345678",
63
64
  channel: "whatsapp",
@@ -66,6 +67,14 @@ await zindua.send({
66
67
  });
67
68
  ```
68
69
 
70
+ ### WhatsApp: brand name + save contact
71
+
72
+ WhatsApp may still show the phone number in the chat header until the recipient saves your contact. Zindua helps in three ways:
73
+
74
+ 1. **Sender name** in Dashboard → Project → WhatsApp (required after linking).
75
+ 2. **Brand prefix** — every WhatsApp body is prefixed with that name (`Acme: …`) when set.
76
+ 3. **Save contact** — download the `.vcf` from the dashboard and ask users to save it before important messages. Optionally enable **Send contact card on first message** so each new recipient gets a saveable card once (never again for that number).
77
+
69
78
  ### WhatsApp anti-ban robot (required)
70
79
 
71
80
  Zindua runs an **anti-ban Guardian** on WhatsApp sends. Burst / simultaneous OTP traffic looks like spam and can **ban the number you linked** in the dashboard.
package/dist/client.d.ts CHANGED
@@ -9,6 +9,23 @@ export type ZinduaSendOptions = {
9
9
  bcc?: string;
10
10
  replyTo?: string;
11
11
  attachments?: unknown[];
12
+ /** When true, server verifies email (format/MX/disposable) before queueing. */
13
+ validate?: boolean;
14
+ };
15
+ export type ZinduaEmailVerifyResult = {
16
+ ok: true;
17
+ email: string;
18
+ status: "valid" | "risky" | "invalid";
19
+ score: number;
20
+ formatOk: boolean;
21
+ mxFound: boolean;
22
+ disposable: boolean;
23
+ didYouMean: string | null;
24
+ domain: string | null;
25
+ reasons: string[];
26
+ suppressed: boolean;
27
+ suppressionReason: string | null;
28
+ deliverable: boolean;
12
29
  };
13
30
  export type ZinduaClientOptions = {
14
31
  apiKey: string;
@@ -272,6 +289,11 @@ export declare class Zindua {
272
289
  templates: ZinduaTemplateInfo[];
273
290
  limits?: Record<string, unknown>;
274
291
  }>;
292
+ /**
293
+ * Verify an email address (format, MX, disposable, typo suggestion).
294
+ * POST /api/v1/email/verify — protects your BYO provider reputation.
295
+ */
296
+ verifyEmail(email: string): Promise<ZinduaEmailVerifyResult>;
275
297
  /** Delivery status for a logId returned by send() (GET /logs/{logId}). */
276
298
  getLog(logId: string): Promise<Record<string, unknown>>;
277
299
  send(options: ZinduaSendOptions): Promise<ZinduaSendResult>;
package/dist/client.js CHANGED
@@ -4,7 +4,7 @@ exports.Zindua = void 0;
4
4
  const errors_1 = require("./errors");
5
5
  const validate_1 = require("./validate");
6
6
  const whatsapp_anti_ban_1 = require("./whatsapp-anti-ban");
7
- const SDK_VERSION = "1.2.9";
7
+ const SDK_VERSION = "1.3.0";
8
8
  const USER_AGENT = `Zindua-JS/${SDK_VERSION}`;
9
9
  function buildPayload(options, channel) {
10
10
  const to = (0, validate_1.validateRecipient)(options.to, channel);
@@ -35,6 +35,8 @@ function buildPayload(options, channel) {
35
35
  payload.replyTo = replyTo;
36
36
  if (attachments)
37
37
  payload.attachments = attachments;
38
+ if (options.validate === true)
39
+ payload.validate = true;
38
40
  }
39
41
  return payload;
40
42
  }
@@ -256,6 +258,38 @@ class Zindua {
256
258
  limits: data.limits,
257
259
  };
258
260
  }
261
+ /**
262
+ * Verify an email address (format, MX, disposable, typo suggestion).
263
+ * POST /api/v1/email/verify — protects your BYO provider reputation.
264
+ */
265
+ async verifyEmail(email) {
266
+ const trimmed = email.trim();
267
+ if (!trimmed) {
268
+ throw new errors_1.ZinduaError("email is required.", { status: 0, code: "MISSING_FIELDS" });
269
+ }
270
+ const data = await this.request("POST", "email/verify", { email: trimmed });
271
+ if (data.ok !== true || typeof data.email !== "string") {
272
+ throw new errors_1.ZinduaError("API response missing verify payload.", {
273
+ status: 200,
274
+ code: "INVALID_RESPONSE",
275
+ });
276
+ }
277
+ return {
278
+ ok: true,
279
+ email: data.email,
280
+ status: data.status === "risky" || data.status === "invalid" ? data.status : "valid",
281
+ score: typeof data.score === "number" ? data.score : 0,
282
+ formatOk: Boolean(data.formatOk),
283
+ mxFound: Boolean(data.mxFound),
284
+ disposable: Boolean(data.disposable),
285
+ didYouMean: typeof data.didYouMean === "string" ? data.didYouMean : null,
286
+ domain: typeof data.domain === "string" ? data.domain : null,
287
+ reasons: Array.isArray(data.reasons) ? data.reasons : [],
288
+ suppressed: Boolean(data.suppressed),
289
+ suppressionReason: typeof data.suppressionReason === "string" ? data.suppressionReason : null,
290
+ deliverable: Boolean(data.deliverable),
291
+ };
292
+ }
259
293
  /** Delivery status for a logId returned by send() (GET /logs/{logId}). */
260
294
  async getLog(logId) {
261
295
  const trimmed = logId.trim();
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export { Zindua } from "./client";
2
- export type { ZinduaClientOptions, ZinduaConnectResult, ZinduaProjectInfo, ZinduaSendContext, ZinduaSendOptions, ZinduaSendResult, ZinduaTemplateInfo, SendChannel, } from "./client";
2
+ export type { ZinduaClientOptions, ZinduaConnectResult, ZinduaEmailVerifyResult, ZinduaProjectInfo, ZinduaSendContext, ZinduaSendOptions, ZinduaSendResult, ZinduaTemplateInfo, SendChannel, } from "./client";
3
3
  export { ZinduaError } from "./errors";
4
4
  export type { ZinduaErrorCode } from "./errors";
5
5
  export { DEFAULT_API_BASE, LIMITS } from "./validate";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zindua/sdk",
3
- "version": "1.2.9",
3
+ "version": "1.3.0",
4
4
  "description": "Official Zindua SDK for Node.js — transactional email and WhatsApp via POST /api/v1/send.",
5
5
  "author": "Zindua",
6
6
  "license": "MIT",