matimo-examples 0.1.0-alpha.11
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/.env.example +49 -0
- package/LICENSE +21 -0
- package/README.md +525 -0
- package/agents/decorator-pattern-agent.ts +368 -0
- package/agents/factory-pattern-agent.ts +253 -0
- package/agents/langchain-agent.ts +146 -0
- package/edit/edit-decorator.ts +178 -0
- package/edit/edit-factory.ts +138 -0
- package/edit/edit-langchain.ts +292 -0
- package/execute/execute-decorator.ts +49 -0
- package/execute/execute-factory.ts +46 -0
- package/execute/execute-langchain.ts +232 -0
- package/github/github-decorator.ts +326 -0
- package/github/github-factory.ts +355 -0
- package/github/github-langchain.ts +206 -0
- package/github/github-with-approval.ts +228 -0
- package/gmail/README.md +345 -0
- package/gmail/gmail-decorator.ts +216 -0
- package/gmail/gmail-factory.ts +231 -0
- package/gmail/gmail-langchain.ts +201 -0
- package/hubspot/README.md +316 -0
- package/hubspot/hubspot-decorator.ts +180 -0
- package/hubspot/hubspot-factory.ts +188 -0
- package/hubspot/hubspot-langchain.ts +222 -0
- package/logger-example.ts +40 -0
- package/mailchimp/README.md +321 -0
- package/mailchimp/mailchimp-decorator.ts +277 -0
- package/mailchimp/mailchimp-factory.ts +187 -0
- package/mailchimp/mailchimp-langchain.ts +155 -0
- package/notion/README.md +293 -0
- package/notion/notion-decorator.ts +275 -0
- package/notion/notion-factory.ts +256 -0
- package/notion/notion-langchain.ts +237 -0
- package/package.json +79 -0
- package/postgres/README.md +188 -0
- package/postgres/postgres-decorator.ts +198 -0
- package/postgres/postgres-factory.ts +180 -0
- package/postgres/postgres-langchain.ts +213 -0
- package/postgres/postgres-with-approval.ts +344 -0
- package/read/read-decorator.ts +154 -0
- package/read/read-factory.ts +121 -0
- package/read/read-langchain.ts +273 -0
- package/search/search-decorator.ts +206 -0
- package/search/search-factory.ts +146 -0
- package/search/search-langchain.ts +255 -0
- package/slack/README.md +339 -0
- package/slack/slack-decorator.ts +245 -0
- package/slack/slack-factory.ts +226 -0
- package/slack/slack-langchain.ts +242 -0
- package/tsconfig.json +20 -0
- package/twilio/README.md +309 -0
- package/twilio/twilio-decorator.ts +288 -0
- package/twilio/twilio-factory.ts +238 -0
- package/twilio/twilio-langchain.ts +218 -0
- package/web/web-decorator.ts +52 -0
- package/web/web-factory.ts +70 -0
- package/web/web-langchain.ts +163 -0
package/twilio/README.md
ADDED
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
# Twilio Tools Examples
|
|
2
|
+
|
|
3
|
+
Example directory contains **3 example patterns** showing different ways to use Matimo's Twilio tools:
|
|
4
|
+
|
|
5
|
+
1. **Factory Pattern** - Direct SDK execution (simplest)
|
|
6
|
+
2. **Decorator Pattern** - Class-based with `@tool` decorators
|
|
7
|
+
3. **LangChain Pattern** - AI-driven with OpenAI agent
|
|
8
|
+
|
|
9
|
+
All examples demonstrate real Twilio Messaging API operations (send SMS, send MMS, retrieve messages, list history).
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## ๐ Quick Start
|
|
14
|
+
|
|
15
|
+
### 1. Create a Twilio Account
|
|
16
|
+
|
|
17
|
+
1. Go to [twilio.com/try-twilio](https://www.twilio.com/try-twilio) and sign up for a free account
|
|
18
|
+
2. After verifying your email and phone number, you'll land on the **Twilio Console** dashboard
|
|
19
|
+
|
|
20
|
+
### 2. Find Your Account SID and Auth Token
|
|
21
|
+
|
|
22
|
+
On the [Twilio Console dashboard](https://console.twilio.com), look for the **Account Info** section:
|
|
23
|
+
|
|
24
|
+
- **Account SID** โ a 34-character identifier starting with `AC`. Acts as your username for every API call.
|
|
25
|
+
- **Auth Token** โ a 32-character secret key. Click the **eye (๐) icon** to reveal it.
|
|
26
|
+
|
|
27
|
+
> โ ๏ธ **Keep both values secret.** Do not commit them to version control.
|
|
28
|
+
|
|
29
|
+
### 3. Get a Phone Number
|
|
30
|
+
|
|
31
|
+
1. In the Console sidebar, go to **Phone Numbers โ Manage โ Buy a Number**
|
|
32
|
+
2. Choose a number with SMS capability
|
|
33
|
+
3. Click **Buy** (free trial credit covers this)
|
|
34
|
+
4. This will be your `TWILIO_FROM_NUMBER`
|
|
35
|
+
|
|
36
|
+
> **Trial accounts**: You can also use the number auto-assigned to your trial account, shown on the Console dashboard.
|
|
37
|
+
|
|
38
|
+
### 4. Verify Your "To" Number (Trial Accounts Only)
|
|
39
|
+
|
|
40
|
+
Free trial accounts can only send messages to **Verified Caller IDs**:
|
|
41
|
+
|
|
42
|
+
1. Go to **Phone Numbers โ Manage โ Verified Caller IDs**
|
|
43
|
+
2. Click **Add a new Caller ID**
|
|
44
|
+
3. Enter the phone number you want to send messages to
|
|
45
|
+
4. Complete the verification call or SMS
|
|
46
|
+
|
|
47
|
+
### 5. Set Up Environment Variables
|
|
48
|
+
|
|
49
|
+
Create or update `.env` in `examples/tools/`:
|
|
50
|
+
|
|
51
|
+
```env
|
|
52
|
+
TWILIO_ACCOUNT_SID=ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
|
53
|
+
TWILIO_AUTH_TOKEN=your_auth_token_here
|
|
54
|
+
TWILIO_FROM_NUMBER=+15557122661
|
|
55
|
+
TWILIO_TO_NUMBER=+15558675310
|
|
56
|
+
OPENAI_API_KEY=sk-your-openai-key-here # Required for LangChain example only
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
> **Note:** All phone numbers must be in **E.164 format** (e.g. `+15551234567`).
|
|
60
|
+
> Matimo automatically handles Basic Auth encoding โ no manual base64 encoding required.
|
|
61
|
+
|
|
62
|
+
### 6. Run Examples
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
# From examples/tools/ directory
|
|
66
|
+
|
|
67
|
+
# Factory Pattern (simplest, direct API calls)
|
|
68
|
+
pnpm twilio:factory
|
|
69
|
+
|
|
70
|
+
# Decorator Pattern (class-based OOP approach)
|
|
71
|
+
pnpm twilio:decorator
|
|
72
|
+
|
|
73
|
+
# LangChain Pattern (AI-driven agent with OpenAI)
|
|
74
|
+
pnpm twilio:langchain
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## ๐ Examples Overview
|
|
80
|
+
|
|
81
|
+
### 1. Factory Pattern (`twilio-factory.ts`)
|
|
82
|
+
|
|
83
|
+
**Best for:** Scripts, quick tests, CLI tools
|
|
84
|
+
|
|
85
|
+
**What it does:**
|
|
86
|
+
- โ
Direct tool execution with `matimo.execute()`
|
|
87
|
+
- โ
Validates environment variables before running
|
|
88
|
+
- โ
Sends an SMS via `twilio-send-sms`
|
|
89
|
+
- โ
Retrieves the sent message via `twilio-get-message`
|
|
90
|
+
- โ
Lists recent messages via `twilio-list-messages`
|
|
91
|
+
- โ
Simplest implementation
|
|
92
|
+
|
|
93
|
+
**Run it:**
|
|
94
|
+
```bash
|
|
95
|
+
pnpm twilio:factory
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
**Key Code:**
|
|
99
|
+
```typescript
|
|
100
|
+
const matimo = await MatimoInstance.init('./tools');
|
|
101
|
+
|
|
102
|
+
// Send SMS
|
|
103
|
+
await matimo.execute('twilio-send-sms', {
|
|
104
|
+
account_sid: process.env.TWILIO_ACCOUNT_SID,
|
|
105
|
+
to: '+15558675310',
|
|
106
|
+
from: '+15557122661',
|
|
107
|
+
body: 'Hello from Matimo!'
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
// List recent messages
|
|
111
|
+
await matimo.execute('twilio-list-messages', {
|
|
112
|
+
account_sid: process.env.TWILIO_ACCOUNT_SID,
|
|
113
|
+
page_size: 5
|
|
114
|
+
});
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
**File:** [twilio-factory.ts](twilio-factory.ts)
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
### 2. Decorator Pattern (`twilio-decorator.ts`)
|
|
122
|
+
|
|
123
|
+
**Best for:** Object-oriented design, class-based applications, service wrappers
|
|
124
|
+
|
|
125
|
+
**What it does:**
|
|
126
|
+
- โ
Class methods decorated with `@tool`
|
|
127
|
+
- โ
Automatic tool execution via decorators
|
|
128
|
+
- โ
Account SID bound at construction time and reused
|
|
129
|
+
- โ
Sends SMS, retrieves messages, lists history
|
|
130
|
+
- โ
OOP-friendly approach
|
|
131
|
+
|
|
132
|
+
**Run it:**
|
|
133
|
+
```bash
|
|
134
|
+
pnpm twilio:decorator
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
**Key Code:**
|
|
138
|
+
```typescript
|
|
139
|
+
class TwilioDecoratorAgent {
|
|
140
|
+
constructor(private readonly accountSid: string) {}
|
|
141
|
+
|
|
142
|
+
@tool('twilio-send-sms')
|
|
143
|
+
async sendSms(account_sid: string, to: string, from: string, body: string) {
|
|
144
|
+
// @tool decorator auto-executes via matimo.execute()
|
|
145
|
+
return undefined;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
@tool('twilio-list-messages')
|
|
149
|
+
async listMessages(account_sid: string, page_size?: number) {
|
|
150
|
+
return undefined;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
const agent = new TwilioDecoratorAgent(process.env.TWILIO_ACCOUNT_SID!);
|
|
155
|
+
await agent.sendSms(accountSid, '+15558675310', '+15557122661', 'Hello!');
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
**File:** [twilio-decorator.ts](twilio-decorator.ts)
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
### 3. LangChain AI Agent (`twilio-langchain.ts`)
|
|
163
|
+
|
|
164
|
+
**Best for:** True autonomous agents with AI reasoning
|
|
165
|
+
|
|
166
|
+
**What it does:**
|
|
167
|
+
- โ
AI agent (OpenAI GPT-4o-mini) decides which Twilio tools to use
|
|
168
|
+
- โ
Takes natural language instructions
|
|
169
|
+
- โ
Autonomously executes Twilio operations
|
|
170
|
+
- โ
Processes results and responds naturally
|
|
171
|
+
- โ
Multi-step reasoning (e.g. send then verify delivery status)
|
|
172
|
+
|
|
173
|
+
**Run it:**
|
|
174
|
+
```bash
|
|
175
|
+
pnpm twilio:langchain
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
**Example Conversation:**
|
|
179
|
+
```
|
|
180
|
+
User: "Send a test SMS to my verified number and check its delivery status"
|
|
181
|
+
AI Agent: I'll send the SMS first using twilio-send-sms...
|
|
182
|
+
[AI calls twilio-send-sms tool]
|
|
183
|
+
AI Agent: Message sent with SID SM1234... Now checking delivery status...
|
|
184
|
+
[AI calls twilio-get-message tool]
|
|
185
|
+
AI Agent: The message was delivered successfully. Status: delivered.
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
**Key Code:**
|
|
189
|
+
```typescript
|
|
190
|
+
const agent = await createAgent({
|
|
191
|
+
model: new ChatOpenAI({ modelName: 'gpt-4o-mini' }),
|
|
192
|
+
tools: langchainTools // AI picks which Twilio tools to use
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
const response = await agent.invoke({
|
|
196
|
+
messages: [{ role: 'user', content: 'Send a test SMS to my number' }]
|
|
197
|
+
});
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
**File:** [twilio-langchain.ts](twilio-langchain.ts)
|
|
201
|
+
|
|
202
|
+
---
|
|
203
|
+
|
|
204
|
+
## ๐ ๏ธ Available Twilio Tools (4 Total)
|
|
205
|
+
|
|
206
|
+
All patterns have access to these 4 Twilio tools:
|
|
207
|
+
|
|
208
|
+
| Tool | Method | Description |
|
|
209
|
+
|------|--------|-------------|
|
|
210
|
+
| `twilio-send-sms` | POST | Send an SMS message |
|
|
211
|
+
| `twilio-send-mms` | POST | Send an MMS message with media |
|
|
212
|
+
| `twilio-get-message` | GET | Retrieve a message by SID |
|
|
213
|
+
| `twilio-list-messages` | GET | List messages with optional filters |
|
|
214
|
+
|
|
215
|
+
### Tool Parameters
|
|
216
|
+
|
|
217
|
+
#### `twilio-send-sms`
|
|
218
|
+
| Parameter | Type | Required | Description |
|
|
219
|
+
|-----------|------|----------|-------------|
|
|
220
|
+
| `account_sid` | string | โ
| Your Twilio Account SID (`AC...`) |
|
|
221
|
+
| `to` | string | โ
| Recipient phone number (E.164) |
|
|
222
|
+
| `from` | string | โ
| Twilio phone number (E.164) |
|
|
223
|
+
| `body` | string | โ
| SMS message text |
|
|
224
|
+
| `status_callback` | string | โ | URL for delivery status webhooks |
|
|
225
|
+
|
|
226
|
+
#### `twilio-send-mms`
|
|
227
|
+
| Parameter | Type | Required | Description |
|
|
228
|
+
|-----------|------|----------|-------------|
|
|
229
|
+
| `account_sid` | string | โ
| Your Twilio Account SID (`AC...`) |
|
|
230
|
+
| `to` | string | โ
| Recipient phone number (E.164) |
|
|
231
|
+
| `from` | string | โ
| Twilio phone number (E.164) |
|
|
232
|
+
| `media_url` | string | โ
| Publicly accessible URL of the media file |
|
|
233
|
+
| `body` | string | โ | Optional text caption |
|
|
234
|
+
| `status_callback` | string | โ | URL for delivery status webhooks |
|
|
235
|
+
|
|
236
|
+
#### `twilio-get-message`
|
|
237
|
+
| Parameter | Type | Required | Description |
|
|
238
|
+
|-----------|------|----------|-------------|
|
|
239
|
+
| `account_sid` | string | โ
| Your Twilio Account SID (`AC...`) |
|
|
240
|
+
| `message_sid` | string | โ
| Message SID (`SM...`) to retrieve |
|
|
241
|
+
|
|
242
|
+
#### `twilio-list-messages`
|
|
243
|
+
| Parameter | Type | Required | Description |
|
|
244
|
+
|-----------|------|----------|-------------|
|
|
245
|
+
| `account_sid` | string | โ
| Your Twilio Account SID (`AC...`) |
|
|
246
|
+
| `to` | string | โ | Filter by recipient number |
|
|
247
|
+
| `from` | string | โ | Filter by sender number |
|
|
248
|
+
| `date_sent` | string | โ | Filter by date (YYYY-MM-DD) |
|
|
249
|
+
| `page_size` | number | โ | Results per page (default 50, max 1000) |
|
|
250
|
+
|
|
251
|
+
---
|
|
252
|
+
|
|
253
|
+
## ๐งช Trial Account Limitations
|
|
254
|
+
|
|
255
|
+
| Limitation | Details |
|
|
256
|
+
|-----------|---------|
|
|
257
|
+
| **Daily message limit** | 50 messages/day |
|
|
258
|
+
| **Recipients** | Must be Verified Caller IDs only |
|
|
259
|
+
| **Trial prefix** | All outgoing messages include `"Sent from your Twilio trial account -"` |
|
|
260
|
+
| **Geographic reach** | Sending to some international numbers may be restricted |
|
|
261
|
+
| **Phone numbers** | 1 trial number provided free |
|
|
262
|
+
| **WhatsApp** | Not available on trial |
|
|
263
|
+
|
|
264
|
+
To remove these limitations, [upgrade to a paid account](https://console.twilio.com/us1/billing/upgrade).
|
|
265
|
+
|
|
266
|
+
---
|
|
267
|
+
|
|
268
|
+
## ๐ง Troubleshooting
|
|
269
|
+
|
|
270
|
+
### `โ Error 21659: From number is not a valid, SMS-capable Twilio number`
|
|
271
|
+
Your `TWILIO_FROM_NUMBER` is not a Twilio number on your account, or it doesn't have SMS capability.
|
|
272
|
+
**Fix:** Go to [Phone Numbers โ Manage โ Active Numbers](https://console.twilio.com/us1/develop/phone-numbers/manage/active) and confirm the number is SMS-capable.
|
|
273
|
+
|
|
274
|
+
### `โ Error 21211: Invalid To phone number`
|
|
275
|
+
The `to` number is not in E.164 format or is not a valid phone number.
|
|
276
|
+
**Fix:** Use format `+15551234567` (country code + number, no dashes or spaces).
|
|
277
|
+
|
|
278
|
+
### `โ Error 21408: Permission to send to this region is not enabled`
|
|
279
|
+
Your account doesn't have permission to send to that country.
|
|
280
|
+
**Fix:** Go to [Messaging โ Settings โ Geo Permissions](https://console.twilio.com/us1/develop/sms/settings/geo-permissions) and enable the target region.
|
|
281
|
+
|
|
282
|
+
### `โ Error 21266: Unverified phone number in To field during trial`
|
|
283
|
+
You're on a trial account and the recipient number is not a Verified Caller ID.
|
|
284
|
+
**Fix:** Add the number at [Phone Numbers โ Manage โ Verified Caller IDs](https://console.twilio.com/us1/develop/phone-numbers/manage/verified).
|
|
285
|
+
|
|
286
|
+
### `โ 401 Unauthorized / Error 20003: Authentication Failed`
|
|
287
|
+
Your `TWILIO_ACCOUNT_SID` or `TWILIO_AUTH_TOKEN` is incorrect.
|
|
288
|
+
**Fix:** Copy both values directly from the [Console dashboard](https://console.twilio.com). Matimo handles Basic Auth encoding automatically.
|
|
289
|
+
|
|
290
|
+
### `TWILIO_ACCOUNT_SID not set in .env`
|
|
291
|
+
The `account_sid` parameter is required for all Twilio tools.
|
|
292
|
+
**Fix:** Add `TWILIO_ACCOUNT_SID=ACxxxxxxxx` to `examples/tools/.env`.
|
|
293
|
+
|
|
294
|
+
### Messages have an unexpected prefix
|
|
295
|
+
Trial accounts automatically prepend `"Sent from your Twilio trial account - "` to all messages. This is removed when you upgrade to a paid account.
|
|
296
|
+
|
|
297
|
+
### `OPENAI_API_KEY not set` (LangChain example only)
|
|
298
|
+
The LangChain agent requires an OpenAI API key.
|
|
299
|
+
**Fix:** Get one at [platform.openai.com/api-keys](https://platform.openai.com/api-keys) and add `OPENAI_API_KEY=sk-...` to your `.env`.
|
|
300
|
+
|
|
301
|
+
---
|
|
302
|
+
|
|
303
|
+
## ๐ Related Documentation
|
|
304
|
+
|
|
305
|
+
- [Matimo Twilio Package](../../../packages/twilio/README.md)
|
|
306
|
+
- [Twilio Messages API Reference](https://www.twilio.com/docs/messaging/api/message-resource)
|
|
307
|
+
- [Twilio Console](https://console.twilio.com)
|
|
308
|
+
- [Twilio Free Trial Guide](https://www.twilio.com/docs/messaging/guides/how-to-use-your-free-trial-account)
|
|
309
|
+
- [Matimo SDK Docs](../../../packages/core/README.md)
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* ============================================================================
|
|
4
|
+
* TWILIO TOOLS - DECORATOR PATTERN EXAMPLE
|
|
5
|
+
* ============================================================================
|
|
6
|
+
*
|
|
7
|
+
* PATTERN: Decorator Pattern with @tool
|
|
8
|
+
* โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
9
|
+
* Uses TypeScript @tool decorators to wrap Twilio tool calls in a class.
|
|
10
|
+
*
|
|
11
|
+
* Use this pattern when:
|
|
12
|
+
* โ
Building class-based applications
|
|
13
|
+
* โ
Encapsulating tool logic in services
|
|
14
|
+
* โ
Adding custom methods that combine multiple tools
|
|
15
|
+
* โ
Need reusable tool wrappers
|
|
16
|
+
* โ
Object-oriented design preferred
|
|
17
|
+
*
|
|
18
|
+
* SETUP:
|
|
19
|
+
* โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
20
|
+
* 1. Create .env file:
|
|
21
|
+
* TWILIO_ACCOUNT_SID=ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
|
22
|
+
* TWILIO_AUTH_TOKEN=your_auth_token_here
|
|
23
|
+
* TWILIO_FROM_NUMBER=+15557122661
|
|
24
|
+
* TWILIO_TO_NUMBER=+15558675310
|
|
25
|
+
*
|
|
26
|
+
* Matimo automatically handles base64 Basic Auth encoding โ no extra steps!
|
|
27
|
+
*
|
|
28
|
+
* USAGE:
|
|
29
|
+
* โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
30
|
+
* pnpm twilio:decorator
|
|
31
|
+
*
|
|
32
|
+
* ============================================================================
|
|
33
|
+
*/
|
|
34
|
+
|
|
35
|
+
import 'dotenv/config';
|
|
36
|
+
import { MatimoInstance, tool, setGlobalMatimoInstance } from 'matimo';
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Decorator Pattern Agent - Uses @tool decorators for Twilio messaging operations.
|
|
40
|
+
* The account_sid is bound at construction time and reused in all tool calls.
|
|
41
|
+
*/
|
|
42
|
+
class TwilioDecoratorAgent {
|
|
43
|
+
constructor(private readonly accountSid: string) {}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Send an SMS message - automatically executes via @tool decorator
|
|
47
|
+
*/
|
|
48
|
+
@tool('twilio-send-sms')
|
|
49
|
+
async sendSms(
|
|
50
|
+
account_sid: string,
|
|
51
|
+
to: string,
|
|
52
|
+
from: string,
|
|
53
|
+
body: string,
|
|
54
|
+
status_callback?: string
|
|
55
|
+
): Promise<unknown> {
|
|
56
|
+
// Decorator automatically calls: matimo.execute('twilio-send-sms', { account_sid, to, from, body, status_callback })
|
|
57
|
+
return undefined;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Send an MMS message with media - automatically executes via @tool decorator
|
|
62
|
+
*/
|
|
63
|
+
@tool('twilio-send-mms')
|
|
64
|
+
async sendMms(
|
|
65
|
+
account_sid: string,
|
|
66
|
+
to: string,
|
|
67
|
+
from: string,
|
|
68
|
+
media_url: string,
|
|
69
|
+
body?: string
|
|
70
|
+
): Promise<unknown> {
|
|
71
|
+
// Decorator automatically calls: matimo.execute('twilio-send-mms', { account_sid, to, from, media_url, body })
|
|
72
|
+
return undefined;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Fetch a message by SID - automatically executes via @tool decorator
|
|
77
|
+
*/
|
|
78
|
+
@tool('twilio-get-message')
|
|
79
|
+
async getMessage(account_sid: string, message_sid: string): Promise<unknown> {
|
|
80
|
+
// Decorator automatically calls: matimo.execute('twilio-get-message', { account_sid, message_sid })
|
|
81
|
+
return undefined;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* List messages with optional filters - automatically executes via @tool decorator
|
|
86
|
+
*/
|
|
87
|
+
@tool('twilio-list-messages')
|
|
88
|
+
async listMessages(
|
|
89
|
+
account_sid: string,
|
|
90
|
+
to?: string,
|
|
91
|
+
from?: string,
|
|
92
|
+
date_sent?: string,
|
|
93
|
+
page_size?: number
|
|
94
|
+
): Promise<unknown> {
|
|
95
|
+
// Decorator automatically calls: matimo.execute('twilio-list-messages', { account_sid, to, from, date_sent, page_size })
|
|
96
|
+
return undefined;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// โโ Convenience helpers that bind account_sid automatically โโโโโโโโโโโโโโ
|
|
100
|
+
|
|
101
|
+
/** Send SMS using the bound account SID */
|
|
102
|
+
async sms(to: string, from: string, body: string): Promise<unknown> {
|
|
103
|
+
return this.sendSms(this.accountSid, to, from, body);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/** Send MMS using the bound account SID */
|
|
107
|
+
async mms(to: string, from: string, mediaUrl: string, body?: string): Promise<unknown> {
|
|
108
|
+
return this.sendMms(this.accountSid, to, from, mediaUrl, body);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/** Fetch a message using the bound account SID */
|
|
112
|
+
async fetch(messageSid: string): Promise<unknown> {
|
|
113
|
+
return this.getMessage(this.accountSid, messageSid);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/** List recent messages using the bound account SID */
|
|
117
|
+
async list(
|
|
118
|
+
options: { to?: string; from?: string; dateSent?: string; pageSize?: number } = {}
|
|
119
|
+
): Promise<unknown> {
|
|
120
|
+
return this.listMessages(
|
|
121
|
+
this.accountSid,
|
|
122
|
+
options.to,
|
|
123
|
+
options.from,
|
|
124
|
+
options.dateSent,
|
|
125
|
+
options.pageSize
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Run decorator pattern examples
|
|
132
|
+
*/
|
|
133
|
+
async function runTwilioDecoratorExamples() {
|
|
134
|
+
console.info('โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ');
|
|
135
|
+
console.info('โ Twilio Tools - Decorator Pattern โ');
|
|
136
|
+
console.info('โ (Uses @tool decorators for automatic execution) โ');
|
|
137
|
+
console.info('โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ\n');
|
|
138
|
+
|
|
139
|
+
// Validate required environment variables
|
|
140
|
+
const accountSid = process.env.TWILIO_ACCOUNT_SID;
|
|
141
|
+
const authToken = process.env.TWILIO_AUTH_TOKEN;
|
|
142
|
+
const fromNumber = process.env.TWILIO_FROM_NUMBER;
|
|
143
|
+
const toNumber = process.env.TWILIO_TO_NUMBER;
|
|
144
|
+
|
|
145
|
+
if (!accountSid) {
|
|
146
|
+
console.info('๐ Warning: TWILIO_ACCOUNT_SID not set in environment');
|
|
147
|
+
console.info(' Set it: export TWILIO_ACCOUNT_SID="ACxxxxxxxxxx"');
|
|
148
|
+
console.info(' Get it from: https://console.twilio.com\n');
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
if (!authToken) {
|
|
152
|
+
console.info('๐ Warning: TWILIO_AUTH_TOKEN not set');
|
|
153
|
+
console.info(' Set it: export TWILIO_AUTH_TOKEN="your_auth_token"\n');
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if (!fromNumber || !toNumber) {
|
|
157
|
+
console.info('๐ฑ Warning: TWILIO_FROM_NUMBER or TWILIO_TO_NUMBER not set\n');
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
if (!accountSid || !authToken || !fromNumber || !toNumber) {
|
|
161
|
+
console.info('โ ๏ธ Missing credentials โ skipping live API calls.\n');
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
console.info(`๐ Account SID: ${accountSid ? 'Configured' : '(not set)'}`);
|
|
165
|
+
console.info(`๐ค From: ${fromNumber || '(not set)'}`);
|
|
166
|
+
console.info(`๐ฅ To: ${toNumber || '(not set)'}\n`);
|
|
167
|
+
|
|
168
|
+
try {
|
|
169
|
+
// Initialize Matimo with auto-discovery
|
|
170
|
+
console.info('๐ Initializing Matimo...');
|
|
171
|
+
const matimo = await MatimoInstance.init({ autoDiscover: true });
|
|
172
|
+
setGlobalMatimoInstance(matimo);
|
|
173
|
+
|
|
174
|
+
const allTools = matimo.listTools();
|
|
175
|
+
const twilioTools = allTools.filter((t) => t.name.startsWith('twilio-'));
|
|
176
|
+
console.info(`๐ฆ Loaded ${allTools.length} total tools, ${twilioTools.length} Twilio tools\n`);
|
|
177
|
+
|
|
178
|
+
// Create agent with bound account SID
|
|
179
|
+
const agent = new TwilioDecoratorAgent(accountSid || 'ACxxxxxxxx');
|
|
180
|
+
|
|
181
|
+
console.info('๐งช Testing Twilio Tools with Decorator Pattern');
|
|
182
|
+
console.info('โ'.repeat(60) + '\n');
|
|
183
|
+
|
|
184
|
+
// โโ Example 1: List recent messages โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
185
|
+
console.info('๐ Example 1: List Recent Messages');
|
|
186
|
+
console.info('โ'.repeat(60));
|
|
187
|
+
try {
|
|
188
|
+
const listResult = await agent.list({ pageSize: 5 });
|
|
189
|
+
const listData = (listResult as any).data || listResult;
|
|
190
|
+
|
|
191
|
+
if (listData.messages && Array.isArray(listData.messages)) {
|
|
192
|
+
console.info(`โ
Found ${listData.messages.length} recent message(s):`);
|
|
193
|
+
listData.messages.slice(0, 3).forEach((msg: any, idx: number) => {
|
|
194
|
+
console.info(
|
|
195
|
+
` ${idx + 1}. ${msg.sid} โ ${msg.status} โ "${msg.body?.substring(0, 40)}"`
|
|
196
|
+
);
|
|
197
|
+
});
|
|
198
|
+
} else {
|
|
199
|
+
console.info(`โน๏ธ Response: ${JSON.stringify(listData).substring(0, 100)}`);
|
|
200
|
+
}
|
|
201
|
+
} catch (error) {
|
|
202
|
+
console.info(`โ Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
203
|
+
}
|
|
204
|
+
console.info();
|
|
205
|
+
|
|
206
|
+
// โโ Example 2: Send SMS โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
207
|
+
console.info('๐ฌ Example 2: Send SMS Message');
|
|
208
|
+
console.info('โ'.repeat(60));
|
|
209
|
+
|
|
210
|
+
if (!accountSid || !fromNumber || !toNumber) {
|
|
211
|
+
console.info('โญ๏ธ Skipping โ credentials not set');
|
|
212
|
+
} else {
|
|
213
|
+
try {
|
|
214
|
+
const smsResult = await agent.sms(
|
|
215
|
+
toNumber,
|
|
216
|
+
fromNumber,
|
|
217
|
+
`๐ Hello from Matimo! Decorator pattern test at ${new Date().toISOString()}`
|
|
218
|
+
);
|
|
219
|
+
const smsData = (smsResult as any).data || smsResult;
|
|
220
|
+
|
|
221
|
+
if (smsData.sid) {
|
|
222
|
+
console.info(`โ
SMS queued successfully!`);
|
|
223
|
+
console.info(` SID: ${smsData.sid}`);
|
|
224
|
+
console.info(` Status: ${smsData.status}`);
|
|
225
|
+
console.info(` To: ${smsData.to}`);
|
|
226
|
+
|
|
227
|
+
// โโ Example 3: Fetch the sent message โโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
228
|
+
console.info();
|
|
229
|
+
console.info('๐ Example 3: Fetch the Sent Message');
|
|
230
|
+
console.info('โ'.repeat(60));
|
|
231
|
+
const fetchResult = await agent.fetch(smsData.sid);
|
|
232
|
+
const fetchData = (fetchResult as any).data || fetchResult;
|
|
233
|
+
|
|
234
|
+
if (fetchData.sid) {
|
|
235
|
+
console.info(`โ
Message fetched!`);
|
|
236
|
+
console.info(` Status: ${fetchData.status}`);
|
|
237
|
+
console.info(` Direction: ${fetchData.direction}`);
|
|
238
|
+
console.info(` Num Segments: ${fetchData.num_segments}`);
|
|
239
|
+
} else {
|
|
240
|
+
console.info(`โ Failed: ${JSON.stringify(fetchData).substring(0, 100)}`);
|
|
241
|
+
}
|
|
242
|
+
} else {
|
|
243
|
+
console.info(`โ SMS failed: ${JSON.stringify(smsData).substring(0, 100)}`);
|
|
244
|
+
}
|
|
245
|
+
} catch (error) {
|
|
246
|
+
console.info(`โ Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
console.info();
|
|
250
|
+
|
|
251
|
+
// โโ Example 4: List messages filtered by sender โโโโโโโโโโโโโโโโโโโโโโ
|
|
252
|
+
console.info('๐ Example 4: List Messages Filtered by Sender');
|
|
253
|
+
console.info('โ'.repeat(60));
|
|
254
|
+
|
|
255
|
+
if (!accountSid || !fromNumber) {
|
|
256
|
+
console.info('โญ๏ธ Skipping โ credentials not set');
|
|
257
|
+
} else {
|
|
258
|
+
try {
|
|
259
|
+
const fromResult = await agent.list({ from: fromNumber, pageSize: 5 });
|
|
260
|
+
const fromData = (fromResult as any).data || fromResult;
|
|
261
|
+
|
|
262
|
+
if (fromData.messages && Array.isArray(fromData.messages)) {
|
|
263
|
+
console.info(`โ
Found ${fromData.messages.length} message(s) from ${fromNumber}`);
|
|
264
|
+
fromData.messages.slice(0, 3).forEach((msg: any, idx: number) => {
|
|
265
|
+
console.info(` ${idx + 1}. ${msg.sid} โ ${msg.status}`);
|
|
266
|
+
});
|
|
267
|
+
} else {
|
|
268
|
+
console.info(`โน๏ธ Response: ${JSON.stringify(fromData).substring(0, 100)}`);
|
|
269
|
+
}
|
|
270
|
+
} catch (error) {
|
|
271
|
+
console.info(`โ Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
console.info('\n' + 'โ'.repeat(60));
|
|
276
|
+
console.info('โจ Decorator Pattern Example Complete!');
|
|
277
|
+
console.info('โ'.repeat(60) + '\n');
|
|
278
|
+
} catch (error) {
|
|
279
|
+
console.error('โ Fatal error:', error instanceof Error ? error.message : String(error));
|
|
280
|
+
process.exit(1);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
// Run the example
|
|
285
|
+
runTwilioDecoratorExamples().catch((error) => {
|
|
286
|
+
console.error('โ Unhandled error:', error);
|
|
287
|
+
process.exit(1);
|
|
288
|
+
});
|