@divyacon/piece-whatsapp 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.MIT-AP +24 -0
- package/README.md +8 -2
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +34 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/actions/send-from-template.d.ts +19 -0
- package/dist/lib/actions/send-from-template.d.ts.map +1 -0
- package/dist/lib/actions/send-from-template.js +111 -0
- package/dist/lib/actions/send-from-template.js.map +1 -0
- package/dist/lib/actions/send-media.d.ts +18 -0
- package/dist/lib/actions/send-media.d.ts.map +1 -0
- package/dist/lib/actions/send-media.js +84 -0
- package/dist/lib/actions/send-media.js.map +1 -0
- package/dist/lib/actions/send-message.d.ts +12 -0
- package/dist/lib/actions/send-message.d.ts.map +1 -0
- package/dist/lib/actions/send-message.js +54 -0
- package/dist/lib/actions/send-message.js.map +1 -0
- package/dist/lib/auth.d.ts +5 -0
- package/dist/lib/auth.d.ts.map +1 -0
- package/dist/lib/auth.js +36 -0
- package/dist/lib/auth.js.map +1 -0
- package/dist/lib/common/utils.d.ts +18 -0
- package/dist/lib/common/utils.d.ts.map +1 -0
- package/dist/lib/common/utils.js +196 -0
- package/dist/lib/common/utils.js.map +1 -0
- package/package.json +43 -3
- package/src/index.ts +30 -0
- package/src/lib/actions/send-from-template.ts +108 -0
- package/src/lib/actions/send-media.ts +79 -0
- package/src/lib/actions/send-message.ts +46 -0
- package/src/lib/auth.ts +32 -0
- package/src/lib/common/utils.ts +225 -0
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AuthenticationType,
|
|
3
|
+
httpClient,
|
|
4
|
+
HttpMethod,
|
|
5
|
+
QueryParams,
|
|
6
|
+
} from '@agnocon/pieces-common';
|
|
7
|
+
import { whatsappAuth } from '../auth';
|
|
8
|
+
import {
|
|
9
|
+
Property,
|
|
10
|
+
PiecePropValueSchema,
|
|
11
|
+
DynamicPropsValue,
|
|
12
|
+
DropdownOption,
|
|
13
|
+
} from '@agnocon/pieces-framework';
|
|
14
|
+
|
|
15
|
+
export const supportedMediaTypes = ['image', 'audio', 'document', 'sticker', 'video'];
|
|
16
|
+
export const capitalizeFirstLetter = (word: string) => word.charAt(0).toUpperCase() + word.slice(1);
|
|
17
|
+
export const mediaTypeSupportsCaption = (type: string) =>
|
|
18
|
+
['image', 'video', 'document'].includes(type);
|
|
19
|
+
|
|
20
|
+
export const commonProps = {
|
|
21
|
+
phone_number_id: Property.Dropdown({
|
|
22
|
+
auth: whatsappAuth,
|
|
23
|
+
displayName: 'Phone Number ID',
|
|
24
|
+
description: 'Phone number ID that will be used to send the message.',
|
|
25
|
+
refreshers: [],
|
|
26
|
+
required: true,
|
|
27
|
+
options: async ({ auth }) => {
|
|
28
|
+
if (!auth) {
|
|
29
|
+
return {
|
|
30
|
+
placeholder: 'Please connect account first',
|
|
31
|
+
disabled: true,
|
|
32
|
+
options: [],
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const authValue = auth.props;
|
|
37
|
+
|
|
38
|
+
const options: DropdownOption<string>[] = [];
|
|
39
|
+
|
|
40
|
+
let hasMore = false;
|
|
41
|
+
let cursor;
|
|
42
|
+
|
|
43
|
+
do {
|
|
44
|
+
const qs: QueryParams = {
|
|
45
|
+
fields: 'verified_name,id,display_phone_number',
|
|
46
|
+
limit: '1',
|
|
47
|
+
};
|
|
48
|
+
if (cursor) qs['after'] = cursor;
|
|
49
|
+
|
|
50
|
+
const response = await httpClient.sendRequest({
|
|
51
|
+
method: HttpMethod.GET,
|
|
52
|
+
url: `https://graph.facebook.com/v20.0/${authValue.businessAccountId}/phone_numbers`,
|
|
53
|
+
authentication: {
|
|
54
|
+
type: AuthenticationType.BEARER_TOKEN,
|
|
55
|
+
token: authValue.access_token,
|
|
56
|
+
},
|
|
57
|
+
queryParams: qs,
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
for (const phoneNumber of response.body.data) {
|
|
61
|
+
options.push({
|
|
62
|
+
label: `${phoneNumber.verified_name as string} : ${
|
|
63
|
+
phoneNumber.display_phone_number as string
|
|
64
|
+
}`,
|
|
65
|
+
value: phoneNumber.id as string,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (response.body.paging.next) {
|
|
70
|
+
(hasMore = true), (cursor = response.body.paging.cursors.after);
|
|
71
|
+
} else {
|
|
72
|
+
hasMore = false;
|
|
73
|
+
}
|
|
74
|
+
} while (hasMore);
|
|
75
|
+
|
|
76
|
+
return {
|
|
77
|
+
disabled: false,
|
|
78
|
+
options,
|
|
79
|
+
};
|
|
80
|
+
},
|
|
81
|
+
}),
|
|
82
|
+
message_template_id: Property.Dropdown({
|
|
83
|
+
displayName: 'Message Template ID',
|
|
84
|
+
refreshers: [],
|
|
85
|
+
required: true,
|
|
86
|
+
auth: whatsappAuth,
|
|
87
|
+
options: async ({ auth }) => {
|
|
88
|
+
if (!auth) {
|
|
89
|
+
return {
|
|
90
|
+
placeholder: 'Please connect account first',
|
|
91
|
+
disabled: true,
|
|
92
|
+
options: [],
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const authValue = auth.props;
|
|
97
|
+
|
|
98
|
+
const options: DropdownOption<string>[] = [];
|
|
99
|
+
|
|
100
|
+
let hasMore = false;
|
|
101
|
+
let cursor;
|
|
102
|
+
|
|
103
|
+
do {
|
|
104
|
+
const qs: QueryParams = {
|
|
105
|
+
fields: 'id,name,language',
|
|
106
|
+
limit: '1',
|
|
107
|
+
};
|
|
108
|
+
if (cursor) qs['after'] = cursor;
|
|
109
|
+
|
|
110
|
+
const response = await httpClient.sendRequest({
|
|
111
|
+
method: HttpMethod.GET,
|
|
112
|
+
url: `https://graph.facebook.com/v20.0/${authValue.businessAccountId}/message_templates`,
|
|
113
|
+
authentication: {
|
|
114
|
+
type: AuthenticationType.BEARER_TOKEN,
|
|
115
|
+
token: authValue.access_token,
|
|
116
|
+
},
|
|
117
|
+
queryParams: qs,
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
for (const template of response.body.data) {
|
|
121
|
+
options.push({
|
|
122
|
+
label: `${template.name as string} (${template.language as string})`,
|
|
123
|
+
value: template.id as string,
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (response.body.paging.next) {
|
|
128
|
+
(hasMore = true), (cursor = response.body.paging.cursors.after);
|
|
129
|
+
} else {
|
|
130
|
+
hasMore = false;
|
|
131
|
+
}
|
|
132
|
+
} while (hasMore);
|
|
133
|
+
|
|
134
|
+
return {
|
|
135
|
+
disabled: false,
|
|
136
|
+
options,
|
|
137
|
+
};
|
|
138
|
+
},
|
|
139
|
+
}),
|
|
140
|
+
|
|
141
|
+
message_template_fields: Property.DynamicProperties({
|
|
142
|
+
displayName: 'Template Fields',
|
|
143
|
+
refreshers: ['message_template_id'],
|
|
144
|
+
required: true,
|
|
145
|
+
auth: whatsappAuth,
|
|
146
|
+
props: async ({ auth, message_template_id }) => {
|
|
147
|
+
if (!auth) return {};
|
|
148
|
+
if (!message_template_id) return {};
|
|
149
|
+
|
|
150
|
+
const authValue = auth.props;
|
|
151
|
+
const templateId = message_template_id as unknown as string;
|
|
152
|
+
|
|
153
|
+
const response = await httpClient.sendRequest({
|
|
154
|
+
url: `https://graph.facebook.com/v20.0/${templateId}`,
|
|
155
|
+
method: HttpMethod.GET,
|
|
156
|
+
authentication: {
|
|
157
|
+
type: AuthenticationType.BEARER_TOKEN,
|
|
158
|
+
token: authValue.access_token,
|
|
159
|
+
},
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
const bodyComponentFields: DynamicPropsValue = {};
|
|
163
|
+
const headerComponentFields: DynamicPropsValue = {};
|
|
164
|
+
const buttonComponentFields: DynamicPropsValue = {};
|
|
165
|
+
|
|
166
|
+
for (const component of response.body.components) {
|
|
167
|
+
if (component.type === 'BODY') {
|
|
168
|
+
// https://developers.facebook.com/docs/whatsapp/business-management-api/message-templates/components#syntax
|
|
169
|
+
bodyComponentFields['BODY_markdown'] = Property.MarkDown({
|
|
170
|
+
value: `
|
|
171
|
+
**Body :**
|
|
172
|
+
${component.text}`,
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
const bodyTextVariables = component.text?.match(/{{(\d+)}}/g) ?? [];
|
|
176
|
+
|
|
177
|
+
for (let i = 0; i < bodyTextVariables.length; i++) {
|
|
178
|
+
bodyComponentFields[`body_{{${i + 1}}}`] = Property.ShortText({
|
|
179
|
+
displayName: `Body {{${i + 1}}}`,
|
|
180
|
+
required: false,
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
} else if (component.type === 'HEADER' && component.format === 'TEXT') {
|
|
184
|
+
// https://developers.facebook.com/docs/whatsapp/business-management-api/message-templates/components#text-headers
|
|
185
|
+
headerComponentFields['HEADER_markdown'] = Property.MarkDown({
|
|
186
|
+
value: `
|
|
187
|
+
**Header :**
|
|
188
|
+
${component.text}`,
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
const headerTextVariables = component.text?.match(/{{(\d+)}}/g) ?? [];
|
|
192
|
+
|
|
193
|
+
for (let i = 0; i < headerTextVariables.length; i++) {
|
|
194
|
+
headerComponentFields[`header_{{${i + 1}}}`] = Property.ShortText({
|
|
195
|
+
displayName: `Header {{${i + 1}}}`,
|
|
196
|
+
required: false,
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
} else if (component.type === 'BUTTONS') {
|
|
200
|
+
// https://developers.facebook.com/docs/whatsapp/business-management-api/message-templates/components#url-buttons
|
|
201
|
+
for (const button of component.buttons) {
|
|
202
|
+
if (button.type === 'URL') {
|
|
203
|
+
const buttonURLTextVariables = button.url?.match(/{{(\d+)}}/g) ?? [];
|
|
204
|
+
|
|
205
|
+
for (let i = 0; i < buttonURLTextVariables.length; i++) {
|
|
206
|
+
buttonComponentFields[`button_{{${i + 1}}}`] = Property.ShortText({
|
|
207
|
+
displayName: button.text,
|
|
208
|
+
required: false,
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
const templateFields: DynamicPropsValue = {
|
|
217
|
+
...headerComponentFields,
|
|
218
|
+
...bodyComponentFields,
|
|
219
|
+
...buttonComponentFields,
|
|
220
|
+
};
|
|
221
|
+
|
|
222
|
+
return templateFields;
|
|
223
|
+
},
|
|
224
|
+
}),
|
|
225
|
+
};
|