@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,196 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.commonProps = exports.mediaTypeSupportsCaption = exports.capitalizeFirstLetter = exports.supportedMediaTypes = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
// Vendored from Activepieces packages/pieces/community/whatsapp/src/lib/common/utils.ts (MIT).
|
|
6
|
+
// Generated by packages/scripts/vendor-ap.mjs - do not edit by hand.
|
|
7
|
+
const pieces_common_1 = require("@agnocon/pieces-common");
|
|
8
|
+
const auth_1 = require("../auth");
|
|
9
|
+
const pieces_framework_1 = require("@agnocon/pieces-framework");
|
|
10
|
+
exports.supportedMediaTypes = ['image', 'audio', 'document', 'sticker', 'video'];
|
|
11
|
+
const capitalizeFirstLetter = (word) => word.charAt(0).toUpperCase() + word.slice(1);
|
|
12
|
+
exports.capitalizeFirstLetter = capitalizeFirstLetter;
|
|
13
|
+
const mediaTypeSupportsCaption = (type) => ['image', 'video', 'document'].includes(type);
|
|
14
|
+
exports.mediaTypeSupportsCaption = mediaTypeSupportsCaption;
|
|
15
|
+
exports.commonProps = {
|
|
16
|
+
phone_number_id: pieces_framework_1.Property.Dropdown({
|
|
17
|
+
auth: auth_1.whatsappAuth,
|
|
18
|
+
displayName: 'Phone Number ID',
|
|
19
|
+
description: 'Phone number ID that will be used to send the message.',
|
|
20
|
+
refreshers: [],
|
|
21
|
+
required: true,
|
|
22
|
+
options: (_a) => tslib_1.__awaiter(void 0, [_a], void 0, function* ({ auth }) {
|
|
23
|
+
if (!auth) {
|
|
24
|
+
return {
|
|
25
|
+
placeholder: 'Please connect account first',
|
|
26
|
+
disabled: true,
|
|
27
|
+
options: [],
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
const authValue = auth.props;
|
|
31
|
+
const options = [];
|
|
32
|
+
let hasMore = false;
|
|
33
|
+
let cursor;
|
|
34
|
+
do {
|
|
35
|
+
const qs = {
|
|
36
|
+
fields: 'verified_name,id,display_phone_number',
|
|
37
|
+
limit: '1',
|
|
38
|
+
};
|
|
39
|
+
if (cursor)
|
|
40
|
+
qs['after'] = cursor;
|
|
41
|
+
const response = yield pieces_common_1.httpClient.sendRequest({
|
|
42
|
+
method: pieces_common_1.HttpMethod.GET,
|
|
43
|
+
url: `https://graph.facebook.com/v20.0/${authValue.businessAccountId}/phone_numbers`,
|
|
44
|
+
authentication: {
|
|
45
|
+
type: pieces_common_1.AuthenticationType.BEARER_TOKEN,
|
|
46
|
+
token: authValue.access_token,
|
|
47
|
+
},
|
|
48
|
+
queryParams: qs,
|
|
49
|
+
});
|
|
50
|
+
for (const phoneNumber of response.body.data) {
|
|
51
|
+
options.push({
|
|
52
|
+
label: `${phoneNumber.verified_name} : ${phoneNumber.display_phone_number}`,
|
|
53
|
+
value: phoneNumber.id,
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
if (response.body.paging.next) {
|
|
57
|
+
(hasMore = true), (cursor = response.body.paging.cursors.after);
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
hasMore = false;
|
|
61
|
+
}
|
|
62
|
+
} while (hasMore);
|
|
63
|
+
return {
|
|
64
|
+
disabled: false,
|
|
65
|
+
options,
|
|
66
|
+
};
|
|
67
|
+
}),
|
|
68
|
+
}),
|
|
69
|
+
message_template_id: pieces_framework_1.Property.Dropdown({
|
|
70
|
+
displayName: 'Message Template ID',
|
|
71
|
+
refreshers: [],
|
|
72
|
+
required: true,
|
|
73
|
+
auth: auth_1.whatsappAuth,
|
|
74
|
+
options: (_a) => tslib_1.__awaiter(void 0, [_a], void 0, function* ({ auth }) {
|
|
75
|
+
if (!auth) {
|
|
76
|
+
return {
|
|
77
|
+
placeholder: 'Please connect account first',
|
|
78
|
+
disabled: true,
|
|
79
|
+
options: [],
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
const authValue = auth.props;
|
|
83
|
+
const options = [];
|
|
84
|
+
let hasMore = false;
|
|
85
|
+
let cursor;
|
|
86
|
+
do {
|
|
87
|
+
const qs = {
|
|
88
|
+
fields: 'id,name,language',
|
|
89
|
+
limit: '1',
|
|
90
|
+
};
|
|
91
|
+
if (cursor)
|
|
92
|
+
qs['after'] = cursor;
|
|
93
|
+
const response = yield pieces_common_1.httpClient.sendRequest({
|
|
94
|
+
method: pieces_common_1.HttpMethod.GET,
|
|
95
|
+
url: `https://graph.facebook.com/v20.0/${authValue.businessAccountId}/message_templates`,
|
|
96
|
+
authentication: {
|
|
97
|
+
type: pieces_common_1.AuthenticationType.BEARER_TOKEN,
|
|
98
|
+
token: authValue.access_token,
|
|
99
|
+
},
|
|
100
|
+
queryParams: qs,
|
|
101
|
+
});
|
|
102
|
+
for (const template of response.body.data) {
|
|
103
|
+
options.push({
|
|
104
|
+
label: `${template.name} (${template.language})`,
|
|
105
|
+
value: template.id,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
if (response.body.paging.next) {
|
|
109
|
+
(hasMore = true), (cursor = response.body.paging.cursors.after);
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
hasMore = false;
|
|
113
|
+
}
|
|
114
|
+
} while (hasMore);
|
|
115
|
+
return {
|
|
116
|
+
disabled: false,
|
|
117
|
+
options,
|
|
118
|
+
};
|
|
119
|
+
}),
|
|
120
|
+
}),
|
|
121
|
+
message_template_fields: pieces_framework_1.Property.DynamicProperties({
|
|
122
|
+
displayName: 'Template Fields',
|
|
123
|
+
refreshers: ['message_template_id'],
|
|
124
|
+
required: true,
|
|
125
|
+
auth: auth_1.whatsappAuth,
|
|
126
|
+
props: (_a) => tslib_1.__awaiter(void 0, [_a], void 0, function* ({ auth, message_template_id }) {
|
|
127
|
+
var _b, _c, _d, _e, _f, _g;
|
|
128
|
+
if (!auth)
|
|
129
|
+
return {};
|
|
130
|
+
if (!message_template_id)
|
|
131
|
+
return {};
|
|
132
|
+
const authValue = auth.props;
|
|
133
|
+
const templateId = message_template_id;
|
|
134
|
+
const response = yield pieces_common_1.httpClient.sendRequest({
|
|
135
|
+
url: `https://graph.facebook.com/v20.0/${templateId}`,
|
|
136
|
+
method: pieces_common_1.HttpMethod.GET,
|
|
137
|
+
authentication: {
|
|
138
|
+
type: pieces_common_1.AuthenticationType.BEARER_TOKEN,
|
|
139
|
+
token: authValue.access_token,
|
|
140
|
+
},
|
|
141
|
+
});
|
|
142
|
+
const bodyComponentFields = {};
|
|
143
|
+
const headerComponentFields = {};
|
|
144
|
+
const buttonComponentFields = {};
|
|
145
|
+
for (const component of response.body.components) {
|
|
146
|
+
if (component.type === 'BODY') {
|
|
147
|
+
// https://developers.facebook.com/docs/whatsapp/business-management-api/message-templates/components#syntax
|
|
148
|
+
bodyComponentFields['BODY_markdown'] = pieces_framework_1.Property.MarkDown({
|
|
149
|
+
value: `
|
|
150
|
+
**Body :**
|
|
151
|
+
${component.text}`,
|
|
152
|
+
});
|
|
153
|
+
const bodyTextVariables = (_c = (_b = component.text) === null || _b === void 0 ? void 0 : _b.match(/{{(\d+)}}/g)) !== null && _c !== void 0 ? _c : [];
|
|
154
|
+
for (let i = 0; i < bodyTextVariables.length; i++) {
|
|
155
|
+
bodyComponentFields[`body_{{${i + 1}}}`] = pieces_framework_1.Property.ShortText({
|
|
156
|
+
displayName: `Body {{${i + 1}}}`,
|
|
157
|
+
required: false,
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
else if (component.type === 'HEADER' && component.format === 'TEXT') {
|
|
162
|
+
// https://developers.facebook.com/docs/whatsapp/business-management-api/message-templates/components#text-headers
|
|
163
|
+
headerComponentFields['HEADER_markdown'] = pieces_framework_1.Property.MarkDown({
|
|
164
|
+
value: `
|
|
165
|
+
**Header :**
|
|
166
|
+
${component.text}`,
|
|
167
|
+
});
|
|
168
|
+
const headerTextVariables = (_e = (_d = component.text) === null || _d === void 0 ? void 0 : _d.match(/{{(\d+)}}/g)) !== null && _e !== void 0 ? _e : [];
|
|
169
|
+
for (let i = 0; i < headerTextVariables.length; i++) {
|
|
170
|
+
headerComponentFields[`header_{{${i + 1}}}`] = pieces_framework_1.Property.ShortText({
|
|
171
|
+
displayName: `Header {{${i + 1}}}`,
|
|
172
|
+
required: false,
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
else if (component.type === 'BUTTONS') {
|
|
177
|
+
// https://developers.facebook.com/docs/whatsapp/business-management-api/message-templates/components#url-buttons
|
|
178
|
+
for (const button of component.buttons) {
|
|
179
|
+
if (button.type === 'URL') {
|
|
180
|
+
const buttonURLTextVariables = (_g = (_f = button.url) === null || _f === void 0 ? void 0 : _f.match(/{{(\d+)}}/g)) !== null && _g !== void 0 ? _g : [];
|
|
181
|
+
for (let i = 0; i < buttonURLTextVariables.length; i++) {
|
|
182
|
+
buttonComponentFields[`button_{{${i + 1}}}`] = pieces_framework_1.Property.ShortText({
|
|
183
|
+
displayName: button.text,
|
|
184
|
+
required: false,
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
const templateFields = Object.assign(Object.assign(Object.assign({}, headerComponentFields), bodyComponentFields), buttonComponentFields);
|
|
192
|
+
return templateFields;
|
|
193
|
+
}),
|
|
194
|
+
}),
|
|
195
|
+
};
|
|
196
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/lib/common/utils.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,46 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@divyacon/piece-whatsapp",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "DivyaCon whatsapp connector",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"require": "./dist/index.js",
|
|
11
|
+
"default": "./dist/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist",
|
|
16
|
+
"src",
|
|
17
|
+
"LICENSE.MIT-AP"
|
|
18
|
+
],
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "tsc -p tsconfig.json",
|
|
21
|
+
"vendor": "node ../scripts/vendor-ap.mjs piece-whatsapp"
|
|
22
|
+
},
|
|
23
|
+
"dependencies": {
|
|
24
|
+
"@agnocon/core-utils": "0.2.0",
|
|
25
|
+
"@agnocon/piece-types": "0.3.1",
|
|
26
|
+
"@agnocon/pieces-common": "0.12.8",
|
|
27
|
+
"@agnocon/pieces-framework": "0.36.0",
|
|
28
|
+
"tslib": "2.6.2"
|
|
29
|
+
},
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"@types/node": "20.17.6",
|
|
32
|
+
"typescript": "5.5.4"
|
|
33
|
+
},
|
|
34
|
+
"license": "MIT",
|
|
35
|
+
"agnocon": {
|
|
36
|
+
"originVersion": "0.2.6"
|
|
37
|
+
},
|
|
38
|
+
"publishConfig": {
|
|
39
|
+
"access": "public",
|
|
40
|
+
"tag": "latest"
|
|
41
|
+
},
|
|
42
|
+
"keywords": [
|
|
43
|
+
"agnocon",
|
|
44
|
+
"connector"
|
|
45
|
+
]
|
|
6
46
|
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { createPiece, PieceAuth, Property } from '@agnocon/pieces-framework';
|
|
2
|
+
import { sendMessage } from './lib/actions/send-message';
|
|
3
|
+
import { sendMedia } from './lib/actions/send-media';
|
|
4
|
+
import { sendTemplateMessageAction } from './lib/actions/send-from-template';
|
|
5
|
+
import { whatsappAuth } from './lib/auth';
|
|
6
|
+
|
|
7
|
+
const markdown = `
|
|
8
|
+
To Obtain a Phone Number ID and a Permanent System User Access Token, follow these steps:
|
|
9
|
+
|
|
10
|
+
1. Go to https://developers.facebook.com/
|
|
11
|
+
2. Make a new app, Select Other for usecase.
|
|
12
|
+
3. Choose Business as the type of app.
|
|
13
|
+
4. Add new Product -> WhatsApp.
|
|
14
|
+
5. Navigate to WhatsApp Settings > API Setup.
|
|
15
|
+
6. Copy the Business Account ID.
|
|
16
|
+
7. Login to your [Meta Business Manager](https://business.facebook.com/).
|
|
17
|
+
8. Click on Settings.
|
|
18
|
+
9. Create a new System User with access over the app and copy the access token.
|
|
19
|
+
`;
|
|
20
|
+
|
|
21
|
+
export const whatsapp = createPiece({
|
|
22
|
+
displayName: 'WhatsApp Business',
|
|
23
|
+
description: 'Manage your WhatsApp business account',
|
|
24
|
+
auth: whatsappAuth,
|
|
25
|
+
minimumSupportedRelease: '0.30.0',
|
|
26
|
+
logoUrl: 'https://cdn.activepieces.com/pieces/whatsapp.png',
|
|
27
|
+
authors: ['LevwTech', 'kishanprmr'],
|
|
28
|
+
actions: [sendMessage, sendMedia, sendTemplateMessageAction],
|
|
29
|
+
triggers: [],
|
|
30
|
+
});
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { whatsappAuth } from '../auth';
|
|
2
|
+
import { AuthenticationType, httpClient, HttpMethod } from '@agnocon/pieces-common';
|
|
3
|
+
import { createAction, Property } from '@agnocon/pieces-framework';
|
|
4
|
+
import { commonProps } from '../common/utils';
|
|
5
|
+
|
|
6
|
+
export const sendTemplateMessageAction = createAction({
|
|
7
|
+
auth: whatsappAuth,
|
|
8
|
+
name: 'send-template-message',
|
|
9
|
+
displayName: 'Send Template Message',
|
|
10
|
+
description: 'Sends a template message.',
|
|
11
|
+
audience: 'both',
|
|
12
|
+
aiMetadata: { description: 'Sends a pre-approved WhatsApp message template to a recipient, filling its header, body, and button placeholders from the supplied fields. Choose this to initiate conversations outside the 24-hour customer service window or for notifications/marketing where a registered template is required; the template must already be approved in the WhatsApp Business account. Requires the sender phone number ID, recipient phone number, and the template ID (its name and language are resolved automatically). Not idempotent — each call delivers a new message.', idempotent: false },
|
|
13
|
+
props: {
|
|
14
|
+
phone_number_id: commonProps.phone_number_id,
|
|
15
|
+
to: Property.ShortText({
|
|
16
|
+
displayName: 'To',
|
|
17
|
+
description: 'Recipient phone number.',
|
|
18
|
+
required: true,
|
|
19
|
+
}),
|
|
20
|
+
message_template_id: commonProps.message_template_id,
|
|
21
|
+
message_template_fields: commonProps.message_template_fields,
|
|
22
|
+
},
|
|
23
|
+
async run(context) {
|
|
24
|
+
const phoneNumberId = context.propsValue.phone_number_id as string;
|
|
25
|
+
const recipientPhoneNumber = context.propsValue.to as string;
|
|
26
|
+
const templateId = context.propsValue.message_template_id as string;
|
|
27
|
+
const templateFields = context.propsValue.message_template_fields;
|
|
28
|
+
|
|
29
|
+
// construct components object
|
|
30
|
+
// https://developers.facebook.com/docs/whatsapp/cloud-api/reference/messages#components-object
|
|
31
|
+
const components = [];
|
|
32
|
+
const headerParameters = [];
|
|
33
|
+
const bodyParameters = [];
|
|
34
|
+
const buttonParameters = [];
|
|
35
|
+
|
|
36
|
+
for (const [key, value] of Object.entries(templateFields)) {
|
|
37
|
+
if (key.startsWith('header_')) {
|
|
38
|
+
headerParameters.push({ type: 'text', text: value });
|
|
39
|
+
} else if (key.startsWith('body_')) {
|
|
40
|
+
bodyParameters.push({ type: 'text', text: value });
|
|
41
|
+
} else if (key.startsWith('button_')) {
|
|
42
|
+
buttonParameters.push({ type: 'text', text: value });
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (headerParameters.length) {
|
|
47
|
+
components.push({
|
|
48
|
+
type: 'header',
|
|
49
|
+
parameters: headerParameters,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
if (bodyParameters.length) {
|
|
53
|
+
components.push({
|
|
54
|
+
type: 'body',
|
|
55
|
+
parameters: bodyParameters,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
if (buttonParameters.length) {
|
|
59
|
+
components.push({
|
|
60
|
+
type: 'button',
|
|
61
|
+
sub_type: 'url',
|
|
62
|
+
index: 0,
|
|
63
|
+
parameters: buttonParameters,
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// fetch template language code
|
|
68
|
+
const templateData = await httpClient.sendRequest({
|
|
69
|
+
method: HttpMethod.GET,
|
|
70
|
+
url: `https://graph.facebook.com/v20.0/${templateId}`,
|
|
71
|
+
authentication: {
|
|
72
|
+
type: AuthenticationType.BEARER_TOKEN,
|
|
73
|
+
token: context.auth.props.access_token,
|
|
74
|
+
},
|
|
75
|
+
queryParams: {
|
|
76
|
+
fields: 'id,name,language',
|
|
77
|
+
},
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
const templateLanguage = templateData.body['language'];
|
|
81
|
+
const templateName = templateData.body['name'];
|
|
82
|
+
|
|
83
|
+
// https://developers.facebook.com/docs/whatsapp/cloud-api/guides/send-message-templates/#text-based
|
|
84
|
+
const response = await httpClient.sendRequest({
|
|
85
|
+
method: HttpMethod.POST,
|
|
86
|
+
url: `https://graph.facebook.com/v20.0/${phoneNumberId}/messages`,
|
|
87
|
+
authentication: {
|
|
88
|
+
type: AuthenticationType.BEARER_TOKEN,
|
|
89
|
+
token: context.auth.props.access_token,
|
|
90
|
+
},
|
|
91
|
+
body: {
|
|
92
|
+
messaging_product: 'whatsapp',
|
|
93
|
+
recipient_type: 'individual',
|
|
94
|
+
to: recipientPhoneNumber,
|
|
95
|
+
type: 'template',
|
|
96
|
+
template: {
|
|
97
|
+
name: templateName,
|
|
98
|
+
language: {
|
|
99
|
+
code: templateLanguage,
|
|
100
|
+
},
|
|
101
|
+
components,
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
return response.body;
|
|
107
|
+
},
|
|
108
|
+
});
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { createAction, Property } from '@agnocon/pieces-framework';
|
|
2
|
+
import { httpClient, HttpMethod } from '@agnocon/pieces-common';
|
|
3
|
+
import { whatsappAuth } from '../auth';
|
|
4
|
+
import {
|
|
5
|
+
supportedMediaTypes,
|
|
6
|
+
capitalizeFirstLetter,
|
|
7
|
+
mediaTypeSupportsCaption,
|
|
8
|
+
commonProps,
|
|
9
|
+
} from '../common/utils';
|
|
10
|
+
|
|
11
|
+
export const sendMedia = createAction({
|
|
12
|
+
auth: whatsappAuth,
|
|
13
|
+
name: 'sendMedia',
|
|
14
|
+
displayName: 'Send Media',
|
|
15
|
+
description: 'Send a media message through WhatsApp',
|
|
16
|
+
audience: 'both',
|
|
17
|
+
aiMetadata: { description: 'Sends an image, video, audio, document, or sticker to a WhatsApp recipient by referencing the media via a public URL. Choose this when the message payload is a file rather than plain text; captions are supported for media types that allow them and a filename can be set for documents. Requires the sender phone number ID, recipient phone number, media type, and a reachable media URL; subject to WhatsApp messaging-window rules. Not idempotent — each call delivers a new message.', idempotent: false },
|
|
18
|
+
props: {
|
|
19
|
+
phone_number_id: commonProps.phone_number_id,
|
|
20
|
+
to: Property.ShortText({
|
|
21
|
+
displayName: 'To',
|
|
22
|
+
description: 'The recipient of the message',
|
|
23
|
+
required: true,
|
|
24
|
+
}),
|
|
25
|
+
type: Property.Dropdown({
|
|
26
|
+
auth: whatsappAuth,
|
|
27
|
+
displayName: 'Type',
|
|
28
|
+
description: 'The type of media to send',
|
|
29
|
+
required: true,
|
|
30
|
+
options: async () => {
|
|
31
|
+
return {
|
|
32
|
+
options: supportedMediaTypes.map((type) => ({
|
|
33
|
+
label: capitalizeFirstLetter(type),
|
|
34
|
+
value: type,
|
|
35
|
+
})),
|
|
36
|
+
};
|
|
37
|
+
},
|
|
38
|
+
refreshers: [],
|
|
39
|
+
}),
|
|
40
|
+
media: Property.ShortText({
|
|
41
|
+
displayName: 'Media URL',
|
|
42
|
+
description: 'The URL of the media to send',
|
|
43
|
+
required: true,
|
|
44
|
+
}),
|
|
45
|
+
caption: Property.LongText({
|
|
46
|
+
displayName: 'Caption',
|
|
47
|
+
description: 'A caption for the media',
|
|
48
|
+
required: false,
|
|
49
|
+
}),
|
|
50
|
+
filename: Property.LongText({
|
|
51
|
+
displayName: 'Filename',
|
|
52
|
+
description: 'Filename of the document to send',
|
|
53
|
+
required: false,
|
|
54
|
+
}),
|
|
55
|
+
},
|
|
56
|
+
async run(context) {
|
|
57
|
+
const { to, caption, media, type, filename, phone_number_id } = context.propsValue;
|
|
58
|
+
const { access_token } = context.auth.props;
|
|
59
|
+
const body = {
|
|
60
|
+
messaging_product: 'whatsapp',
|
|
61
|
+
recipient_type: 'individual',
|
|
62
|
+
to,
|
|
63
|
+
type,
|
|
64
|
+
[type]: {
|
|
65
|
+
link: media,
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
if (caption && mediaTypeSupportsCaption(type)) (body[type] as any).caption = caption;
|
|
69
|
+
if (filename && type === 'document') (body[type] as any).filename = filename;
|
|
70
|
+
return await httpClient.sendRequest({
|
|
71
|
+
method: HttpMethod.POST,
|
|
72
|
+
url: `https://graph.facebook.com/v17.0/${phone_number_id}/messages`,
|
|
73
|
+
headers: {
|
|
74
|
+
Authorization: 'Bearer ' + access_token,
|
|
75
|
+
},
|
|
76
|
+
body,
|
|
77
|
+
});
|
|
78
|
+
},
|
|
79
|
+
});
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { createAction, Property } from '@agnocon/pieces-framework';
|
|
2
|
+
import { httpClient, HttpMethod } from '@agnocon/pieces-common';
|
|
3
|
+
import { whatsappAuth } from '../auth';
|
|
4
|
+
import { commonProps } from '../common/utils';
|
|
5
|
+
|
|
6
|
+
export const sendMessage = createAction({
|
|
7
|
+
auth: whatsappAuth,
|
|
8
|
+
name: 'sendMessage',
|
|
9
|
+
displayName: 'Send Message',
|
|
10
|
+
description: 'Send a text message through WhatsApp',
|
|
11
|
+
audience: 'both',
|
|
12
|
+
aiMetadata: { description: 'Sends a plain text WhatsApp message from a business phone number to a single recipient via the WhatsApp Cloud API. Choose this for free-form text replies or notifications when no media or pre-approved template is needed; for media use Send Media and for marketing/utility templates use Send Template Message. Requires the sender phone number ID and the recipient phone number in international format; outside the 24-hour customer service window only template messages are deliverable. Not idempotent — each call delivers a new message.', idempotent: false },
|
|
13
|
+
props: {
|
|
14
|
+
phone_number_id: commonProps.phone_number_id,
|
|
15
|
+
to: Property.ShortText({
|
|
16
|
+
displayName: 'To',
|
|
17
|
+
description: 'The recipient of the message',
|
|
18
|
+
required: true,
|
|
19
|
+
}),
|
|
20
|
+
text: Property.LongText({
|
|
21
|
+
displayName: 'Message',
|
|
22
|
+
description: 'The message to send',
|
|
23
|
+
required: true,
|
|
24
|
+
}),
|
|
25
|
+
},
|
|
26
|
+
async run(context) {
|
|
27
|
+
const { to, text, phone_number_id } = context.propsValue;
|
|
28
|
+
const { access_token } = context.auth.props;
|
|
29
|
+
return await httpClient.sendRequest({
|
|
30
|
+
method: HttpMethod.POST,
|
|
31
|
+
url: `https://graph.facebook.com/v17.0/${phone_number_id}/messages`,
|
|
32
|
+
headers: {
|
|
33
|
+
Authorization: 'Bearer ' + access_token,
|
|
34
|
+
},
|
|
35
|
+
body: {
|
|
36
|
+
messaging_product: 'whatsapp',
|
|
37
|
+
recipient_type: 'individual',
|
|
38
|
+
to,
|
|
39
|
+
type: 'text',
|
|
40
|
+
text: {
|
|
41
|
+
body: text,
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
},
|
|
46
|
+
});
|
package/src/lib/auth.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { PieceAuth, Property } from '@agnocon/pieces-framework';
|
|
2
|
+
|
|
3
|
+
const markdown = `
|
|
4
|
+
To Obtain a Phone Number ID and a Permanent System User Access Token, follow these steps:
|
|
5
|
+
|
|
6
|
+
1. Go to https://developers.facebook.com/
|
|
7
|
+
2. Make a new app, Select Other for usecase.
|
|
8
|
+
3. Choose Business as the type of app.
|
|
9
|
+
4. Add new Product -> WhatsApp.
|
|
10
|
+
5. Navigate to WhatsApp Settings > API Setup.
|
|
11
|
+
6. Copy the Business Account ID.
|
|
12
|
+
7. Login to your [Meta Business Manager](https://business.facebook.com/).
|
|
13
|
+
8. Click on Settings.
|
|
14
|
+
9. Create a new System User with access over the app and copy the access token.
|
|
15
|
+
`;
|
|
16
|
+
|
|
17
|
+
export const whatsappAuth = PieceAuth.CustomAuth({
|
|
18
|
+
required: true,
|
|
19
|
+
description: markdown,
|
|
20
|
+
props: {
|
|
21
|
+
access_token: PieceAuth.SecretText({
|
|
22
|
+
displayName: 'System User Access Token',
|
|
23
|
+
description: 'The system user access token of your WhatsApp business account.',
|
|
24
|
+
required: true,
|
|
25
|
+
}),
|
|
26
|
+
businessAccountId: Property.ShortText({
|
|
27
|
+
displayName: 'Business Account ID',
|
|
28
|
+
description: 'The business account ID of your WhatsApp business account.',
|
|
29
|
+
required: true,
|
|
30
|
+
}),
|
|
31
|
+
},
|
|
32
|
+
});
|