whatsapp-cloud 0.0.3 → 0.0.5
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/CHANGELOG.md +13 -0
- package/README.md +11 -0
- package/agent_docs/DESIGN.md +707 -0
- package/agent_docs/INCOMING_MESSAGES_BRAINSTORM.md +500 -0
- package/agent_docs/MESSAGES_NAMESPACE_ANALYSIS.md +368 -0
- package/agent_docs/NAMING_DECISION.md +78 -0
- package/agent_docs/STRUCTURE.md +711 -0
- package/agent_docs/messages-namespace-design.md +357 -0
- package/cloud-api-docs/webhooks/endpoint.md +112 -0
- package/cloud-api-docs/webhooks/overview.md +154 -0
- package/package.json +10 -3
- package/src/client/HttpClient.ts +159 -0
- package/src/client/WhatsAppClient.ts +58 -0
- package/src/client/index.ts +2 -0
- package/src/errors.ts +58 -0
- package/src/examples/main.ts +9 -0
- package/src/examples/template.ts +134 -0
- package/src/index.ts +16 -1
- package/src/schemas/accounts/index.ts +1 -0
- package/src/schemas/accounts/phone-number.ts +20 -0
- package/src/schemas/business/account.ts +43 -0
- package/src/schemas/business/index.ts +2 -0
- package/src/schemas/client.ts +50 -0
- package/src/schemas/debug.ts +25 -0
- package/src/schemas/index.ts +6 -0
- package/src/schemas/messages/index.ts +2 -0
- package/src/schemas/messages/request.ts +82 -0
- package/src/schemas/messages/response.ts +19 -0
- package/src/schemas/templates/component.ts +145 -0
- package/src/schemas/templates/index.ts +4 -0
- package/src/schemas/templates/request.ts +78 -0
- package/src/schemas/templates/response.ts +64 -0
- package/src/services/accounts/AccountsClient.ts +34 -0
- package/src/services/accounts/AccountsService.ts +45 -0
- package/src/services/accounts/index.ts +2 -0
- package/src/services/accounts/methods/list-phone-numbers.ts +15 -0
- package/src/services/business/BusinessClient.ts +34 -0
- package/src/services/business/BusinessService.ts +45 -0
- package/src/services/business/index.ts +3 -0
- package/src/services/business/methods/list-accounts.ts +17 -0
- package/src/services/index.ts +2 -0
- package/src/services/messages/MessagesClient.ts +34 -0
- package/src/services/messages/MessagesService.ts +97 -0
- package/src/services/messages/index.ts +8 -0
- package/src/services/messages/methods/send-image.ts +33 -0
- package/src/services/messages/methods/send-location.ts +32 -0
- package/src/services/messages/methods/send-reaction.ts +33 -0
- package/src/services/messages/methods/send-text.ts +32 -0
- package/src/services/messages/utils/build-message-payload.ts +32 -0
- package/src/services/templates/TemplatesClient.ts +35 -0
- package/src/services/templates/TemplatesService.ts +117 -0
- package/src/services/templates/index.ts +3 -0
- package/src/services/templates/methods/create.ts +27 -0
- package/src/services/templates/methods/delete.ts +38 -0
- package/src/services/templates/methods/get.ts +23 -0
- package/src/services/templates/methods/list.ts +36 -0
- package/src/services/templates/methods/update.ts +35 -0
- package/src/types/accounts/index.ts +1 -0
- package/src/types/accounts/phone-number.ts +9 -0
- package/src/types/business/account.ts +10 -0
- package/src/types/business/index.ts +2 -0
- package/src/types/client.ts +8 -0
- package/src/types/debug.ts +8 -0
- package/src/types/index.ts +6 -0
- package/src/types/messages/index.ts +2 -0
- package/src/types/messages/request.ts +27 -0
- package/src/types/messages/response.ts +7 -0
- package/src/types/templates/component.ts +33 -0
- package/src/types/templates/index.ts +4 -0
- package/src/types/templates/request.ts +28 -0
- package/src/types/templates/response.ts +34 -0
- package/src/utils/zod-error.ts +28 -0
- package/tsconfig.json +6 -4
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { MessagesClient } from "../MessagesClient";
|
|
2
|
+
import { sendImageRequestSchema } from "../../../schemas/messages/request";
|
|
3
|
+
import type { SendImageRequest } from "../../../types/messages/request";
|
|
4
|
+
import type { MessageResponse } from "../../../types/messages/response";
|
|
5
|
+
import { buildMessagePayload } from "../utils/build-message-payload";
|
|
6
|
+
import { transformZodError } from "../../../utils/zod-error";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Send an image message
|
|
10
|
+
*
|
|
11
|
+
* @param messagesClient - Messages client with phone number ID baked in
|
|
12
|
+
* @param request - Image message request (to, image)
|
|
13
|
+
*/
|
|
14
|
+
export async function sendImage(
|
|
15
|
+
messagesClient: MessagesClient,
|
|
16
|
+
request: SendImageRequest
|
|
17
|
+
): Promise<MessageResponse> {
|
|
18
|
+
// Validate request with schema - throws WhatsAppValidationError if invalid
|
|
19
|
+
const result = sendImageRequestSchema.safeParse(request);
|
|
20
|
+
if (!result.success) {
|
|
21
|
+
throw transformZodError(result.error);
|
|
22
|
+
}
|
|
23
|
+
const data = result.data;
|
|
24
|
+
|
|
25
|
+
// Build message payload using common structure
|
|
26
|
+
// The request.image already matches the API structure, so we can pass it directly
|
|
27
|
+
const payload = buildMessagePayload(data.to, "image", {
|
|
28
|
+
image: data.image,
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
// Make API request - messagesClient handles the phoneNumberId prefix automatically
|
|
32
|
+
return messagesClient.post<MessageResponse>("/messages", payload);
|
|
33
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { MessagesClient } from "../MessagesClient";
|
|
2
|
+
import { sendLocationRequestSchema } from "../../../schemas/messages/request";
|
|
3
|
+
import type { SendLocationRequest } from "../../../types/messages/request";
|
|
4
|
+
import type { MessageResponse } from "../../../types/messages/response";
|
|
5
|
+
import { buildMessagePayload } from "../utils/build-message-payload";
|
|
6
|
+
import { transformZodError } from "../../../utils/zod-error";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Send a location message
|
|
10
|
+
*
|
|
11
|
+
* @param messagesClient - Messages client with phone number ID baked in
|
|
12
|
+
* @param request - Location message request (to, location)
|
|
13
|
+
*/
|
|
14
|
+
export async function sendLocation(
|
|
15
|
+
messagesClient: MessagesClient,
|
|
16
|
+
request: SendLocationRequest
|
|
17
|
+
): Promise<MessageResponse> {
|
|
18
|
+
// Validate request with schema - throws WhatsAppValidationError if invalid
|
|
19
|
+
const result = sendLocationRequestSchema.safeParse(request);
|
|
20
|
+
if (!result.success) {
|
|
21
|
+
throw transformZodError(result.error);
|
|
22
|
+
}
|
|
23
|
+
const data = result.data;
|
|
24
|
+
|
|
25
|
+
// Build message payload using common structure
|
|
26
|
+
const payload = buildMessagePayload(data.to, "location", {
|
|
27
|
+
location: data.location,
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
// Make API request - messagesClient handles the phoneNumberId prefix automatically
|
|
31
|
+
return messagesClient.post<MessageResponse>("/messages", payload);
|
|
32
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { MessagesClient } from "../MessagesClient";
|
|
2
|
+
import { sendReactionRequestSchema } from "../../../schemas/messages/request";
|
|
3
|
+
import type { SendReactionRequest } from "../../../types/messages/request";
|
|
4
|
+
import type { MessageResponse } from "../../../types/messages/response";
|
|
5
|
+
import { buildMessagePayload } from "../utils/build-message-payload";
|
|
6
|
+
import { transformZodError } from "../../../utils/zod-error";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Send a reaction message
|
|
10
|
+
*
|
|
11
|
+
* @param messagesClient - Messages client with phone number ID baked in
|
|
12
|
+
* @param request - Reaction message request (to, reaction)
|
|
13
|
+
*/
|
|
14
|
+
export async function sendReaction(
|
|
15
|
+
messagesClient: MessagesClient,
|
|
16
|
+
request: SendReactionRequest
|
|
17
|
+
): Promise<MessageResponse> {
|
|
18
|
+
// Validate request with schema - throws WhatsAppValidationError if invalid
|
|
19
|
+
const result = sendReactionRequestSchema.safeParse(request);
|
|
20
|
+
if (!result.success) {
|
|
21
|
+
throw transformZodError(result.error);
|
|
22
|
+
}
|
|
23
|
+
const data = result.data;
|
|
24
|
+
|
|
25
|
+
// Build message payload using common structure
|
|
26
|
+
const payload = buildMessagePayload(data.to, "reaction", {
|
|
27
|
+
reaction: data.reaction,
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
// Make API request - messagesClient handles the phoneNumberId prefix automatically
|
|
31
|
+
return messagesClient.post<MessageResponse>("/messages", payload);
|
|
32
|
+
}
|
|
33
|
+
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { MessagesClient } from "../MessagesClient";
|
|
2
|
+
import { sendTextRequestSchema } from "../../../schemas/messages/request";
|
|
3
|
+
import type { SendTextRequest } from "../../../types/messages/request";
|
|
4
|
+
import type { MessageResponse } from "../../../types/messages/response";
|
|
5
|
+
import { buildMessagePayload } from "../utils/build-message-payload";
|
|
6
|
+
import { transformZodError } from "../../../utils/zod-error";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Send a text message
|
|
10
|
+
*
|
|
11
|
+
* @param messagesClient - Messages client with phone number ID baked in
|
|
12
|
+
* @param request - Text message request (to, text)
|
|
13
|
+
*/
|
|
14
|
+
export async function sendText(
|
|
15
|
+
messagesClient: MessagesClient,
|
|
16
|
+
request: SendTextRequest
|
|
17
|
+
): Promise<MessageResponse> {
|
|
18
|
+
// Validate request with schema - throws WhatsAppValidationError if invalid
|
|
19
|
+
const result = sendTextRequestSchema.safeParse(request);
|
|
20
|
+
if (!result.success) {
|
|
21
|
+
throw transformZodError(result.error);
|
|
22
|
+
}
|
|
23
|
+
const data = result.data;
|
|
24
|
+
|
|
25
|
+
// Build message payload using common structure
|
|
26
|
+
const payload = buildMessagePayload(data.to, "text", {
|
|
27
|
+
text: data.text,
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
// Make API request - messagesClient handles the phoneNumberId prefix automatically
|
|
31
|
+
return messagesClient.post<MessageResponse>("/messages", payload);
|
|
32
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Builds the base message payload structure that's common to all WhatsApp messages
|
|
3
|
+
*
|
|
4
|
+
* According to WhatsApp API docs, all messages follow this structure:
|
|
5
|
+
* {
|
|
6
|
+
* "messaging_product": "whatsapp",
|
|
7
|
+
* "recipient_type": "individual",
|
|
8
|
+
* "to": "<WHATSAPP_USER_PHONE_NUMBER>",
|
|
9
|
+
* "type": "<MESSAGE_TYPE>",
|
|
10
|
+
* "<MESSAGE_TYPE>": {<MESSAGE_CONTENTS>}
|
|
11
|
+
* }
|
|
12
|
+
*
|
|
13
|
+
* Note: undefined values in content are automatically omitted by JSON.stringify
|
|
14
|
+
*
|
|
15
|
+
* @param to - WhatsApp phone number (E.164 format)
|
|
16
|
+
* @param type - Message type (text, image, video, etc.)
|
|
17
|
+
* @param content - Message-specific content object
|
|
18
|
+
* @returns Complete message payload ready for API request
|
|
19
|
+
*/
|
|
20
|
+
export function buildMessagePayload<T extends Record<string, unknown>>(
|
|
21
|
+
to: string,
|
|
22
|
+
type: string,
|
|
23
|
+
content: T
|
|
24
|
+
) {
|
|
25
|
+
return {
|
|
26
|
+
messaging_product: "whatsapp" as const,
|
|
27
|
+
recipient_type: "individual" as const,
|
|
28
|
+
to,
|
|
29
|
+
type,
|
|
30
|
+
...content,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { HttpClient } from "../../client/HttpClient";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Templates client - wraps HttpClient with WABA ID as base endpoint
|
|
5
|
+
*
|
|
6
|
+
* This client automatically prepends `/${businessAccountId}` to all request paths.
|
|
7
|
+
* Similar to AccountsClient, since templates are scoped to WABA.
|
|
8
|
+
*/
|
|
9
|
+
export class TemplatesClient {
|
|
10
|
+
constructor(
|
|
11
|
+
private readonly httpClient: HttpClient,
|
|
12
|
+
private readonly businessAccountId: string
|
|
13
|
+
) {}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Make a GET request with WABA ID prefix
|
|
17
|
+
*/
|
|
18
|
+
async get<T>(path: string): Promise<T> {
|
|
19
|
+
return this.httpClient.get<T>(`/${this.businessAccountId}${path}`);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Make a POST request with WABA ID prefix
|
|
24
|
+
*/
|
|
25
|
+
async post<T>(path: string, body: unknown): Promise<T> {
|
|
26
|
+
return this.httpClient.post<T>(`/${this.businessAccountId}${path}`, body);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Make a DELETE request with WABA ID prefix
|
|
31
|
+
*/
|
|
32
|
+
async delete<T>(path: string): Promise<T> {
|
|
33
|
+
return this.httpClient.delete<T>(`/${this.businessAccountId}${path}`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import type { HttpClient } from "../../client/HttpClient";
|
|
2
|
+
import { TemplatesClient } from "./TemplatesClient";
|
|
3
|
+
import { createTemplate } from "./methods/create";
|
|
4
|
+
import { listTemplates } from "./methods/list";
|
|
5
|
+
import { getTemplate } from "./methods/get";
|
|
6
|
+
import { updateTemplate } from "./methods/update";
|
|
7
|
+
import { deleteTemplate } from "./methods/delete";
|
|
8
|
+
import { WhatsAppValidationError } from "../../errors";
|
|
9
|
+
import type {
|
|
10
|
+
CreateTemplateRequest,
|
|
11
|
+
UpdateTemplateRequest,
|
|
12
|
+
ListTemplatesRequest,
|
|
13
|
+
DeleteTemplateRequest,
|
|
14
|
+
} from "../../types/templates/request";
|
|
15
|
+
import type {
|
|
16
|
+
CreateTemplateResponse,
|
|
17
|
+
ListTemplatesResponse,
|
|
18
|
+
TemplateResponse,
|
|
19
|
+
UpdateTemplateResponse,
|
|
20
|
+
DeleteTemplateResponse,
|
|
21
|
+
} from "../../types/templates/response";
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Templates service for managing message templates
|
|
25
|
+
*
|
|
26
|
+
* This service handles template operations like creating, listing, and deleting templates.
|
|
27
|
+
* It supports both a globally configured businessAccountId (in WhatsAppClient)
|
|
28
|
+
* and per-request businessAccountId overrides.
|
|
29
|
+
*
|
|
30
|
+
* Note: Get and Update operations use template ID directly (no WABA prefix needed).
|
|
31
|
+
*/
|
|
32
|
+
export class TemplatesService {
|
|
33
|
+
constructor(private readonly httpClient: HttpClient) {}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Helper to create a Scoped Client (prefer override, fallback to config)
|
|
37
|
+
*/
|
|
38
|
+
private getClient(overrideId?: string): TemplatesClient {
|
|
39
|
+
const id = overrideId || this.httpClient.businessAccountId;
|
|
40
|
+
if (!id) {
|
|
41
|
+
throw new WhatsAppValidationError(
|
|
42
|
+
"businessAccountId (WABA ID) is required for templates. Provide it in WhatsAppClient config or as a parameter.",
|
|
43
|
+
"businessAccountId"
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return new TemplatesClient(this.httpClient, id);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Create a message template
|
|
52
|
+
*
|
|
53
|
+
* @param request - Template creation request
|
|
54
|
+
* @param businessAccountId - Optional WABA ID (overrides client config)
|
|
55
|
+
*/
|
|
56
|
+
async create(
|
|
57
|
+
request: CreateTemplateRequest,
|
|
58
|
+
businessAccountId?: string
|
|
59
|
+
): Promise<CreateTemplateResponse> {
|
|
60
|
+
const client = this.getClient(businessAccountId);
|
|
61
|
+
return createTemplate(client, request);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* List message templates
|
|
66
|
+
*
|
|
67
|
+
* @param options - Optional filter options (name)
|
|
68
|
+
* @param businessAccountId - Optional WABA ID (overrides client config)
|
|
69
|
+
*/
|
|
70
|
+
async list(
|
|
71
|
+
options?: ListTemplatesRequest,
|
|
72
|
+
businessAccountId?: string
|
|
73
|
+
): Promise<ListTemplatesResponse> {
|
|
74
|
+
const client = this.getClient(businessAccountId);
|
|
75
|
+
return listTemplates(client, options);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Get a template by ID
|
|
80
|
+
*
|
|
81
|
+
* Note: This uses the template ID directly (no WABA prefix needed)
|
|
82
|
+
*
|
|
83
|
+
* @param templateId - Template ID
|
|
84
|
+
*/
|
|
85
|
+
async get(templateId: string): Promise<TemplateResponse> {
|
|
86
|
+
return getTemplate(this.httpClient, templateId);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Update a template
|
|
91
|
+
*
|
|
92
|
+
* Note: This uses the template ID directly (no WABA prefix needed)
|
|
93
|
+
*
|
|
94
|
+
* @param templateId - Template ID
|
|
95
|
+
* @param request - Template update request
|
|
96
|
+
*/
|
|
97
|
+
async update(
|
|
98
|
+
templateId: string,
|
|
99
|
+
request: UpdateTemplateRequest
|
|
100
|
+
): Promise<UpdateTemplateResponse> {
|
|
101
|
+
return updateTemplate(this.httpClient, templateId, request);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Delete a template
|
|
106
|
+
*
|
|
107
|
+
* @param options - Delete options (name or hsm_id)
|
|
108
|
+
* @param businessAccountId - Optional WABA ID (overrides client config)
|
|
109
|
+
*/
|
|
110
|
+
async delete(
|
|
111
|
+
options: DeleteTemplateRequest,
|
|
112
|
+
businessAccountId?: string
|
|
113
|
+
): Promise<DeleteTemplateResponse> {
|
|
114
|
+
const client = this.getClient(businessAccountId);
|
|
115
|
+
return deleteTemplate(client, options);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { TemplatesClient } from "../TemplatesClient";
|
|
2
|
+
import { createTemplateRequestSchema } from "../../../schemas/templates/request";
|
|
3
|
+
import type { CreateTemplateRequest } from "../../../types/templates/request";
|
|
4
|
+
import type { CreateTemplateResponse } from "../../../types/templates/response";
|
|
5
|
+
import { transformZodError } from "../../../utils/zod-error";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Create a message template
|
|
9
|
+
*
|
|
10
|
+
* @param templatesClient - Templates client with WABA ID baked in
|
|
11
|
+
* @param request - Template creation request
|
|
12
|
+
*/
|
|
13
|
+
export async function createTemplate(
|
|
14
|
+
templatesClient: TemplatesClient,
|
|
15
|
+
request: CreateTemplateRequest
|
|
16
|
+
): Promise<CreateTemplateResponse> {
|
|
17
|
+
// Validate request with schema - throws WhatsAppValidationError if invalid
|
|
18
|
+
const result = createTemplateRequestSchema.safeParse(request);
|
|
19
|
+
if (!result.success) {
|
|
20
|
+
throw transformZodError(result.error);
|
|
21
|
+
}
|
|
22
|
+
const data = result.data;
|
|
23
|
+
|
|
24
|
+
// Make API request - templatesClient handles the WABA ID prefix automatically
|
|
25
|
+
return templatesClient.post<CreateTemplateResponse>("/message_templates", data);
|
|
26
|
+
}
|
|
27
|
+
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { TemplatesClient } from "../TemplatesClient";
|
|
2
|
+
import { deleteTemplateRequestSchema } from "../../../schemas/templates/request";
|
|
3
|
+
import type { DeleteTemplateRequest } from "../../../types/templates/request";
|
|
4
|
+
import type { DeleteTemplateResponse } from "../../../types/templates/response";
|
|
5
|
+
import { transformZodError } from "../../../utils/zod-error";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Delete a template
|
|
9
|
+
*
|
|
10
|
+
* @param templatesClient - Templates client with WABA ID baked in
|
|
11
|
+
* @param options - Delete options (name or hsm_id)
|
|
12
|
+
*/
|
|
13
|
+
export async function deleteTemplate(
|
|
14
|
+
templatesClient: TemplatesClient,
|
|
15
|
+
options: DeleteTemplateRequest
|
|
16
|
+
): Promise<DeleteTemplateResponse> {
|
|
17
|
+
// Validate request with schema - throws WhatsAppValidationError if invalid
|
|
18
|
+
const result = deleteTemplateRequestSchema.safeParse(options);
|
|
19
|
+
if (!result.success) {
|
|
20
|
+
throw transformZodError(result.error);
|
|
21
|
+
}
|
|
22
|
+
const data = result.data;
|
|
23
|
+
|
|
24
|
+
// Build query string
|
|
25
|
+
const params = new URLSearchParams();
|
|
26
|
+
if (data.name) {
|
|
27
|
+
params.append("name", data.name);
|
|
28
|
+
}
|
|
29
|
+
if (data.hsm_id) {
|
|
30
|
+
params.append("hsm_id", data.hsm_id);
|
|
31
|
+
}
|
|
32
|
+
const queryString = params.toString();
|
|
33
|
+
const path = `/message_templates?${queryString}`;
|
|
34
|
+
|
|
35
|
+
// Make API request - templatesClient handles the WABA ID prefix automatically
|
|
36
|
+
return templatesClient.delete<DeleteTemplateResponse>(path);
|
|
37
|
+
}
|
|
38
|
+
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { HttpClient } from "../../../client/HttpClient";
|
|
2
|
+
import type { TemplateResponse } from "../../../types/templates/response";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Get a template by ID
|
|
6
|
+
*
|
|
7
|
+
* Note: This uses the template ID directly (no WABA prefix needed)
|
|
8
|
+
*
|
|
9
|
+
* @param httpClient - HTTP client
|
|
10
|
+
* @param templateId - Template ID
|
|
11
|
+
*/
|
|
12
|
+
export async function getTemplate(
|
|
13
|
+
httpClient: HttpClient,
|
|
14
|
+
templateId: string
|
|
15
|
+
): Promise<TemplateResponse> {
|
|
16
|
+
if (!templateId || templateId.trim().length === 0) {
|
|
17
|
+
throw new Error("Template ID is required");
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// Make API request - template ID is used directly, no WABA prefix
|
|
21
|
+
return httpClient.get<TemplateResponse>(`/${templateId}`);
|
|
22
|
+
}
|
|
23
|
+
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { TemplatesClient } from "../TemplatesClient";
|
|
2
|
+
import { listTemplatesRequestSchema } from "../../../schemas/templates/request";
|
|
3
|
+
import type { ListTemplatesRequest } from "../../../types/templates/request";
|
|
4
|
+
import type { ListTemplatesResponse } from "../../../types/templates/response";
|
|
5
|
+
import { transformZodError } from "../../../utils/zod-error";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* List message templates
|
|
9
|
+
*
|
|
10
|
+
* @param templatesClient - Templates client with WABA ID baked in
|
|
11
|
+
* @param options - Optional filter options (name)
|
|
12
|
+
*/
|
|
13
|
+
export async function listTemplates(
|
|
14
|
+
templatesClient: TemplatesClient,
|
|
15
|
+
options?: ListTemplatesRequest
|
|
16
|
+
): Promise<ListTemplatesResponse> {
|
|
17
|
+
// Validate options if provided
|
|
18
|
+
if (options) {
|
|
19
|
+
const result = listTemplatesRequestSchema.safeParse(options);
|
|
20
|
+
if (!result.success) {
|
|
21
|
+
throw transformZodError(result.error);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Build query string
|
|
26
|
+
const params = new URLSearchParams();
|
|
27
|
+
if (options?.name) {
|
|
28
|
+
params.append("name", options.name);
|
|
29
|
+
}
|
|
30
|
+
const queryString = params.toString();
|
|
31
|
+
const path = queryString ? `/message_templates?${queryString}` : "/message_templates";
|
|
32
|
+
|
|
33
|
+
// Make API request - templatesClient handles the WABA ID prefix automatically
|
|
34
|
+
return templatesClient.get<ListTemplatesResponse>(path);
|
|
35
|
+
}
|
|
36
|
+
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { HttpClient } from "../../../client/HttpClient";
|
|
2
|
+
import { updateTemplateRequestSchema } from "../../../schemas/templates/request";
|
|
3
|
+
import type { UpdateTemplateRequest } from "../../../types/templates/request";
|
|
4
|
+
import type { UpdateTemplateResponse } from "../../../types/templates/response";
|
|
5
|
+
import { transformZodError } from "../../../utils/zod-error";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Update a template
|
|
9
|
+
*
|
|
10
|
+
* Note: This uses the template ID directly (no WABA prefix needed)
|
|
11
|
+
*
|
|
12
|
+
* @param httpClient - HTTP client
|
|
13
|
+
* @param templateId - Template ID
|
|
14
|
+
* @param request - Template update request
|
|
15
|
+
*/
|
|
16
|
+
export async function updateTemplate(
|
|
17
|
+
httpClient: HttpClient,
|
|
18
|
+
templateId: string,
|
|
19
|
+
request: UpdateTemplateRequest
|
|
20
|
+
): Promise<UpdateTemplateResponse> {
|
|
21
|
+
if (!templateId || templateId.trim().length === 0) {
|
|
22
|
+
throw new Error("Template ID is required");
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Validate request with schema - throws WhatsAppValidationError if invalid
|
|
26
|
+
const result = updateTemplateRequestSchema.safeParse(request);
|
|
27
|
+
if (!result.success) {
|
|
28
|
+
throw transformZodError(result.error);
|
|
29
|
+
}
|
|
30
|
+
const data = result.data;
|
|
31
|
+
|
|
32
|
+
// Make API request - template ID is used directly, no WABA prefix
|
|
33
|
+
return httpClient.post<UpdateTemplateResponse>(`/${templateId}`, data);
|
|
34
|
+
}
|
|
35
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type * from "./phone-number";
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { businessAccountsListResponseSchema } from "../../schemas/business/account";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Type for WhatsApp Business Accounts list response
|
|
6
|
+
*/
|
|
7
|
+
export type BusinessAccountsListResponse = z.infer<
|
|
8
|
+
typeof businessAccountsListResponseSchema
|
|
9
|
+
>;
|
|
10
|
+
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import {
|
|
3
|
+
sendTextRequestSchema,
|
|
4
|
+
sendImageRequestSchema,
|
|
5
|
+
sendLocationRequestSchema,
|
|
6
|
+
sendReactionRequestSchema,
|
|
7
|
+
} from "../../schemas/messages/request";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Type for sending a text message
|
|
11
|
+
*/
|
|
12
|
+
export type SendTextRequest = z.infer<typeof sendTextRequestSchema>;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Type for sending an image message
|
|
16
|
+
*/
|
|
17
|
+
export type SendImageRequest = z.infer<typeof sendImageRequestSchema>;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Type for sending a location message
|
|
21
|
+
*/
|
|
22
|
+
export type SendLocationRequest = z.infer<typeof sendLocationRequestSchema>;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Type for sending a reaction message
|
|
26
|
+
*/
|
|
27
|
+
export type SendReactionRequest = z.infer<typeof sendReactionRequestSchema>;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import {
|
|
3
|
+
buttonSchema,
|
|
4
|
+
componentSchema,
|
|
5
|
+
quickReplyButtonSchema,
|
|
6
|
+
urlButtonSchema,
|
|
7
|
+
phoneNumberButtonSchema,
|
|
8
|
+
copyCodeButtonSchema,
|
|
9
|
+
flowButtonSchema,
|
|
10
|
+
headerComponentSchema,
|
|
11
|
+
bodyComponentSchema,
|
|
12
|
+
footerComponentSchema,
|
|
13
|
+
buttonsComponentSchema,
|
|
14
|
+
} from "../../schemas/templates/component";
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Button types
|
|
18
|
+
*/
|
|
19
|
+
export type QuickReplyButton = z.infer<typeof quickReplyButtonSchema>;
|
|
20
|
+
export type UrlButton = z.infer<typeof urlButtonSchema>;
|
|
21
|
+
export type PhoneNumberButton = z.infer<typeof phoneNumberButtonSchema>;
|
|
22
|
+
export type CopyCodeButton = z.infer<typeof copyCodeButtonSchema>;
|
|
23
|
+
export type FlowButton = z.infer<typeof flowButtonSchema>;
|
|
24
|
+
export type Button = z.infer<typeof buttonSchema>;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Component types
|
|
28
|
+
*/
|
|
29
|
+
export type HeaderComponent = z.infer<typeof headerComponentSchema>;
|
|
30
|
+
export type BodyComponent = z.infer<typeof bodyComponentSchema>;
|
|
31
|
+
export type FooterComponent = z.infer<typeof footerComponentSchema>;
|
|
32
|
+
export type ButtonsComponent = z.infer<typeof buttonsComponentSchema>;
|
|
33
|
+
export type Component = z.infer<typeof componentSchema>;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import {
|
|
3
|
+
createTemplateRequestSchema,
|
|
4
|
+
updateTemplateRequestSchema,
|
|
5
|
+
listTemplatesRequestSchema,
|
|
6
|
+
deleteTemplateRequestSchema,
|
|
7
|
+
} from "../../schemas/templates/request";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Type for creating a template
|
|
11
|
+
*/
|
|
12
|
+
export type CreateTemplateRequest = z.infer<typeof createTemplateRequestSchema>;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Type for updating a template
|
|
16
|
+
*/
|
|
17
|
+
export type UpdateTemplateRequest = z.infer<typeof updateTemplateRequestSchema>;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Type for listing templates
|
|
21
|
+
*/
|
|
22
|
+
export type ListTemplatesRequest = z.infer<typeof listTemplatesRequestSchema>;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Type for deleting a template
|
|
26
|
+
*/
|
|
27
|
+
export type DeleteTemplateRequest = z.infer<typeof deleteTemplateRequestSchema>;
|
|
28
|
+
|