@memberjunction/communication-twilio 3.4.0 → 4.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/README.md +166 -209
- package/dist/TwilioProvider.d.ts +97 -0
- package/dist/TwilioProvider.d.ts.map +1 -0
- package/dist/TwilioProvider.js +120 -56
- package/dist/TwilioProvider.js.map +1 -1
- package/dist/config.d.ts +6 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +13 -34
- package/dist/config.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -18
- package/dist/index.js.map +1 -1
- package/package.json +10 -9
package/README.md
CHANGED
|
@@ -1,18 +1,42 @@
|
|
|
1
1
|
# @memberjunction/communication-twilio
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
##
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
3
|
+
Twilio provider for the MemberJunction Communication Framework. This provider enables messaging across multiple channels -- SMS, WhatsApp Business, and Facebook Messenger -- through the Twilio API. The channel is automatically detected based on recipient format.
|
|
4
|
+
|
|
5
|
+
## Architecture
|
|
6
|
+
|
|
7
|
+
```mermaid
|
|
8
|
+
graph TD
|
|
9
|
+
subgraph twilio["@memberjunction/communication-twilio"]
|
|
10
|
+
TP["TwilioProvider"]
|
|
11
|
+
CFG["Config Module\n(Environment Variables)"]
|
|
12
|
+
CRED["TwilioCredentials"]
|
|
13
|
+
DETECT["Channel Detection\n(SMS / WhatsApp / Messenger)"]
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
subgraph tw["Twilio Service"]
|
|
17
|
+
API["Twilio REST API"]
|
|
18
|
+
SMS["SMS / MMS"]
|
|
19
|
+
WA["WhatsApp Business"]
|
|
20
|
+
FB["Facebook Messenger"]
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
subgraph base["@memberjunction/communication-types"]
|
|
24
|
+
BCP["BaseCommunicationProvider"]
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
BCP --> TP
|
|
28
|
+
TP --> CFG
|
|
29
|
+
TP --> CRED
|
|
30
|
+
TP --> DETECT
|
|
31
|
+
TP --> API
|
|
32
|
+
API --> SMS
|
|
33
|
+
API --> WA
|
|
34
|
+
API --> FB
|
|
35
|
+
|
|
36
|
+
style twilio fill:#2d6a9f,stroke:#1a4971,color:#fff
|
|
37
|
+
style tw fill:#7c5295,stroke:#563a6b,color:#fff
|
|
38
|
+
style base fill:#2d8659,stroke:#1a5c3a,color:#fff
|
|
39
|
+
```
|
|
16
40
|
|
|
17
41
|
## Installation
|
|
18
42
|
|
|
@@ -22,260 +46,193 @@ npm install @memberjunction/communication-twilio
|
|
|
22
46
|
|
|
23
47
|
## Configuration
|
|
24
48
|
|
|
25
|
-
|
|
49
|
+
Set the following environment variables:
|
|
26
50
|
|
|
27
51
|
```env
|
|
28
|
-
# Required
|
|
29
|
-
TWILIO_ACCOUNT_SID=
|
|
30
|
-
TWILIO_AUTH_TOKEN=
|
|
52
|
+
# Required
|
|
53
|
+
TWILIO_ACCOUNT_SID=your-account-sid
|
|
54
|
+
TWILIO_AUTH_TOKEN=your-auth-token
|
|
31
55
|
TWILIO_PHONE_NUMBER=+1234567890
|
|
32
56
|
|
|
33
|
-
# Optional
|
|
57
|
+
# Optional (for additional channels)
|
|
34
58
|
TWILIO_WHATSAPP_NUMBER=+1234567890
|
|
35
|
-
|
|
36
|
-
# Optional - For Facebook Messenger
|
|
37
|
-
TWILIO_FACEBOOK_PAGE_ID=your_page_id
|
|
59
|
+
TWILIO_FACEBOOK_PAGE_ID=your-page-id
|
|
38
60
|
```
|
|
39
61
|
|
|
40
|
-
|
|
62
|
+
## Channel Detection
|
|
63
|
+
|
|
64
|
+
The provider automatically selects the messaging channel based on the recipient format:
|
|
41
65
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
| `TWILIO_FACEBOOK_PAGE_ID` | No | Your Facebook Page ID for Messenger |
|
|
66
|
+
```mermaid
|
|
67
|
+
flowchart LR
|
|
68
|
+
TO["Recipient Address"] --> CHECK{"Prefix?"}
|
|
69
|
+
CHECK -->|"whatsapp:+1..."| WA["WhatsApp Channel"]
|
|
70
|
+
CHECK -->|"messenger:psid"| FB["Messenger Channel"]
|
|
71
|
+
CHECK -->|"+1234567890"| SMS["SMS Channel"]
|
|
49
72
|
|
|
50
|
-
|
|
73
|
+
style TO fill:#2d6a9f,stroke:#1a4971,color:#fff
|
|
74
|
+
style WA fill:#2d8659,stroke:#1a5c3a,color:#fff
|
|
75
|
+
style FB fill:#7c5295,stroke:#563a6b,color:#fff
|
|
76
|
+
style SMS fill:#b8762f,stroke:#8a5722,color:#fff
|
|
77
|
+
```
|
|
51
78
|
|
|
52
|
-
|
|
79
|
+
| Recipient Format | Channel | From Number Config |
|
|
80
|
+
|-----------------|---------|-------------------|
|
|
81
|
+
| `+1234567890` | SMS | `TWILIO_PHONE_NUMBER` |
|
|
82
|
+
| `whatsapp:+1234567890` | WhatsApp | `TWILIO_WHATSAPP_NUMBER` |
|
|
83
|
+
| `messenger:user_psid` | Facebook Messenger | `TWILIO_FACEBOOK_PAGE_ID` |
|
|
53
84
|
|
|
54
|
-
|
|
55
|
-
import { TwilioProvider } from '@memberjunction/communication-twilio';
|
|
85
|
+
## Supported Operations
|
|
56
86
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
87
|
+
| Operation | Supported | Notes |
|
|
88
|
+
|-----------|-----------|-------|
|
|
89
|
+
| `SendSingleMessage` | Yes | Auto-detects channel, supports media URLs |
|
|
90
|
+
| `GetMessages` | Yes | Filter by from, to, dateSent |
|
|
91
|
+
| `ForwardMessage` | Yes | Reconstructs message body with forward prefix |
|
|
92
|
+
| `ReplyToMessage` | Yes | Fetches original, sends to original sender |
|
|
93
|
+
| `CreateDraft` | No | Messaging services have no draft concept |
|
|
94
|
+
| Extended operations | No | No folder, search, or attachment operations |
|
|
95
|
+
|
|
96
|
+
## Usage
|
|
61
97
|
|
|
62
|
-
### Sending
|
|
98
|
+
### Sending SMS
|
|
63
99
|
|
|
64
|
-
#### SMS Message
|
|
65
100
|
```typescript
|
|
66
|
-
import {
|
|
101
|
+
import { CommunicationEngine } from '@memberjunction/communication-engine';
|
|
102
|
+
import { Message } from '@memberjunction/communication-types';
|
|
67
103
|
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
ProcessedBody: 'Hello from MemberJunction!',
|
|
71
|
-
// Other required fields...
|
|
72
|
-
};
|
|
104
|
+
const engine = CommunicationEngine.Instance;
|
|
105
|
+
await engine.Config(false, contextUser);
|
|
73
106
|
|
|
74
|
-
const
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
}
|
|
107
|
+
const message = new Message();
|
|
108
|
+
message.To = '+1234567890';
|
|
109
|
+
message.Body = 'Hello from MemberJunction!';
|
|
110
|
+
|
|
111
|
+
const result = await engine.SendSingleMessage('Twilio', 'Standard SMS', message);
|
|
80
112
|
```
|
|
81
113
|
|
|
82
|
-
|
|
114
|
+
### Sending WhatsApp Message
|
|
115
|
+
|
|
83
116
|
```typescript
|
|
84
|
-
const
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
// Other required fields...
|
|
88
|
-
};
|
|
117
|
+
const message = new Message();
|
|
118
|
+
message.To = 'whatsapp:+1234567890';
|
|
119
|
+
message.Body = 'Hello via WhatsApp!';
|
|
89
120
|
|
|
90
|
-
const result = await
|
|
121
|
+
const result = await engine.SendSingleMessage('Twilio', 'Standard SMS', message);
|
|
91
122
|
```
|
|
92
123
|
|
|
93
|
-
|
|
124
|
+
### Sending Facebook Messenger Message
|
|
125
|
+
|
|
94
126
|
```typescript
|
|
95
|
-
const
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
// Other required fields...
|
|
99
|
-
};
|
|
127
|
+
const message = new Message();
|
|
128
|
+
message.To = 'messenger:user_psid';
|
|
129
|
+
message.Body = 'Hello via Messenger!';
|
|
100
130
|
|
|
101
|
-
const result = await
|
|
131
|
+
const result = await engine.SendSingleMessage('Twilio', 'Standard SMS', message);
|
|
102
132
|
```
|
|
103
133
|
|
|
104
|
-
|
|
134
|
+
### Sending Media (MMS / WhatsApp)
|
|
135
|
+
|
|
105
136
|
```typescript
|
|
106
|
-
const
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
137
|
+
const message = new Message();
|
|
138
|
+
message.To = '+1234567890';
|
|
139
|
+
message.Body = 'Check out this image!';
|
|
140
|
+
message.ContextData = {
|
|
110
141
|
mediaUrls: ['https://example.com/image.jpg']
|
|
111
|
-
},
|
|
112
|
-
// Other required fields...
|
|
113
142
|
};
|
|
114
143
|
|
|
115
|
-
const result = await
|
|
144
|
+
const result = await engine.SendSingleMessage('Twilio', 'Standard SMS', message);
|
|
116
145
|
```
|
|
117
146
|
|
|
118
147
|
### Retrieving Messages
|
|
119
148
|
|
|
120
149
|
```typescript
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
const
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
console.log(`Retrieved ${result.Messages.length} messages`);
|
|
136
|
-
result.Messages.forEach(msg => {
|
|
137
|
-
console.log(`From: ${msg.From}, Body: ${msg.Body}`);
|
|
138
|
-
});
|
|
139
|
-
}
|
|
150
|
+
const provider = engine.GetProvider('Twilio');
|
|
151
|
+
|
|
152
|
+
const result = await provider.GetMessages({
|
|
153
|
+
NumMessages: 50,
|
|
154
|
+
ContextData: {
|
|
155
|
+
from: '+1234567890',
|
|
156
|
+
to: '+0987654321',
|
|
157
|
+
dateSent: new Date('2025-01-01')
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
result.Messages.forEach(msg => {
|
|
162
|
+
console.log(`${msg.From} -> ${msg.To}: ${msg.Body}`);
|
|
163
|
+
});
|
|
140
164
|
```
|
|
141
165
|
|
|
142
|
-
###
|
|
166
|
+
### Per-Request Credentials
|
|
143
167
|
|
|
144
168
|
```typescript
|
|
145
|
-
import {
|
|
146
|
-
|
|
147
|
-
const replyParams: ReplyToMessageParams = {
|
|
148
|
-
MessageID: 'original_message_sid', // The Twilio Message SID
|
|
149
|
-
Message: {
|
|
150
|
-
ProcessedBody: 'Thanks for your message!',
|
|
151
|
-
// Other message fields...
|
|
152
|
-
}
|
|
153
|
-
};
|
|
169
|
+
import { TwilioCredentials } from '@memberjunction/communication-twilio';
|
|
154
170
|
|
|
155
|
-
const result = await provider.
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
171
|
+
const result = await provider.SendSingleMessage(processedMessage, {
|
|
172
|
+
accountSid: 'customer-sid',
|
|
173
|
+
authToken: 'customer-token',
|
|
174
|
+
phoneNumber: '+1987654321'
|
|
175
|
+
} as TwilioCredentials);
|
|
159
176
|
```
|
|
160
177
|
|
|
161
|
-
###
|
|
178
|
+
### Replying to a Message
|
|
162
179
|
|
|
163
180
|
```typescript
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
ToRecipients: ['+1234567890', 'whatsapp:+0987654321'],
|
|
169
|
-
Message: 'FYI - forwarding this message' // Optional comment
|
|
170
|
-
};
|
|
171
|
-
|
|
172
|
-
const result = await provider.ForwardMessage(forwardParams);
|
|
173
|
-
if (result.Success) {
|
|
174
|
-
console.log('Message forwarded successfully');
|
|
175
|
-
}
|
|
181
|
+
const result = await provider.ReplyToMessage({
|
|
182
|
+
MessageID: 'original-twilio-message-sid',
|
|
183
|
+
Message: processedReply
|
|
184
|
+
});
|
|
176
185
|
```
|
|
177
186
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
The provider automatically detects the communication channel based on the recipient format:
|
|
181
|
-
|
|
182
|
-
- **SMS**: Standard phone number format (e.g., `+1234567890`)
|
|
183
|
-
- **WhatsApp**: Prefixed with `whatsapp:` (e.g., `whatsapp:+1234567890`)
|
|
184
|
-
- **Facebook Messenger**: Prefixed with `messenger:` (e.g., `messenger:user_psid`)
|
|
185
|
-
|
|
186
|
-
## API Reference
|
|
187
|
-
|
|
188
|
-
### TwilioProvider
|
|
189
|
-
|
|
190
|
-
The main provider class that implements the `BaseCommunicationProvider` interface.
|
|
191
|
-
|
|
192
|
-
#### Methods
|
|
193
|
-
|
|
194
|
-
##### `SendSingleMessage(message: ProcessedMessage): Promise<MessageResult>`
|
|
195
|
-
Sends a single message through the appropriate Twilio channel.
|
|
187
|
+
### Forwarding a Message
|
|
196
188
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
**Returns:** `MessageResult` with success status and any error information
|
|
205
|
-
|
|
206
|
-
##### `GetMessages(params: GetMessagesParams): Promise<GetMessagesResult>`
|
|
207
|
-
Retrieves messages from Twilio based on filter criteria.
|
|
208
|
-
|
|
209
|
-
**Parameters:**
|
|
210
|
-
- `params`: Message retrieval parameters
|
|
211
|
-
- `NumMessages`: Maximum number of messages to retrieve
|
|
212
|
-
- `ContextData`: Optional filters (from, to, dateSent)
|
|
213
|
-
|
|
214
|
-
**Returns:** `GetMessagesResult` with retrieved messages and status
|
|
189
|
+
```typescript
|
|
190
|
+
const result = await provider.ForwardMessage({
|
|
191
|
+
MessageID: 'message-sid-to-forward',
|
|
192
|
+
ToRecipients: ['+1234567890', 'whatsapp:+0987654321'],
|
|
193
|
+
Message: 'FYI - forwarding this message'
|
|
194
|
+
});
|
|
195
|
+
```
|
|
215
196
|
|
|
216
|
-
|
|
217
|
-
Sends a reply to a specific message.
|
|
197
|
+
## TwilioCredentials
|
|
218
198
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
199
|
+
```typescript
|
|
200
|
+
interface TwilioCredentials extends ProviderCredentialsBase {
|
|
201
|
+
accountSid?: string;
|
|
202
|
+
authToken?: string;
|
|
203
|
+
phoneNumber?: string;
|
|
204
|
+
whatsappNumber?: string;
|
|
205
|
+
facebookPageId?: string;
|
|
206
|
+
disableEnvironmentFallback?: boolean;
|
|
207
|
+
}
|
|
208
|
+
```
|
|
223
209
|
|
|
224
|
-
|
|
210
|
+
## Client Caching
|
|
225
211
|
|
|
226
|
-
|
|
227
|
-
Forwards a message to one or more recipients.
|
|
212
|
+
The provider caches Twilio client instances for performance. Environment credential clients are shared across all calls; per-request credential clients are cached by `accountSid`.
|
|
228
213
|
|
|
229
|
-
|
|
230
|
-
- `params`: Forward parameters
|
|
231
|
-
- `MessageID`: The Twilio SID of the message to forward
|
|
232
|
-
- `ToRecipients`: Array of recipient addresses
|
|
233
|
-
- `Message`: (Optional) Additional comment to include
|
|
214
|
+
## Important Notes
|
|
234
215
|
|
|
235
|
-
**
|
|
216
|
+
- SMS/messaging channels use **plain text only** -- HTML content is not supported
|
|
217
|
+
- Message threading is simulated using Twilio Message SIDs (Twilio has no native thread concept)
|
|
218
|
+
- Forwarding reconstructs the message content with a "Forwarded message" prefix
|
|
219
|
+
- Media attachments are supported through the `mediaUrls` context data property
|
|
220
|
+
- All operations are asynchronous via the Twilio REST API
|
|
236
221
|
|
|
237
222
|
## Dependencies
|
|
238
223
|
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
## Integration with MemberJunction
|
|
248
|
-
|
|
249
|
-
This provider is automatically registered with the MemberJunction framework using the `@RegisterClass` decorator. Once imported, it becomes available for use through the MemberJunction communication system.
|
|
224
|
+
| Package | Purpose |
|
|
225
|
+
|---------|---------|
|
|
226
|
+
| `@memberjunction/communication-types` | Base provider class and type definitions |
|
|
227
|
+
| `@memberjunction/core` | Logging utilities (LogError, LogStatus) |
|
|
228
|
+
| `@memberjunction/global` | RegisterClass decorator |
|
|
229
|
+
| `twilio` | Official Twilio SDK |
|
|
230
|
+
| `dotenv` | Environment variable loading |
|
|
231
|
+
| `env-var` | Environment variable validation |
|
|
250
232
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
## Build and Development
|
|
254
|
-
|
|
255
|
-
### Building the Package
|
|
256
|
-
```bash
|
|
257
|
-
npm run build
|
|
258
|
-
```
|
|
233
|
+
## Development
|
|
259
234
|
|
|
260
|
-
### Cleaning Build Artifacts
|
|
261
235
|
```bash
|
|
262
|
-
npm run
|
|
236
|
+
npm run build # Compile TypeScript
|
|
237
|
+
npm run clean # Remove dist directory
|
|
263
238
|
```
|
|
264
|
-
|
|
265
|
-
### TypeScript Configuration
|
|
266
|
-
The package uses TypeScript and compiles to ES2020 with CommonJS modules. Type definitions are included in the distribution.
|
|
267
|
-
|
|
268
|
-
## Notes
|
|
269
|
-
|
|
270
|
-
- The provider uses plain text for message bodies as HTML is not supported by SMS/messaging channels
|
|
271
|
-
- Message threading is simulated using Message SIDs as Twilio doesn't have a native thread concept
|
|
272
|
-
- Media attachments are supported through the `mediaUrls` context data property
|
|
273
|
-
- All messages are sent asynchronously using the Twilio REST API
|
|
274
|
-
|
|
275
|
-
## Error Handling
|
|
276
|
-
|
|
277
|
-
The provider includes comprehensive error handling with detailed logging through the MemberJunction logging system. All errors are caught and returned in the result objects with descriptive error messages.
|
|
278
|
-
|
|
279
|
-
## License
|
|
280
|
-
|
|
281
|
-
This package is part of the MemberJunction framework. See the main repository for license information.
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { BaseCommunicationProvider, CreateDraftParams, CreateDraftResult, ForwardMessageParams, ForwardMessageResult, GetMessagesParams, GetMessagesResult, MessageResult, ProcessedMessage, ProviderCredentialsBase, ReplyToMessageParams, ReplyToMessageResult, ProviderOperation } from "@memberjunction/communication-types";
|
|
2
|
+
/**
|
|
3
|
+
* Credentials for Twilio provider.
|
|
4
|
+
* Extend ProviderCredentialsBase to support per-request credential override.
|
|
5
|
+
*
|
|
6
|
+
* @remarks
|
|
7
|
+
* **TEMPORARY INTERFACE**: This interface is part of the interim credential solution for 2.x patch release.
|
|
8
|
+
* In MemberJunction 3.0, this will be integrated with the comprehensive credential management system.
|
|
9
|
+
*/
|
|
10
|
+
export interface TwilioCredentials extends ProviderCredentialsBase {
|
|
11
|
+
/** Twilio Account SID */
|
|
12
|
+
accountSid?: string;
|
|
13
|
+
/** Twilio Auth Token */
|
|
14
|
+
authToken?: string;
|
|
15
|
+
/** Twilio Phone Number for SMS */
|
|
16
|
+
phoneNumber?: string;
|
|
17
|
+
/** Optional WhatsApp number (if using WhatsApp messaging) */
|
|
18
|
+
whatsappNumber?: string;
|
|
19
|
+
/** Optional Facebook Page ID (if using Facebook Messenger) */
|
|
20
|
+
facebookPageId?: string;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Implementation of the Twilio provider for sending and receiving messages (SMS, WhatsApp, Facebook Messenger)
|
|
24
|
+
*/
|
|
25
|
+
export declare class TwilioProvider extends BaseCommunicationProvider {
|
|
26
|
+
/** Cached Twilio client for environment credentials */
|
|
27
|
+
private envTwilioClient;
|
|
28
|
+
/** Cache of Twilio clients for per-request credentials */
|
|
29
|
+
private clientCache;
|
|
30
|
+
/**
|
|
31
|
+
* Returns the list of operations supported by the Twilio provider.
|
|
32
|
+
* Twilio is a messaging provider (SMS, WhatsApp, Messenger) and does not support
|
|
33
|
+
* mailbox operations like folders, archiving, or attachments.
|
|
34
|
+
*/
|
|
35
|
+
getSupportedOperations(): ProviderOperation[];
|
|
36
|
+
/**
|
|
37
|
+
* Resolves credentials by merging request credentials with environment fallback
|
|
38
|
+
*/
|
|
39
|
+
private resolveCredentials;
|
|
40
|
+
/**
|
|
41
|
+
* Gets a Twilio client for the given credentials, using caching for efficiency
|
|
42
|
+
*/
|
|
43
|
+
private getTwilioClient;
|
|
44
|
+
/**
|
|
45
|
+
* Determine the message channel type based on recipient format
|
|
46
|
+
*/
|
|
47
|
+
private getChannelType;
|
|
48
|
+
/**
|
|
49
|
+
* Format the sender number/ID based on channel type and credentials
|
|
50
|
+
*/
|
|
51
|
+
private formatFrom;
|
|
52
|
+
/**
|
|
53
|
+
* Format the recipient number/ID if needed
|
|
54
|
+
*/
|
|
55
|
+
private formatTo;
|
|
56
|
+
/**
|
|
57
|
+
* Sends a single message using Twilio
|
|
58
|
+
* @param message - The message to send
|
|
59
|
+
* @param credentials - Optional credentials override for this request.
|
|
60
|
+
* If not provided, uses environment variables.
|
|
61
|
+
* Set `credentials.disableEnvironmentFallback = true` to require explicit credentials.
|
|
62
|
+
*/
|
|
63
|
+
SendSingleMessage(message: ProcessedMessage, credentials?: TwilioCredentials): Promise<MessageResult>;
|
|
64
|
+
/**
|
|
65
|
+
* Gets messages from Twilio
|
|
66
|
+
* @param params - Parameters for fetching messages
|
|
67
|
+
* @param credentials - Optional credentials override for this request.
|
|
68
|
+
* If not provided, uses environment variables.
|
|
69
|
+
* Set `credentials.disableEnvironmentFallback = true` to require explicit credentials.
|
|
70
|
+
*/
|
|
71
|
+
GetMessages(params: GetMessagesParams, credentials?: TwilioCredentials): Promise<GetMessagesResult>;
|
|
72
|
+
/**
|
|
73
|
+
* Reply to a message using Twilio
|
|
74
|
+
* @param params - Parameters for replying to a message
|
|
75
|
+
* @param credentials - Optional credentials override for this request.
|
|
76
|
+
* If not provided, uses environment variables.
|
|
77
|
+
* Set `credentials.disableEnvironmentFallback = true` to require explicit credentials.
|
|
78
|
+
*/
|
|
79
|
+
ReplyToMessage(params: ReplyToMessageParams, credentials?: TwilioCredentials): Promise<ReplyToMessageResult>;
|
|
80
|
+
/**
|
|
81
|
+
* Forward a message using Twilio
|
|
82
|
+
* Note: Twilio doesn't have a native "forward" concept, so we implement it as a new message
|
|
83
|
+
* that includes the content of the original message
|
|
84
|
+
* @param params - Parameters for forwarding a message
|
|
85
|
+
* @param credentials - Optional credentials override for this request.
|
|
86
|
+
* If not provided, uses environment variables.
|
|
87
|
+
* Set `credentials.disableEnvironmentFallback = true` to require explicit credentials.
|
|
88
|
+
*/
|
|
89
|
+
ForwardMessage(params: ForwardMessageParams, credentials?: TwilioCredentials): Promise<ForwardMessageResult>;
|
|
90
|
+
/**
|
|
91
|
+
* Twilio does not support creating draft messages
|
|
92
|
+
* @param params - Parameters for creating a draft (not used)
|
|
93
|
+
* @param credentials - Optional credentials (not used for Twilio)
|
|
94
|
+
*/
|
|
95
|
+
CreateDraft(params: CreateDraftParams, credentials?: TwilioCredentials): Promise<CreateDraftResult>;
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=TwilioProvider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TwilioProvider.d.ts","sourceRoot":"","sources":["../src/TwilioProvider.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,yBAAyB,EACzB,iBAAiB,EACjB,iBAAiB,EACjB,oBAAoB,EACpB,oBAAoB,EACpB,iBAAiB,EACjB,iBAAiB,EACjB,aAAa,EACb,gBAAgB,EAChB,uBAAuB,EACvB,oBAAoB,EACpB,oBAAoB,EAGpB,iBAAiB,EAClB,MAAM,qCAAqC,CAAC;AAM7C;;;;;;;GAOG;AACH,MAAM,WAAW,iBAAkB,SAAQ,uBAAuB;IAChE,yBAAyB;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,wBAAwB;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kCAAkC;IAClC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,6DAA6D;IAC7D,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,8DAA8D;IAC9D,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAaD;;GAEG;AACH,qBACa,cAAe,SAAQ,yBAAyB;IAC3D,uDAAuD;IACvD,OAAO,CAAC,eAAe,CAAuB;IAE9C,0DAA0D;IAC1D,OAAO,CAAC,WAAW,CAAkC;IAErD;;;;OAIG;IACa,sBAAsB,IAAI,iBAAiB,EAAE;IAW7D;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAyB1B;;OAEG;IACH,OAAO,CAAC,eAAe;IAyBvB;;OAEG;IACH,OAAO,CAAC,cAAc;IAUtB;;OAEG;IACH,OAAO,CAAC,UAAU;IAYlB;;OAEG;IACH,OAAO,CAAC,QAAQ;IAkBhB;;;;;;OAMG;IACU,iBAAiB,CAC5B,OAAO,EAAE,gBAAgB,EACzB,WAAW,CAAC,EAAE,iBAAiB,GAC9B,OAAO,CAAC,aAAa,CAAC;IAgEzB;;;;;;OAMG;IACU,WAAW,CACtB,MAAM,EAAE,iBAAiB,EACzB,WAAW,CAAC,EAAE,iBAAiB,GAC9B,OAAO,CAAC,iBAAiB,CAAC;IAuD7B;;;;;;OAMG;IACU,cAAc,CACzB,MAAM,EAAE,oBAAoB,EAC5B,WAAW,CAAC,EAAE,iBAAiB,GAC9B,OAAO,CAAC,oBAAoB,CAAC;IAkEhC;;;;;;;;OAQG;IACU,cAAc,CACzB,MAAM,EAAE,oBAAoB,EAC5B,WAAW,CAAC,EAAE,iBAAiB,GAC9B,OAAO,CAAC,oBAAoB,CAAC;IA2DhC;;;;OAIG;IACU,WAAW,CACtB,MAAM,EAAE,iBAAiB,EACzB,WAAW,CAAC,EAAE,iBAAiB,GAC9B,OAAO,CAAC,iBAAiB,CAAC;CAM9B"}
|
package/dist/TwilioProvider.js
CHANGED
|
@@ -1,65 +1,52 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
1
|
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
19
2
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
20
3
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
21
4
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
22
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
23
6
|
};
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
};
|
|
34
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
35
|
-
exports.LoadProvider = exports.TwilioProvider = void 0;
|
|
36
|
-
const communication_types_1 = require("@memberjunction/communication-types");
|
|
37
|
-
const global_1 = require("@memberjunction/global");
|
|
38
|
-
const core_1 = require("@memberjunction/core");
|
|
39
|
-
const twilio_1 = __importDefault(require("twilio"));
|
|
40
|
-
const Config = __importStar(require("./config"));
|
|
41
|
-
let TwilioProvider = class TwilioProvider extends communication_types_1.BaseCommunicationProvider {
|
|
7
|
+
import { BaseCommunicationProvider, resolveCredentialValue, validateRequiredCredentials } from "@memberjunction/communication-types";
|
|
8
|
+
import { RegisterClass } from "@memberjunction/global";
|
|
9
|
+
import { LogError, LogStatus } from "@memberjunction/core";
|
|
10
|
+
import twilio from 'twilio';
|
|
11
|
+
import * as Config from "./config.js";
|
|
12
|
+
/**
|
|
13
|
+
* Implementation of the Twilio provider for sending and receiving messages (SMS, WhatsApp, Facebook Messenger)
|
|
14
|
+
*/
|
|
15
|
+
let TwilioProvider = class TwilioProvider extends BaseCommunicationProvider {
|
|
42
16
|
constructor() {
|
|
43
17
|
super(...arguments);
|
|
18
|
+
/** Cached Twilio client for environment credentials */
|
|
44
19
|
this.envTwilioClient = null;
|
|
20
|
+
/** Cache of Twilio clients for per-request credentials */
|
|
45
21
|
this.clientCache = new Map();
|
|
46
22
|
}
|
|
23
|
+
/**
|
|
24
|
+
* Returns the list of operations supported by the Twilio provider.
|
|
25
|
+
* Twilio is a messaging provider (SMS, WhatsApp, Messenger) and does not support
|
|
26
|
+
* mailbox operations like folders, archiving, or attachments.
|
|
27
|
+
*/
|
|
47
28
|
getSupportedOperations() {
|
|
48
29
|
return [
|
|
49
30
|
'SendSingleMessage',
|
|
50
31
|
'GetMessages',
|
|
51
32
|
'ForwardMessage',
|
|
52
33
|
'ReplyToMessage'
|
|
34
|
+
// Note: CreateDraft is NOT supported - Twilio is real-time messaging only
|
|
35
|
+
// Mailbox operations (folders, archive, attachments) are not applicable to SMS/messaging
|
|
53
36
|
];
|
|
54
37
|
}
|
|
38
|
+
/**
|
|
39
|
+
* Resolves credentials by merging request credentials with environment fallback
|
|
40
|
+
*/
|
|
55
41
|
resolveCredentials(credentials) {
|
|
56
42
|
const disableFallback = credentials?.disableEnvironmentFallback ?? false;
|
|
57
|
-
const accountSid =
|
|
58
|
-
const authToken =
|
|
59
|
-
const phoneNumber =
|
|
60
|
-
const whatsappNumber =
|
|
61
|
-
const facebookPageId =
|
|
62
|
-
|
|
43
|
+
const accountSid = resolveCredentialValue(credentials?.accountSid, Config.TWILIO_ACCOUNT_SID, disableFallback);
|
|
44
|
+
const authToken = resolveCredentialValue(credentials?.authToken, Config.TWILIO_AUTH_TOKEN, disableFallback);
|
|
45
|
+
const phoneNumber = resolveCredentialValue(credentials?.phoneNumber, Config.TWILIO_PHONE_NUMBER, disableFallback);
|
|
46
|
+
const whatsappNumber = resolveCredentialValue(credentials?.whatsappNumber, Config.TWILIO_WHATSAPP_NUMBER, disableFallback);
|
|
47
|
+
const facebookPageId = resolveCredentialValue(credentials?.facebookPageId, Config.TWILIO_FACEBOOK_PAGE_ID, disableFallback);
|
|
48
|
+
// Validate required credentials
|
|
49
|
+
validateRequiredCredentials({ accountSid, authToken, phoneNumber }, ['accountSid', 'authToken', 'phoneNumber'], 'Twilio');
|
|
63
50
|
return {
|
|
64
51
|
accountSid: accountSid,
|
|
65
52
|
authToken: authToken,
|
|
@@ -68,23 +55,31 @@ let TwilioProvider = class TwilioProvider extends communication_types_1.BaseComm
|
|
|
68
55
|
facebookPageId: facebookPageId || ''
|
|
69
56
|
};
|
|
70
57
|
}
|
|
58
|
+
/**
|
|
59
|
+
* Gets a Twilio client for the given credentials, using caching for efficiency
|
|
60
|
+
*/
|
|
71
61
|
getTwilioClient(creds) {
|
|
62
|
+
// Check if using environment credentials (can use shared client)
|
|
72
63
|
const isEnvCredentials = creds.accountSid === Config.TWILIO_ACCOUNT_SID &&
|
|
73
64
|
creds.authToken === Config.TWILIO_AUTH_TOKEN;
|
|
74
65
|
if (isEnvCredentials) {
|
|
75
66
|
if (!this.envTwilioClient) {
|
|
76
|
-
this.envTwilioClient = (
|
|
67
|
+
this.envTwilioClient = twilio(creds.accountSid, creds.authToken);
|
|
77
68
|
}
|
|
78
69
|
return this.envTwilioClient;
|
|
79
70
|
}
|
|
71
|
+
// For per-request credentials, use cached client by credential key
|
|
80
72
|
const cacheKey = `${creds.accountSid}`;
|
|
81
73
|
let client = this.clientCache.get(cacheKey);
|
|
82
74
|
if (!client) {
|
|
83
|
-
client = (
|
|
75
|
+
client = twilio(creds.accountSid, creds.authToken);
|
|
84
76
|
this.clientCache.set(cacheKey, client);
|
|
85
77
|
}
|
|
86
78
|
return client;
|
|
87
79
|
}
|
|
80
|
+
/**
|
|
81
|
+
* Determine the message channel type based on recipient format
|
|
82
|
+
*/
|
|
88
83
|
getChannelType(to) {
|
|
89
84
|
if (to.startsWith('whatsapp:')) {
|
|
90
85
|
return 'whatsapp';
|
|
@@ -96,6 +91,9 @@ let TwilioProvider = class TwilioProvider extends communication_types_1.BaseComm
|
|
|
96
91
|
return 'sms';
|
|
97
92
|
}
|
|
98
93
|
}
|
|
94
|
+
/**
|
|
95
|
+
* Format the sender number/ID based on channel type and credentials
|
|
96
|
+
*/
|
|
99
97
|
formatFrom(channelType, creds) {
|
|
100
98
|
switch (channelType) {
|
|
101
99
|
case 'whatsapp':
|
|
@@ -107,10 +105,15 @@ let TwilioProvider = class TwilioProvider extends communication_types_1.BaseComm
|
|
|
107
105
|
return creds.phoneNumber;
|
|
108
106
|
}
|
|
109
107
|
}
|
|
108
|
+
/**
|
|
109
|
+
* Format the recipient number/ID if needed
|
|
110
|
+
*/
|
|
110
111
|
formatTo(to, channelType) {
|
|
112
|
+
// If already formatted with prefix, return as is
|
|
111
113
|
if (to.startsWith('whatsapp:') || to.startsWith('messenger:')) {
|
|
112
114
|
return to;
|
|
113
115
|
}
|
|
116
|
+
// Format based on channel type
|
|
114
117
|
switch (channelType) {
|
|
115
118
|
case 'whatsapp':
|
|
116
119
|
return `whatsapp:${to}`;
|
|
@@ -121,6 +124,13 @@ let TwilioProvider = class TwilioProvider extends communication_types_1.BaseComm
|
|
|
121
124
|
return to;
|
|
122
125
|
}
|
|
123
126
|
}
|
|
127
|
+
/**
|
|
128
|
+
* Sends a single message using Twilio
|
|
129
|
+
* @param message - The message to send
|
|
130
|
+
* @param credentials - Optional credentials override for this request.
|
|
131
|
+
* If not provided, uses environment variables.
|
|
132
|
+
* Set `credentials.disableEnvironmentFallback = true` to require explicit credentials.
|
|
133
|
+
*/
|
|
124
134
|
async SendSingleMessage(message, credentials) {
|
|
125
135
|
try {
|
|
126
136
|
if (!message.To) {
|
|
@@ -130,11 +140,15 @@ let TwilioProvider = class TwilioProvider extends communication_types_1.BaseComm
|
|
|
130
140
|
Error: 'Recipient not specified'
|
|
131
141
|
};
|
|
132
142
|
}
|
|
143
|
+
// Resolve credentials (request credentials with env fallback)
|
|
133
144
|
const creds = this.resolveCredentials(credentials);
|
|
134
145
|
const twilioClient = this.getTwilioClient(creds);
|
|
146
|
+
// Determine channel type (SMS, WhatsApp, Messenger)
|
|
135
147
|
const channelType = this.getChannelType(message.To);
|
|
148
|
+
// Format sender and recipient
|
|
136
149
|
const from = message.From || this.formatFrom(channelType, creds);
|
|
137
150
|
const to = this.formatTo(message.To, channelType);
|
|
151
|
+
// Ensure from is configured for this channel
|
|
138
152
|
if (!from) {
|
|
139
153
|
return {
|
|
140
154
|
Message: message,
|
|
@@ -142,15 +156,20 @@ let TwilioProvider = class TwilioProvider extends communication_types_1.BaseComm
|
|
|
142
156
|
Error: `${channelType.toUpperCase()} sender not configured`
|
|
143
157
|
};
|
|
144
158
|
}
|
|
159
|
+
// Prepare message body
|
|
160
|
+
// For SMS and messaging channels, we use plain text
|
|
161
|
+
// HTML is not supported, so we use the text body
|
|
145
162
|
const body = message.ProcessedBody || '';
|
|
163
|
+
// Optional media URLs if specified in context data
|
|
146
164
|
const mediaUrls = message.ContextData?.mediaUrls || [];
|
|
165
|
+
// Send the message
|
|
147
166
|
const result = await twilioClient.messages.create({
|
|
148
167
|
body,
|
|
149
168
|
from,
|
|
150
169
|
to,
|
|
151
170
|
...(mediaUrls.length > 0 && { mediaUrl: mediaUrls })
|
|
152
171
|
});
|
|
153
|
-
|
|
172
|
+
LogStatus(`${channelType.toUpperCase()} message sent via Twilio (SID: ${result.sid})`);
|
|
154
173
|
return {
|
|
155
174
|
Message: message,
|
|
156
175
|
Success: true,
|
|
@@ -159,7 +178,7 @@ let TwilioProvider = class TwilioProvider extends communication_types_1.BaseComm
|
|
|
159
178
|
}
|
|
160
179
|
catch (error) {
|
|
161
180
|
const errorMessage = error instanceof Error ? error.message : 'Error sending message';
|
|
162
|
-
|
|
181
|
+
LogError('Error sending message via Twilio', undefined, error);
|
|
163
182
|
return {
|
|
164
183
|
Message: message,
|
|
165
184
|
Success: false,
|
|
@@ -167,29 +186,43 @@ let TwilioProvider = class TwilioProvider extends communication_types_1.BaseComm
|
|
|
167
186
|
};
|
|
168
187
|
}
|
|
169
188
|
}
|
|
189
|
+
/**
|
|
190
|
+
* Gets messages from Twilio
|
|
191
|
+
* @param params - Parameters for fetching messages
|
|
192
|
+
* @param credentials - Optional credentials override for this request.
|
|
193
|
+
* If not provided, uses environment variables.
|
|
194
|
+
* Set `credentials.disableEnvironmentFallback = true` to require explicit credentials.
|
|
195
|
+
*/
|
|
170
196
|
async GetMessages(params, credentials) {
|
|
171
197
|
try {
|
|
198
|
+
// Resolve credentials (request credentials with env fallback)
|
|
172
199
|
const creds = this.resolveCredentials(credentials);
|
|
173
200
|
const twilioClient = this.getTwilioClient(creds);
|
|
201
|
+
// Build query parameters
|
|
174
202
|
const queryParams = {
|
|
175
203
|
limit: params.NumMessages
|
|
176
204
|
};
|
|
205
|
+
// Filter by date sent
|
|
177
206
|
if (params.ContextData?.dateSent) {
|
|
178
207
|
queryParams.dateSent = params.ContextData.dateSent;
|
|
179
208
|
}
|
|
209
|
+
// Filter by sender
|
|
180
210
|
if (params.ContextData?.from) {
|
|
181
211
|
queryParams.from = params.ContextData.from;
|
|
182
212
|
}
|
|
213
|
+
// Filter by recipient
|
|
183
214
|
queryParams.to = params.Identifier || params.ContextData?.to || undefined;
|
|
215
|
+
// Fetch messages
|
|
184
216
|
const messages = await twilioClient.messages.list(queryParams);
|
|
217
|
+
// Format messages into standard structure
|
|
185
218
|
const formattedMessages = messages.map((message) => {
|
|
186
219
|
return {
|
|
187
220
|
From: message.from || '',
|
|
188
221
|
To: message.to || '',
|
|
189
222
|
Body: message.body || '',
|
|
190
223
|
ExternalSystemRecordID: message.sid,
|
|
191
|
-
Subject: '',
|
|
192
|
-
ThreadID: message.sid
|
|
224
|
+
Subject: '', // SMS doesn't have subject
|
|
225
|
+
ThreadID: message.sid // Using message SID as thread ID as Twilio doesn't have thread concept
|
|
193
226
|
};
|
|
194
227
|
});
|
|
195
228
|
return {
|
|
@@ -200,7 +233,7 @@ let TwilioProvider = class TwilioProvider extends communication_types_1.BaseComm
|
|
|
200
233
|
}
|
|
201
234
|
catch (error) {
|
|
202
235
|
const errorMessage = error instanceof Error ? error.message : 'Error fetching messages';
|
|
203
|
-
|
|
236
|
+
LogError('Error fetching messages from Twilio', undefined, error);
|
|
204
237
|
return {
|
|
205
238
|
Success: false,
|
|
206
239
|
Messages: [],
|
|
@@ -208,6 +241,13 @@ let TwilioProvider = class TwilioProvider extends communication_types_1.BaseComm
|
|
|
208
241
|
};
|
|
209
242
|
}
|
|
210
243
|
}
|
|
244
|
+
/**
|
|
245
|
+
* Reply to a message using Twilio
|
|
246
|
+
* @param params - Parameters for replying to a message
|
|
247
|
+
* @param credentials - Optional credentials override for this request.
|
|
248
|
+
* If not provided, uses environment variables.
|
|
249
|
+
* Set `credentials.disableEnvironmentFallback = true` to require explicit credentials.
|
|
250
|
+
*/
|
|
211
251
|
async ReplyToMessage(params, credentials) {
|
|
212
252
|
try {
|
|
213
253
|
if (!params.MessageID) {
|
|
@@ -216,8 +256,10 @@ let TwilioProvider = class TwilioProvider extends communication_types_1.BaseComm
|
|
|
216
256
|
ErrorMessage: 'Message ID not provided'
|
|
217
257
|
};
|
|
218
258
|
}
|
|
259
|
+
// Resolve credentials (request credentials with env fallback)
|
|
219
260
|
const creds = this.resolveCredentials(credentials);
|
|
220
261
|
const twilioClient = this.getTwilioClient(creds);
|
|
262
|
+
// Get original message to determine recipient and channel
|
|
221
263
|
const originalMessage = await twilioClient.messages(params.MessageID).fetch();
|
|
222
264
|
if (!originalMessage) {
|
|
223
265
|
return {
|
|
@@ -225,6 +267,7 @@ let TwilioProvider = class TwilioProvider extends communication_types_1.BaseComm
|
|
|
225
267
|
ErrorMessage: 'Original message not found'
|
|
226
268
|
};
|
|
227
269
|
}
|
|
270
|
+
// The recipient of our reply is the sender of the original message
|
|
228
271
|
const to = originalMessage.from || '';
|
|
229
272
|
if (!to) {
|
|
230
273
|
return {
|
|
@@ -232,10 +275,15 @@ let TwilioProvider = class TwilioProvider extends communication_types_1.BaseComm
|
|
|
232
275
|
ErrorMessage: 'Could not determine recipient for reply'
|
|
233
276
|
};
|
|
234
277
|
}
|
|
278
|
+
// Determine channel type
|
|
235
279
|
const channelType = this.getChannelType(to);
|
|
280
|
+
// Format sender
|
|
236
281
|
const from = params.Message.From || this.formatFrom(channelType, creds);
|
|
282
|
+
// Prepare message content
|
|
237
283
|
const body = params.Message.ProcessedBody || '';
|
|
284
|
+
// Optional media URLs
|
|
238
285
|
const mediaUrls = params.Message.ContextData?.mediaUrls || [];
|
|
286
|
+
// Send the reply
|
|
239
287
|
const result = await twilioClient.messages.create({
|
|
240
288
|
body,
|
|
241
289
|
from,
|
|
@@ -249,13 +297,22 @@ let TwilioProvider = class TwilioProvider extends communication_types_1.BaseComm
|
|
|
249
297
|
}
|
|
250
298
|
catch (error) {
|
|
251
299
|
const errorMessage = error instanceof Error ? error.message : 'Error replying to message';
|
|
252
|
-
|
|
300
|
+
LogError('Error replying to message via Twilio', undefined, error);
|
|
253
301
|
return {
|
|
254
302
|
Success: false,
|
|
255
303
|
ErrorMessage: errorMessage
|
|
256
304
|
};
|
|
257
305
|
}
|
|
258
306
|
}
|
|
307
|
+
/**
|
|
308
|
+
* Forward a message using Twilio
|
|
309
|
+
* Note: Twilio doesn't have a native "forward" concept, so we implement it as a new message
|
|
310
|
+
* that includes the content of the original message
|
|
311
|
+
* @param params - Parameters for forwarding a message
|
|
312
|
+
* @param credentials - Optional credentials override for this request.
|
|
313
|
+
* If not provided, uses environment variables.
|
|
314
|
+
* Set `credentials.disableEnvironmentFallback = true` to require explicit credentials.
|
|
315
|
+
*/
|
|
259
316
|
async ForwardMessage(params, credentials) {
|
|
260
317
|
try {
|
|
261
318
|
if (!params.MessageID || !params.ToRecipients || params.ToRecipients.length === 0) {
|
|
@@ -264,8 +321,10 @@ let TwilioProvider = class TwilioProvider extends communication_types_1.BaseComm
|
|
|
264
321
|
ErrorMessage: 'Message ID or recipients not provided'
|
|
265
322
|
};
|
|
266
323
|
}
|
|
324
|
+
// Resolve credentials (request credentials with env fallback)
|
|
267
325
|
const creds = this.resolveCredentials(credentials);
|
|
268
326
|
const twilioClient = this.getTwilioClient(creds);
|
|
327
|
+
// Get the original message
|
|
269
328
|
const originalMessage = await twilioClient.messages(params.MessageID).fetch();
|
|
270
329
|
if (!originalMessage) {
|
|
271
330
|
return {
|
|
@@ -273,11 +332,13 @@ let TwilioProvider = class TwilioProvider extends communication_types_1.BaseComm
|
|
|
273
332
|
ErrorMessage: 'Original message not found'
|
|
274
333
|
};
|
|
275
334
|
}
|
|
335
|
+
// Create forwarded message content
|
|
276
336
|
const forwardPrefix = 'Forwarded message:\n';
|
|
277
337
|
const originalSender = `From: ${originalMessage.from}\n`;
|
|
278
338
|
const originalContent = originalMessage.body || '';
|
|
279
339
|
const forwardComment = params.Message ? `${params.Message}\n\n` : '';
|
|
280
340
|
const body = `${forwardComment}${forwardPrefix}${originalSender}${originalContent}`;
|
|
341
|
+
// Send to all recipients
|
|
281
342
|
const results = await Promise.all(params.ToRecipients.map(async (recipient) => {
|
|
282
343
|
const channelType = this.getChannelType(recipient);
|
|
283
344
|
const from = this.formatFrom(channelType, creds);
|
|
@@ -286,6 +347,7 @@ let TwilioProvider = class TwilioProvider extends communication_types_1.BaseComm
|
|
|
286
347
|
body,
|
|
287
348
|
from,
|
|
288
349
|
to,
|
|
350
|
+
// If original had media, we can forward it
|
|
289
351
|
...(originalMessage.numMedia !== '0' && { mediaUrl: [originalMessage.uri] })
|
|
290
352
|
});
|
|
291
353
|
}));
|
|
@@ -296,13 +358,18 @@ let TwilioProvider = class TwilioProvider extends communication_types_1.BaseComm
|
|
|
296
358
|
}
|
|
297
359
|
catch (error) {
|
|
298
360
|
const errorMessage = error instanceof Error ? error.message : 'Error forwarding message';
|
|
299
|
-
|
|
361
|
+
LogError('Error forwarding message via Twilio', undefined, error);
|
|
300
362
|
return {
|
|
301
363
|
Success: false,
|
|
302
364
|
ErrorMessage: errorMessage
|
|
303
365
|
};
|
|
304
366
|
}
|
|
305
367
|
}
|
|
368
|
+
/**
|
|
369
|
+
* Twilio does not support creating draft messages
|
|
370
|
+
* @param params - Parameters for creating a draft (not used)
|
|
371
|
+
* @param credentials - Optional credentials (not used for Twilio)
|
|
372
|
+
*/
|
|
306
373
|
async CreateDraft(params, credentials) {
|
|
307
374
|
return {
|
|
308
375
|
Success: false,
|
|
@@ -310,11 +377,8 @@ let TwilioProvider = class TwilioProvider extends communication_types_1.BaseComm
|
|
|
310
377
|
};
|
|
311
378
|
}
|
|
312
379
|
};
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
(0, global_1.RegisterClass)(communication_types_1.BaseCommunicationProvider, 'Twilio')
|
|
380
|
+
TwilioProvider = __decorate([
|
|
381
|
+
RegisterClass(BaseCommunicationProvider, 'Twilio')
|
|
316
382
|
], TwilioProvider);
|
|
317
|
-
|
|
318
|
-
}
|
|
319
|
-
exports.LoadProvider = LoadProvider;
|
|
383
|
+
export { TwilioProvider };
|
|
320
384
|
//# sourceMappingURL=TwilioProvider.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TwilioProvider.js","sourceRoot":"","sources":["../src/TwilioProvider.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"TwilioProvider.js","sourceRoot":"","sources":["../src/TwilioProvider.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EACL,yBAAyB,EAYzB,sBAAsB,EACtB,2BAA2B,EAE5B,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,MAAkB,MAAM,QAAQ,CAAC;AACxC,OAAO,KAAK,MAAM,MAAM,UAAU,CAAC;AAkCnC;;GAEG;AAEI,IAAM,cAAc,GAApB,MAAM,cAAe,SAAQ,yBAAyB;IAAtD;;QACL,uDAAuD;QAC/C,oBAAe,GAAkB,IAAI,CAAC;QAE9C,0DAA0D;QAClD,gBAAW,GAAwB,IAAI,GAAG,EAAE,CAAC;IAuavD,CAAC;IAraC;;;;OAIG;IACa,sBAAsB;QACpC,OAAO;YACL,mBAAmB;YACnB,aAAa;YACb,gBAAgB;YAChB,gBAAgB;YAChB,0EAA0E;YAC1E,yFAAyF;SAC1F,CAAC;IACJ,CAAC;IAED;;OAEG;IACK,kBAAkB,CAAC,WAA+B;QACxD,MAAM,eAAe,GAAG,WAAW,EAAE,0BAA0B,IAAI,KAAK,CAAC;QAEzE,MAAM,UAAU,GAAG,sBAAsB,CAAC,WAAW,EAAE,UAAU,EAAE,MAAM,CAAC,kBAAkB,EAAE,eAAe,CAAC,CAAC;QAC/G,MAAM,SAAS,GAAG,sBAAsB,CAAC,WAAW,EAAE,SAAS,EAAE,MAAM,CAAC,iBAAiB,EAAE,eAAe,CAAC,CAAC;QAC5G,MAAM,WAAW,GAAG,sBAAsB,CAAC,WAAW,EAAE,WAAW,EAAE,MAAM,CAAC,mBAAmB,EAAE,eAAe,CAAC,CAAC;QAClH,MAAM,cAAc,GAAG,sBAAsB,CAAC,WAAW,EAAE,cAAc,EAAE,MAAM,CAAC,sBAAsB,EAAE,eAAe,CAAC,CAAC;QAC3H,MAAM,cAAc,GAAG,sBAAsB,CAAC,WAAW,EAAE,cAAc,EAAE,MAAM,CAAC,uBAAuB,EAAE,eAAe,CAAC,CAAC;QAE5H,gCAAgC;QAChC,2BAA2B,CACzB,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,EACtC,CAAC,YAAY,EAAE,WAAW,EAAE,aAAa,CAAC,EAC1C,QAAQ,CACT,CAAC;QAEF,OAAO;YACL,UAAU,EAAE,UAAW;YACvB,SAAS,EAAE,SAAU;YACrB,WAAW,EAAE,WAAY;YACzB,cAAc,EAAE,cAAc,IAAI,EAAE;YACpC,cAAc,EAAE,cAAc,IAAI,EAAE;SACrC,CAAC;IACJ,CAAC;IAED;;OAEG;IACK,eAAe,CAAC,KAAgC;QACtD,iEAAiE;QACjE,MAAM,gBAAgB,GACpB,KAAK,CAAC,UAAU,KAAK,MAAM,CAAC,kBAAkB;YAC9C,KAAK,CAAC,SAAS,KAAK,MAAM,CAAC,iBAAiB,CAAC;QAE/C,IAAI,gBAAgB,EAAE,CAAC;YACrB,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC;gBAC1B,IAAI,CAAC,eAAe,GAAG,MAAM,CAAC,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;YACnE,CAAC;YACD,OAAO,IAAI,CAAC,eAAe,CAAC;QAC9B,CAAC;QAED,mEAAmE;QACnE,MAAM,QAAQ,GAAG,GAAG,KAAK,CAAC,UAAU,EAAE,CAAC;QACvC,IAAI,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAE5C,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;YACnD,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QACzC,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;OAEG;IACK,cAAc,CAAC,EAAU;QAC/B,IAAI,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;YAC/B,OAAO,UAAU,CAAC;QACpB,CAAC;aAAM,IAAI,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;YACvC,OAAO,WAAW,CAAC;QACrB,CAAC;aAAM,CAAC;YACN,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED;;OAEG;IACK,UAAU,CAAC,WAA6C,EAAE,KAAgC;QAChG,QAAQ,WAAW,EAAE,CAAC;YACpB,KAAK,UAAU;gBACb,OAAO,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC,YAAY,KAAK,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACxE,KAAK,WAAW;gBACd,OAAO,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC,aAAa,KAAK,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACzE,KAAK,KAAK,CAAC;YACX;gBACE,OAAO,KAAK,CAAC,WAAW,CAAC;QAC7B,CAAC;IACH,CAAC;IAED;;OAEG;IACK,QAAQ,CAAC,EAAU,EAAE,WAA6C;QACxE,iDAAiD;QACjD,IAAI,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;YAC9D,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,+BAA+B;QAC/B,QAAQ,WAAW,EAAE,CAAC;YACpB,KAAK,UAAU;gBACb,OAAO,YAAY,EAAE,EAAE,CAAC;YAC1B,KAAK,WAAW;gBACd,OAAO,aAAa,EAAE,EAAE,CAAC;YAC3B,KAAK,KAAK,CAAC;YACX;gBACE,OAAO,EAAE,CAAC;QACd,CAAC;IACH,CAAC;IAED;;;;;;OAMG;IACI,KAAK,CAAC,iBAAiB,CAC5B,OAAyB,EACzB,WAA+B;QAE/B,IAAI,CAAC;YACH,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC;gBAChB,OAAO;oBACL,OAAO,EAAE,OAAO;oBAChB,OAAO,EAAE,KAAK;oBACd,KAAK,EAAE,yBAAyB;iBACjC,CAAC;YACJ,CAAC;YAED,8DAA8D;YAC9D,MAAM,KAAK,GAAG,IAAI,CAAC,kBAAkB,CAAC,WAAW,CAAC,CAAC;YACnD,MAAM,YAAY,GAAG,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;YAEjD,oDAAoD;YACpD,MAAM,WAAW,GAAG,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YAEpD,8BAA8B;YAC9B,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,IAAI,CAAC,UAAU,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;YACjE,MAAM,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,EAAE,WAAW,CAAC,CAAC;YAElD,6CAA6C;YAC7C,IAAI,CAAC,IAAI,EAAE,CAAC;gBACV,OAAO;oBACL,OAAO,EAAE,OAAO;oBAChB,OAAO,EAAE,KAAK;oBACd,KAAK,EAAE,GAAG,WAAW,CAAC,WAAW,EAAE,wBAAwB;iBAC5D,CAAC;YACJ,CAAC;YAED,uBAAuB;YACvB,oDAAoD;YACpD,iDAAiD;YACjD,MAAM,IAAI,GAAG,OAAO,CAAC,aAAa,IAAI,EAAE,CAAC;YAEzC,mDAAmD;YACnD,MAAM,SAAS,GAAG,OAAO,CAAC,WAAW,EAAE,SAAqB,IAAI,EAAE,CAAC;YAEnE,mBAAmB;YACnB,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,QAAQ,CAAC,MAAM,CAAC;gBAChD,IAAI;gBACJ,IAAI;gBACJ,EAAE;gBACF,GAAG,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;aACrD,CAAC,CAAC;YAEH,SAAS,CAAC,GAAG,WAAW,CAAC,WAAW,EAAE,kCAAkC,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC;YAEvF,OAAO;gBACL,OAAO,EAAE,OAAO;gBAChB,OAAO,EAAE,IAAI;gBACb,KAAK,EAAE,EAAE;aACV,CAAC;QACJ,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,MAAM,YAAY,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,uBAAuB,CAAC;YACtF,QAAQ,CAAC,kCAAkC,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;YAC/D,OAAO;gBACL,OAAO,EAAE,OAAO;gBAChB,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,YAAY;aACpB,CAAC;QACJ,CAAC;IACH,CAAC;IAED;;;;;;OAMG;IACI,KAAK,CAAC,WAAW,CACtB,MAAyB,EACzB,WAA+B;QAE/B,IAAI,CAAC;YACH,8DAA8D;YAC9D,MAAM,KAAK,GAAG,IAAI,CAAC,kBAAkB,CAAC,WAAW,CAAC,CAAC;YACnD,MAAM,YAAY,GAAG,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;YAEjD,yBAAyB;YACzB,MAAM,WAAW,GAA4B;gBAC3C,KAAK,EAAE,MAAM,CAAC,WAAW;aAC1B,CAAC;YAEF,sBAAsB;YACtB,IAAI,MAAM,CAAC,WAAW,EAAE,QAAQ,EAAE,CAAC;gBACjC,WAAW,CAAC,QAAQ,GAAG,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC;YACrD,CAAC;YAED,mBAAmB;YACnB,IAAI,MAAM,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC;gBAC7B,WAAW,CAAC,IAAI,GAAG,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC;YAC7C,CAAC;YAED,sBAAsB;YACtB,WAAW,CAAC,EAAE,GAAG,MAAM,CAAC,UAAU,IAAI,MAAM,CAAC,WAAW,EAAE,EAAE,IAAI,SAAS,CAAC;YAE1E,iBAAiB;YACjB,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YAE/D,0CAA0C;YAC1C,MAAM,iBAAiB,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE;gBACjD,OAAO;oBACL,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,EAAE;oBACxB,EAAE,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE;oBACpB,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,EAAE;oBACxB,sBAAsB,EAAE,OAAO,CAAC,GAAG;oBACnC,OAAO,EAAE,EAAE,EAAE,2BAA2B;oBACxC,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,uEAAuE;iBAC9F,CAAC;YACJ,CAAC,CAAC,CAAC;YAEH,OAAO;gBACL,OAAO,EAAE,IAAI;gBACb,QAAQ,EAAE,iBAAiB;gBAC3B,UAAU,EAAE,QAAQ;aACrB,CAAC;QACJ,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,MAAM,YAAY,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,yBAAyB,CAAC;YACxF,QAAQ,CAAC,qCAAqC,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;YAClE,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,QAAQ,EAAE,EAAE;gBACZ,YAAY,EAAE,YAAY;aAC3B,CAAC;QACJ,CAAC;IACH,CAAC;IAED;;;;;;OAMG;IACI,KAAK,CAAC,cAAc,CACzB,MAA4B,EAC5B,WAA+B;QAE/B,IAAI,CAAC;YACH,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;gBACtB,OAAO;oBACL,OAAO,EAAE,KAAK;oBACd,YAAY,EAAE,yBAAyB;iBACxC,CAAC;YACJ,CAAC;YAED,8DAA8D;YAC9D,MAAM,KAAK,GAAG,IAAI,CAAC,kBAAkB,CAAC,WAAW,CAAC,CAAC;YACnD,MAAM,YAAY,GAAG,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;YAEjD,0DAA0D;YAC1D,MAAM,eAAe,GAAG,MAAM,YAAY,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,CAAC;YAE9E,IAAI,CAAC,eAAe,EAAE,CAAC;gBACrB,OAAO;oBACL,OAAO,EAAE,KAAK;oBACd,YAAY,EAAE,4BAA4B;iBAC3C,CAAC;YACJ,CAAC;YAED,mEAAmE;YACnE,MAAM,EAAE,GAAG,eAAe,CAAC,IAAI,IAAI,EAAE,CAAC;YACtC,IAAI,CAAC,EAAE,EAAE,CAAC;gBACR,OAAO;oBACL,OAAO,EAAE,KAAK;oBACd,YAAY,EAAE,yCAAyC;iBACxD,CAAC;YACJ,CAAC;YAED,yBAAyB;YACzB,MAAM,WAAW,GAAG,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC;YAE5C,gBAAgB;YAChB,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,IAAI,IAAI,CAAC,UAAU,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;YAExE,0BAA0B;YAC1B,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,aAAa,IAAI,EAAE,CAAC;YAEhD,sBAAsB;YACtB,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,WAAW,EAAE,SAAqB,IAAI,EAAE,CAAC;YAE1E,iBAAiB;YACjB,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,QAAQ,CAAC,MAAM,CAAC;gBAChD,IAAI;gBACJ,IAAI;gBACJ,EAAE;gBACF,GAAG,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;aACrD,CAAC,CAAC;YAEH,OAAO;gBACL,OAAO,EAAE,IAAI;gBACb,MAAM,EAAE,MAAM;aACf,CAAC;QACJ,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,MAAM,YAAY,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,2BAA2B,CAAC;YAC1F,QAAQ,CAAC,sCAAsC,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;YACnE,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,YAAY,EAAE,YAAY;aAC3B,CAAC;QACJ,CAAC;IACH,CAAC;IAED;;;;;;;;OAQG;IACI,KAAK,CAAC,cAAc,CACzB,MAA4B,EAC5B,WAA+B;QAE/B,IAAI,CAAC;YACH,IAAI,CAAC,MAAM,CAAC,SAAS,IAAI,CAAC,MAAM,CAAC,YAAY,IAAI,MAAM,CAAC,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAClF,OAAO;oBACL,OAAO,EAAE,KAAK;oBACd,YAAY,EAAE,uCAAuC;iBACtD,CAAC;YACJ,CAAC;YAED,8DAA8D;YAC9D,MAAM,KAAK,GAAG,IAAI,CAAC,kBAAkB,CAAC,WAAW,CAAC,CAAC;YACnD,MAAM,YAAY,GAAG,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;YAEjD,2BAA2B;YAC3B,MAAM,eAAe,GAAG,MAAM,YAAY,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,CAAC;YAE9E,IAAI,CAAC,eAAe,EAAE,CAAC;gBACrB,OAAO;oBACL,OAAO,EAAE,KAAK;oBACd,YAAY,EAAE,4BAA4B;iBAC3C,CAAC;YACJ,CAAC;YAED,mCAAmC;YACnC,MAAM,aAAa,GAAG,sBAAsB,CAAC;YAC7C,MAAM,cAAc,GAAG,SAAS,eAAe,CAAC,IAAI,IAAI,CAAC;YACzD,MAAM,eAAe,GAAG,eAAe,CAAC,IAAI,IAAI,EAAE,CAAC;YACnD,MAAM,cAAc,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,OAAO,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;YACrE,MAAM,IAAI,GAAG,GAAG,cAAc,GAAG,aAAa,GAAG,cAAc,GAAG,eAAe,EAAE,CAAC;YAEpF,yBAAyB;YACzB,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE;gBAC5E,MAAM,WAAW,GAAG,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;gBACnD,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;gBACjD,MAAM,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;gBAEjD,OAAO,YAAY,CAAC,QAAQ,CAAC,MAAM,CAAC;oBAClC,IAAI;oBACJ,IAAI;oBACJ,EAAE;oBACF,2CAA2C;oBAC3C,GAAG,CAAC,eAAe,CAAC,QAAQ,KAAK,GAAG,IAAI,EAAE,QAAQ,EAAE,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC;iBAC7E,CAAC,CAAC;YACL,CAAC,CAAC,CAAC,CAAC;YAEJ,OAAO;gBACL,OAAO,EAAE,IAAI;gBACb,MAAM,EAAE,OAAO;aAChB,CAAC;QACJ,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,MAAM,YAAY,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,0BAA0B,CAAC;YACzF,QAAQ,CAAC,qCAAqC,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;YAClE,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,YAAY,EAAE,YAAY;aAC3B,CAAC;QACJ,CAAC;IACH,CAAC;IAED;;;;OAIG;IACI,KAAK,CAAC,WAAW,CACtB,MAAyB,EACzB,WAA+B;QAE/B,OAAO;YACL,OAAO,EAAE,KAAK;YACd,YAAY,EAAE,sIAAsI;SACrJ,CAAC;IACJ,CAAC;CACF,CAAA;AA5aY,cAAc;IAD1B,aAAa,CAAC,yBAAyB,EAAE,QAAQ,CAAC;GACtC,cAAc,CA4a1B"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare const TWILIO_ACCOUNT_SID: string;
|
|
2
|
+
export declare const TWILIO_AUTH_TOKEN: string;
|
|
3
|
+
export declare const TWILIO_PHONE_NUMBER: string;
|
|
4
|
+
export declare const TWILIO_WHATSAPP_NUMBER: string;
|
|
5
|
+
export declare const TWILIO_FACEBOOK_PAGE_ID: string;
|
|
6
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAQA,eAAO,MAAM,kBAAkB,QAAuD,CAAC;AACvF,eAAO,MAAM,iBAAiB,QAAsD,CAAC;AACrF,eAAO,MAAM,mBAAmB,QAAwD,CAAC;AAGzF,eAAO,MAAM,sBAAsB,QAA2D,CAAC;AAG/F,eAAO,MAAM,uBAAuB,QAA4D,CAAC"}
|
package/dist/config.js
CHANGED
|
@@ -1,35 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
-
if (mod && mod.__esModule) return mod;
|
|
20
|
-
var result = {};
|
|
21
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
-
__setModuleDefault(result, mod);
|
|
23
|
-
return result;
|
|
24
|
-
};
|
|
25
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
-
exports.TWILIO_FACEBOOK_PAGE_ID = exports.TWILIO_WHATSAPP_NUMBER = exports.TWILIO_PHONE_NUMBER = exports.TWILIO_AUTH_TOKEN = exports.TWILIO_ACCOUNT_SID = void 0;
|
|
27
|
-
const env = __importStar(require("env-var"));
|
|
28
|
-
const dotenv = __importStar(require("dotenv"));
|
|
29
|
-
dotenv.config();
|
|
30
|
-
exports.TWILIO_ACCOUNT_SID = env.get('TWILIO_ACCOUNT_SID').default('').asString();
|
|
31
|
-
exports.TWILIO_AUTH_TOKEN = env.get('TWILIO_AUTH_TOKEN').default('').asString();
|
|
32
|
-
exports.TWILIO_PHONE_NUMBER = env.get('TWILIO_PHONE_NUMBER').default('').asString();
|
|
33
|
-
exports.TWILIO_WHATSAPP_NUMBER = env.get('TWILIO_WHATSAPP_NUMBER').default('').asString();
|
|
34
|
-
exports.TWILIO_FACEBOOK_PAGE_ID = env.get('TWILIO_FACEBOOK_PAGE_ID').default('').asString();
|
|
1
|
+
import env from 'env-var';
|
|
2
|
+
import dotenv from 'dotenv';
|
|
3
|
+
// Load environment variables from .env file
|
|
4
|
+
dotenv.config({ quiet: true });
|
|
5
|
+
// Twilio credentials - now optional to support per-request credential override
|
|
6
|
+
// When not set, credentials must be provided via API
|
|
7
|
+
export const TWILIO_ACCOUNT_SID = env.get('TWILIO_ACCOUNT_SID').default('').asString();
|
|
8
|
+
export const TWILIO_AUTH_TOKEN = env.get('TWILIO_AUTH_TOKEN').default('').asString();
|
|
9
|
+
export const TWILIO_PHONE_NUMBER = env.get('TWILIO_PHONE_NUMBER').default('').asString();
|
|
10
|
+
// Optional WhatsApp number (if using WhatsApp messaging)
|
|
11
|
+
export const TWILIO_WHATSAPP_NUMBER = env.get('TWILIO_WHATSAPP_NUMBER').default('').asString();
|
|
12
|
+
// Optional Facebook Page ID (if using Facebook Messenger)
|
|
13
|
+
export const TWILIO_FACEBOOK_PAGE_ID = env.get('TWILIO_FACEBOOK_PAGE_ID').default('').asString();
|
|
35
14
|
//# sourceMappingURL=config.js.map
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,SAAS,CAAC;AAC1B,OAAO,MAAM,MAAM,QAAQ,CAAC;AAE5B,4CAA4C;AAC5C,MAAM,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;AAE/B,+EAA+E;AAC/E,qDAAqD;AACrD,MAAM,CAAC,MAAM,kBAAkB,GAAG,GAAG,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;AACvF,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;AACrF,MAAM,CAAC,MAAM,mBAAmB,GAAG,GAAG,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;AAEzF,yDAAyD;AACzD,MAAM,CAAC,MAAM,sBAAsB,GAAG,GAAG,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;AAE/F,0DAA0D;AAC1D,MAAM,CAAC,MAAM,uBAAuB,GAAG,GAAG,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,kBAAkB,CAAC;AACjC,cAAc,UAAU,CAAC;AAGzB,YAAY,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,19 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
-
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
-
};
|
|
16
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
__exportStar(require("./TwilioProvider"), exports);
|
|
18
|
-
__exportStar(require("./config"), exports);
|
|
1
|
+
// PUBLIC API SURFACE AREA
|
|
2
|
+
export * from './TwilioProvider.js';
|
|
3
|
+
export * from './config.js';
|
|
19
4
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,0BAA0B;AAC1B,cAAc,kBAAkB,CAAC;AACjC,cAAc,UAAU,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@memberjunction/communication-twilio",
|
|
3
|
-
"
|
|
3
|
+
"type": "module",
|
|
4
|
+
"version": "4.1.0",
|
|
4
5
|
"description": "Twilio provider for MemberJunction Communication framework",
|
|
5
6
|
"main": "dist/index.js",
|
|
6
7
|
"types": "dist/index.d.ts",
|
|
@@ -8,20 +9,20 @@
|
|
|
8
9
|
"dist/**/*"
|
|
9
10
|
],
|
|
10
11
|
"scripts": {
|
|
11
|
-
"build": "tsc",
|
|
12
|
+
"build": "tsc && tsc-alias -f",
|
|
12
13
|
"clean": "rimraf dist"
|
|
13
14
|
},
|
|
14
15
|
"dependencies": {
|
|
15
|
-
"@memberjunction/communication-types": "
|
|
16
|
-
"@memberjunction/core": "
|
|
17
|
-
"@memberjunction/global": "
|
|
18
|
-
"dotenv": "^
|
|
16
|
+
"@memberjunction/communication-types": "4.1.0",
|
|
17
|
+
"@memberjunction/core": "4.1.0",
|
|
18
|
+
"@memberjunction/global": "4.1.0",
|
|
19
|
+
"dotenv": "^17.2.4",
|
|
19
20
|
"env-var": "^7.4.1",
|
|
20
|
-
"twilio": "^
|
|
21
|
+
"twilio": "^5.12.1"
|
|
21
22
|
},
|
|
22
23
|
"devDependencies": {
|
|
23
|
-
"typescript": "^5.
|
|
24
|
-
"rimraf": "^
|
|
24
|
+
"typescript": "^5.9.3",
|
|
25
|
+
"rimraf": "^6.1.2"
|
|
25
26
|
},
|
|
26
27
|
"repository": {
|
|
27
28
|
"type": "git",
|