retransmit.dev 0.1.2 → 0.2.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
@@ -1,12 +1,12 @@
1
1
  # retransmit.dev
2
2
 
3
- Node.js SDK for the [Retransmit](https://retransmit.dev) messaging API. Send email and SMS through one typed client; WhatsApp support is coming soon. Zero dependencies, works on Node 18+ and edge runtimes with `fetch`.
3
+ Node.js SDK for the [Retransmit](https://retransmit.dev) messaging API. Send email, SMS, and WhatsApp through one typed client. Zero dependencies, works on Node 18+ and edge runtimes with `fetch`.
4
4
 
5
5
  | Channel | SDK namespace | Availability |
6
6
  | --- | --- | --- |
7
7
  | Email | `retransmit.emails` | Available |
8
8
  | SMS | `retransmit.sms` | Available |
9
- | WhatsApp | `retransmit.whatsapp` | Coming soon; not included in the current release |
9
+ | WhatsApp | `retransmit.whatsapp` | Available |
10
10
 
11
11
  ## Install
12
12
 
@@ -93,10 +93,33 @@ console.log(progress?.processed, "/", progress?.total, progress?.counts);
93
93
 
94
94
  ## WhatsApp
95
95
 
96
- WhatsApp is the next planned channel. The intended SDK namespace is
97
- `retransmit.whatsapp`, but it is deliberately not exported yet because the
98
- production endpoint and request types are still being finalized. This keeps
99
- the current SDK honest while reserving a consistent channel-based API shape.
96
+ Connect your WhatsApp Business number in the dashboard first. One recipient
97
+ per request, in E.164 format. Start a conversation with an approved template;
98
+ once the recipient replies you can send free-form text and media for 24 hours.
99
+
100
+ ```ts
101
+ const { data, error } = await retransmit.whatsapp.send({
102
+ to: "+237670000000",
103
+ type: "template",
104
+ template: {
105
+ name: "verification_code",
106
+ language: "en_US",
107
+ components: [{ type: "body", parameters: [{ type: "text", text: "482913" }] }],
108
+ },
109
+ });
110
+
111
+ // Inside the 24-hour window:
112
+ await retransmit.whatsapp.send({ to: "+237670000000", text: "Anything else we can help with?" });
113
+ ```
114
+
115
+ Check the outcome, including `read` receipts:
116
+
117
+ ```ts
118
+ const { data } = await retransmit.whatsapp.get("wa_xxxxxxxxxxxx");
119
+ console.log(data?.status); // "sent" | "delivered" | "read" | "failed"
120
+ ```
121
+
122
+ Replies from recipients reach you as `whatsapp.received` webhooks.
100
123
 
101
124
  ## Error handling
102
125
 
package/dist/index.cjs CHANGED
@@ -25,7 +25,9 @@ __export(index_exports, {
25
25
  Emails: () => Emails,
26
26
  Retransmit: () => Retransmit,
27
27
  SMS_STATUSES: () => SMS_STATUSES,
28
- Sms: () => Sms
28
+ Sms: () => Sms,
29
+ WHATSAPP_STATUSES: () => WHATSAPP_STATUSES,
30
+ Whatsapp: () => Whatsapp
29
31
  });
30
32
  module.exports = __toCommonJS(index_exports);
31
33
 
@@ -96,6 +98,35 @@ var Sms = class {
96
98
  }
97
99
  };
98
100
 
101
+ // src/whatsapp.ts
102
+ var Whatsapp = class {
103
+ constructor(client) {
104
+ this.client = client;
105
+ }
106
+ client;
107
+ /**
108
+ * Queues a single WhatsApp message to one recipient. Poll `get(id)` or
109
+ * subscribe to webhooks for the outcome; replies arrive as
110
+ * `whatsapp.received` webhooks.
111
+ */
112
+ send(options) {
113
+ return this.client.request("POST", "/v1/whatsapp", {
114
+ from: options.from,
115
+ to: options.to,
116
+ type: options.type,
117
+ text: options.text,
118
+ preview_url: options.previewUrl,
119
+ template: options.template,
120
+ image: options.image,
121
+ document: options.document
122
+ });
123
+ }
124
+ /** Retrieves a WhatsApp message with its current status and event history. */
125
+ get(id) {
126
+ return this.client.request("GET", `/v1/whatsapp/${encodeURIComponent(id)}`);
127
+ }
128
+ };
129
+
99
130
  // src/retransmit.ts
100
131
  var DEFAULT_BASE_URL = "https://api.retransmit.dev";
101
132
  var USER_AGENT = "retransmit.dev-node/0.1.0";
@@ -105,6 +136,7 @@ function readEnv(name) {
105
136
  var Retransmit = class {
106
137
  emails = new Emails(this);
107
138
  sms = new Sms(this);
139
+ whatsapp = new Whatsapp(this);
108
140
  batch = new Batch(this);
109
141
  apiKey;
110
142
  baseUrl;
@@ -187,6 +219,7 @@ var SMS_STATUSES = [
187
219
  "rejected",
188
220
  "failed"
189
221
  ];
222
+ var WHATSAPP_STATUSES = ["queued", "sent", "delivered", "read", "failed"];
190
223
  // Annotate the CommonJS export names for ESM import in node:
191
224
  0 && (module.exports = {
192
225
  Batch,
@@ -194,5 +227,7 @@ var SMS_STATUSES = [
194
227
  Emails,
195
228
  Retransmit,
196
229
  SMS_STATUSES,
197
- Sms
230
+ Sms,
231
+ WHATSAPP_STATUSES,
232
+ Whatsapp
198
233
  });
package/dist/index.d.cts CHANGED
@@ -106,6 +106,81 @@ interface GetSmsResponse {
106
106
  last_event_at: string | null;
107
107
  events: SmsEvent[];
108
108
  }
109
+ declare const WHATSAPP_STATUSES: readonly ["queued", "sent", "delivered", "read", "failed"];
110
+ type WhatsappStatus = (typeof WHATSAPP_STATUSES)[number];
111
+ type WhatsappMessageType = "text" | "template" | "image" | "document";
112
+ interface WhatsappTemplate {
113
+ /** Template name as approved in WhatsApp Manager. */
114
+ name: string;
115
+ /** Language code the template was approved for, e.g. `en_US`. */
116
+ language: string;
117
+ /** Meta `components` (header/body/button parameters), passed through verbatim. */
118
+ components?: Record<string, unknown>[];
119
+ }
120
+ interface WhatsappMedia {
121
+ /** Public HTTPS link fetched at send time. */
122
+ link: string;
123
+ caption?: string;
124
+ }
125
+ interface WhatsappDocument extends WhatsappMedia {
126
+ /** File name shown to the recipient. */
127
+ filename?: string;
128
+ }
129
+ interface SendWhatsappOptions {
130
+ /**
131
+ * Connected number to send from, in international format. Optional when
132
+ * your organization has a single WhatsApp number.
133
+ */
134
+ from?: string;
135
+ /** One recipient in international format (`+237670000000`). */
136
+ to: string;
137
+ /** Defaults to `text`. */
138
+ type?: WhatsappMessageType;
139
+ /** Body for `text` messages (up to 4,096 characters), or a media caption. */
140
+ text?: string;
141
+ /** Render a preview for the first link in a `text` message. */
142
+ previewUrl?: boolean;
143
+ /** Required for `type: "template"`. Needed to start a conversation outside the 24h window. */
144
+ template?: WhatsappTemplate;
145
+ /** Required for `type: "image"`. */
146
+ image?: WhatsappMedia;
147
+ /** Required for `type: "document"`. */
148
+ document?: WhatsappDocument;
149
+ }
150
+ interface SendWhatsappResponse {
151
+ id: string;
152
+ status: "queued";
153
+ type: WhatsappMessageType;
154
+ /** The connected number the message goes out from. */
155
+ from: string;
156
+ /** ISO 3166-1 alpha-2 destination country detected from the number prefix. */
157
+ country: string | null;
158
+ created_at: string;
159
+ }
160
+ interface WhatsappEvent {
161
+ type: string;
162
+ created_at: string;
163
+ }
164
+ interface GetWhatsappResponse {
165
+ id: string;
166
+ from: string;
167
+ to: string;
168
+ country: string | null;
169
+ type: WhatsappMessageType;
170
+ text: string | null;
171
+ preview_url: boolean;
172
+ template: WhatsappTemplate | null;
173
+ media: WhatsappDocument | null;
174
+ /** Upstream provider that carried the message, e.g. `meta`. */
175
+ provider: string | null;
176
+ /** Provider-side message id (`wamid.…` on Meta); inbound replies reference it. */
177
+ provider_message_id: string | null;
178
+ status: WhatsappStatus;
179
+ error: string | null;
180
+ created_at: string;
181
+ last_event_at: string | null;
182
+ events: WhatsappEvent[];
183
+ }
109
184
  interface SendBatchResponse {
110
185
  id: string;
111
186
  total: number;
@@ -149,9 +224,23 @@ declare class Sms {
149
224
  get(id: string): Promise<Result<GetSmsResponse>>;
150
225
  }
151
226
 
227
+ declare class Whatsapp {
228
+ private readonly client;
229
+ constructor(client: Retransmit);
230
+ /**
231
+ * Queues a single WhatsApp message to one recipient. Poll `get(id)` or
232
+ * subscribe to webhooks for the outcome; replies arrive as
233
+ * `whatsapp.received` webhooks.
234
+ */
235
+ send(options: SendWhatsappOptions): Promise<Result<SendWhatsappResponse>>;
236
+ /** Retrieves a WhatsApp message with its current status and event history. */
237
+ get(id: string): Promise<Result<GetWhatsappResponse>>;
238
+ }
239
+
152
240
  declare class Retransmit {
153
241
  readonly emails: Emails;
154
242
  readonly sms: Sms;
243
+ readonly whatsapp: Whatsapp;
155
244
  readonly batch: Batch;
156
245
  private readonly apiKey;
157
246
  private readonly baseUrl;
@@ -160,4 +249,4 @@ declare class Retransmit {
160
249
  request<T>(method: "GET" | "POST", path: string, body?: unknown): Promise<Result<T>>;
161
250
  }
162
251
 
163
- export { Batch, EMAIL_STATUSES, type EmailEvent, type EmailStatus, Emails, type GetBatchResponse, type GetEmailResponse, type GetSmsResponse, type Result, Retransmit, type RetransmitError, type RetransmitOptions, SMS_STATUSES, type SendBatchResponse, type SendEmailOptions, type SendEmailResponse, type SendSmsOptions, type SendSmsResponse, Sms, type SmsEvent, type SmsStatus };
252
+ export { Batch, EMAIL_STATUSES, type EmailEvent, type EmailStatus, Emails, type GetBatchResponse, type GetEmailResponse, type GetSmsResponse, type GetWhatsappResponse, type Result, Retransmit, type RetransmitError, type RetransmitOptions, SMS_STATUSES, type SendBatchResponse, type SendEmailOptions, type SendEmailResponse, type SendSmsOptions, type SendSmsResponse, type SendWhatsappOptions, type SendWhatsappResponse, Sms, type SmsEvent, type SmsStatus, WHATSAPP_STATUSES, Whatsapp, type WhatsappDocument, type WhatsappEvent, type WhatsappMedia, type WhatsappMessageType, type WhatsappStatus, type WhatsappTemplate };
package/dist/index.d.ts CHANGED
@@ -106,6 +106,81 @@ interface GetSmsResponse {
106
106
  last_event_at: string | null;
107
107
  events: SmsEvent[];
108
108
  }
109
+ declare const WHATSAPP_STATUSES: readonly ["queued", "sent", "delivered", "read", "failed"];
110
+ type WhatsappStatus = (typeof WHATSAPP_STATUSES)[number];
111
+ type WhatsappMessageType = "text" | "template" | "image" | "document";
112
+ interface WhatsappTemplate {
113
+ /** Template name as approved in WhatsApp Manager. */
114
+ name: string;
115
+ /** Language code the template was approved for, e.g. `en_US`. */
116
+ language: string;
117
+ /** Meta `components` (header/body/button parameters), passed through verbatim. */
118
+ components?: Record<string, unknown>[];
119
+ }
120
+ interface WhatsappMedia {
121
+ /** Public HTTPS link fetched at send time. */
122
+ link: string;
123
+ caption?: string;
124
+ }
125
+ interface WhatsappDocument extends WhatsappMedia {
126
+ /** File name shown to the recipient. */
127
+ filename?: string;
128
+ }
129
+ interface SendWhatsappOptions {
130
+ /**
131
+ * Connected number to send from, in international format. Optional when
132
+ * your organization has a single WhatsApp number.
133
+ */
134
+ from?: string;
135
+ /** One recipient in international format (`+237670000000`). */
136
+ to: string;
137
+ /** Defaults to `text`. */
138
+ type?: WhatsappMessageType;
139
+ /** Body for `text` messages (up to 4,096 characters), or a media caption. */
140
+ text?: string;
141
+ /** Render a preview for the first link in a `text` message. */
142
+ previewUrl?: boolean;
143
+ /** Required for `type: "template"`. Needed to start a conversation outside the 24h window. */
144
+ template?: WhatsappTemplate;
145
+ /** Required for `type: "image"`. */
146
+ image?: WhatsappMedia;
147
+ /** Required for `type: "document"`. */
148
+ document?: WhatsappDocument;
149
+ }
150
+ interface SendWhatsappResponse {
151
+ id: string;
152
+ status: "queued";
153
+ type: WhatsappMessageType;
154
+ /** The connected number the message goes out from. */
155
+ from: string;
156
+ /** ISO 3166-1 alpha-2 destination country detected from the number prefix. */
157
+ country: string | null;
158
+ created_at: string;
159
+ }
160
+ interface WhatsappEvent {
161
+ type: string;
162
+ created_at: string;
163
+ }
164
+ interface GetWhatsappResponse {
165
+ id: string;
166
+ from: string;
167
+ to: string;
168
+ country: string | null;
169
+ type: WhatsappMessageType;
170
+ text: string | null;
171
+ preview_url: boolean;
172
+ template: WhatsappTemplate | null;
173
+ media: WhatsappDocument | null;
174
+ /** Upstream provider that carried the message, e.g. `meta`. */
175
+ provider: string | null;
176
+ /** Provider-side message id (`wamid.…` on Meta); inbound replies reference it. */
177
+ provider_message_id: string | null;
178
+ status: WhatsappStatus;
179
+ error: string | null;
180
+ created_at: string;
181
+ last_event_at: string | null;
182
+ events: WhatsappEvent[];
183
+ }
109
184
  interface SendBatchResponse {
110
185
  id: string;
111
186
  total: number;
@@ -149,9 +224,23 @@ declare class Sms {
149
224
  get(id: string): Promise<Result<GetSmsResponse>>;
150
225
  }
151
226
 
227
+ declare class Whatsapp {
228
+ private readonly client;
229
+ constructor(client: Retransmit);
230
+ /**
231
+ * Queues a single WhatsApp message to one recipient. Poll `get(id)` or
232
+ * subscribe to webhooks for the outcome; replies arrive as
233
+ * `whatsapp.received` webhooks.
234
+ */
235
+ send(options: SendWhatsappOptions): Promise<Result<SendWhatsappResponse>>;
236
+ /** Retrieves a WhatsApp message with its current status and event history. */
237
+ get(id: string): Promise<Result<GetWhatsappResponse>>;
238
+ }
239
+
152
240
  declare class Retransmit {
153
241
  readonly emails: Emails;
154
242
  readonly sms: Sms;
243
+ readonly whatsapp: Whatsapp;
155
244
  readonly batch: Batch;
156
245
  private readonly apiKey;
157
246
  private readonly baseUrl;
@@ -160,4 +249,4 @@ declare class Retransmit {
160
249
  request<T>(method: "GET" | "POST", path: string, body?: unknown): Promise<Result<T>>;
161
250
  }
162
251
 
163
- export { Batch, EMAIL_STATUSES, type EmailEvent, type EmailStatus, Emails, type GetBatchResponse, type GetEmailResponse, type GetSmsResponse, type Result, Retransmit, type RetransmitError, type RetransmitOptions, SMS_STATUSES, type SendBatchResponse, type SendEmailOptions, type SendEmailResponse, type SendSmsOptions, type SendSmsResponse, Sms, type SmsEvent, type SmsStatus };
252
+ export { Batch, EMAIL_STATUSES, type EmailEvent, type EmailStatus, Emails, type GetBatchResponse, type GetEmailResponse, type GetSmsResponse, type GetWhatsappResponse, type Result, Retransmit, type RetransmitError, type RetransmitOptions, SMS_STATUSES, type SendBatchResponse, type SendEmailOptions, type SendEmailResponse, type SendSmsOptions, type SendSmsResponse, type SendWhatsappOptions, type SendWhatsappResponse, Sms, type SmsEvent, type SmsStatus, WHATSAPP_STATUSES, Whatsapp, type WhatsappDocument, type WhatsappEvent, type WhatsappMedia, type WhatsappMessageType, type WhatsappStatus, type WhatsappTemplate };
package/dist/index.js CHANGED
@@ -65,6 +65,35 @@ var Sms = class {
65
65
  }
66
66
  };
67
67
 
68
+ // src/whatsapp.ts
69
+ var Whatsapp = class {
70
+ constructor(client) {
71
+ this.client = client;
72
+ }
73
+ client;
74
+ /**
75
+ * Queues a single WhatsApp message to one recipient. Poll `get(id)` or
76
+ * subscribe to webhooks for the outcome; replies arrive as
77
+ * `whatsapp.received` webhooks.
78
+ */
79
+ send(options) {
80
+ return this.client.request("POST", "/v1/whatsapp", {
81
+ from: options.from,
82
+ to: options.to,
83
+ type: options.type,
84
+ text: options.text,
85
+ preview_url: options.previewUrl,
86
+ template: options.template,
87
+ image: options.image,
88
+ document: options.document
89
+ });
90
+ }
91
+ /** Retrieves a WhatsApp message with its current status and event history. */
92
+ get(id) {
93
+ return this.client.request("GET", `/v1/whatsapp/${encodeURIComponent(id)}`);
94
+ }
95
+ };
96
+
68
97
  // src/retransmit.ts
69
98
  var DEFAULT_BASE_URL = "https://api.retransmit.dev";
70
99
  var USER_AGENT = "retransmit.dev-node/0.1.0";
@@ -74,6 +103,7 @@ function readEnv(name) {
74
103
  var Retransmit = class {
75
104
  emails = new Emails(this);
76
105
  sms = new Sms(this);
106
+ whatsapp = new Whatsapp(this);
77
107
  batch = new Batch(this);
78
108
  apiKey;
79
109
  baseUrl;
@@ -156,11 +186,14 @@ var SMS_STATUSES = [
156
186
  "rejected",
157
187
  "failed"
158
188
  ];
189
+ var WHATSAPP_STATUSES = ["queued", "sent", "delivered", "read", "failed"];
159
190
  export {
160
191
  Batch,
161
192
  EMAIL_STATUSES,
162
193
  Emails,
163
194
  Retransmit,
164
195
  SMS_STATUSES,
165
- Sms
196
+ Sms,
197
+ WHATSAPP_STATUSES,
198
+ Whatsapp
166
199
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "retransmit.dev",
3
- "version": "0.1.2",
4
- "description": "Node.js SDK for the Retransmit email and SMS APIs",
3
+ "version": "0.2.0",
4
+ "description": "Node.js SDK for the Retransmit email, SMS and WhatsApp APIs",
5
5
  "keywords": [
6
6
  "email",
7
7
  "sms",
@@ -9,7 +9,9 @@
9
9
  "retransmit",
10
10
  "ses",
11
11
  "transactional-email",
12
- "transactional-sms"
12
+ "transactional-sms",
13
+ "whatsapp",
14
+ "whatsapp-cloud-api"
13
15
  ],
14
16
  "homepage": "https://docs.retransmit.dev",
15
17
  "repository": {