@skillful-ai/piece-skai-adapters 0.0.1
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 +325 -0
- package/package.json +36 -0
- package/skillful-ai-piece-skai-adapters-0.0.1.tgz +0 -0
- package/src/index.d.ts +1 -0
- package/src/index.js +25 -0
- package/src/index.js.map +1 -0
- package/src/lib/actions/skai-to-telegram.d.ts +3 -0
- package/src/lib/actions/skai-to-telegram.js +192 -0
- package/src/lib/actions/skai-to-telegram.js.map +1 -0
- package/src/lib/actions/skai-to-whatsapp.d.ts +3 -0
- package/src/lib/actions/skai-to-whatsapp.js +179 -0
- package/src/lib/actions/skai-to-whatsapp.js.map +1 -0
- package/src/lib/actions/telegram-to-skai.d.ts +6 -0
- package/src/lib/actions/telegram-to-skai.js +93 -0
- package/src/lib/actions/telegram-to-skai.js.map +1 -0
- package/src/lib/actions/whatsapp-to-skai.d.ts +6 -0
- package/src/lib/actions/whatsapp-to-skai.js +93 -0
- package/src/lib/actions/whatsapp-to-skai.js.map +1 -0
- package/src/lib/auth/skai.auth.d.ts +3 -0
- package/src/lib/auth/skai.auth.js +32 -0
- package/src/lib/auth/skai.auth.js.map +1 -0
- package/src/lib/common/dropdowns.d.ts +5 -0
- package/src/lib/common/dropdowns.js +61 -0
- package/src/lib/common/dropdowns.js.map +1 -0
- package/src/lib/common/skai-client.d.ts +65 -0
- package/src/lib/common/skai-client.js +173 -0
- package/src/lib/common/skai-client.js.map +1 -0
- package/src/lib/common/types/generic-message.d.ts +44 -0
- package/src/lib/common/types/generic-message.js +27 -0
- package/src/lib/common/types/generic-message.js.map +1 -0
- package/src/lib/transformers/telegram.transformer.d.ts +78 -0
- package/src/lib/transformers/telegram.transformer.js +72 -0
- package/src/lib/transformers/telegram.transformer.js.map +1 -0
- package/src/lib/transformers/whatsapp.transformer.d.ts +73 -0
- package/src/lib/transformers/whatsapp.transformer.js +136 -0
- package/src/lib/transformers/whatsapp.transformer.js.map +1 -0
- package/src/lib/triggers/skai-response-webhook.d.ts +20 -0
- package/src/lib/triggers/skai-response-webhook.js +144 -0
- package/src/lib/triggers/skai-response-webhook.js.map +1 -0
package/README.md
ADDED
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
# SKAI Adapters Piece
|
|
2
|
+
|
|
3
|
+
Transform messages between messaging platforms and SKAI Agents API.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The SKAI Adapters piece acts as a bridge between messaging platforms (WhatsApp, Telegram, Discord, etc.) and SKAI Agents. It provides:
|
|
8
|
+
|
|
9
|
+
- **Platform-agnostic message format** - GenericMessage interface
|
|
10
|
+
- **Bidirectional transformations** - Platform ↔ SKAI
|
|
11
|
+
- **SKAI API integration** - Direct communication with SKAI Agents
|
|
12
|
+
- **Agent dropdown** - Dynamic agent selection from your SKAI account
|
|
13
|
+
|
|
14
|
+
## Architecture
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
Platform Message → Adapter (Transform) → SKAI Agent → Adapter (Transform) → Platform Message
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
### GenericMessage Format
|
|
21
|
+
|
|
22
|
+
All platform messages are transformed to this unified format:
|
|
23
|
+
|
|
24
|
+
```typescript
|
|
25
|
+
interface GenericMessage {
|
|
26
|
+
external_id: string; // Platform identifier (phone, chat ID, etc.)
|
|
27
|
+
platform: Platform; // 'whatsapp' | 'telegram' | 'discord'
|
|
28
|
+
message: string; // Text content
|
|
29
|
+
reference_id?: string; // Platform's message ID
|
|
30
|
+
media_urls?: string[]; // Media attachments
|
|
31
|
+
media_types?: MediaType[]; // Types of media
|
|
32
|
+
sender_name?: string; // Display name
|
|
33
|
+
metadata?: Record<string, any>; // Platform-specific data
|
|
34
|
+
timestamp?: string; // ISO 8601 timestamp
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Actions
|
|
39
|
+
|
|
40
|
+
### WhatsApp → SKAI Agent
|
|
41
|
+
|
|
42
|
+
Transform WhatsApp message and process with SKAI agent.
|
|
43
|
+
|
|
44
|
+
**Inputs:**
|
|
45
|
+
- WhatsApp Message (JSON) - Output from WhatsApp New Message trigger
|
|
46
|
+
- Environment - Production/Development/Staging
|
|
47
|
+
- SKAI Agent - Select from dropdown
|
|
48
|
+
- Include Raw Metadata - Optional
|
|
49
|
+
|
|
50
|
+
**Output:**
|
|
51
|
+
```json
|
|
52
|
+
{
|
|
53
|
+
"success": true,
|
|
54
|
+
"skaiResponse": {
|
|
55
|
+
"success": true,
|
|
56
|
+
"response": "Agent's reply",
|
|
57
|
+
"conversationId": "conv_123"
|
|
58
|
+
},
|
|
59
|
+
"genericMessage": { /* Transformed message */ },
|
|
60
|
+
"originalPlatform": "whatsapp"
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### SKAI → WhatsApp
|
|
65
|
+
|
|
66
|
+
Transform SKAI agent response back to WhatsApp format.
|
|
67
|
+
|
|
68
|
+
**Inputs:**
|
|
69
|
+
- SKAI Response (JSON) - Output from WhatsApp → SKAI action
|
|
70
|
+
- Include Conversation ID - Add as footer
|
|
71
|
+
- Custom Footer - Optional custom text
|
|
72
|
+
|
|
73
|
+
**Output:**
|
|
74
|
+
```json
|
|
75
|
+
{
|
|
76
|
+
"to": "+1234567890",
|
|
77
|
+
"text": "Agent's formatted response",
|
|
78
|
+
"conversationId": "conv_123",
|
|
79
|
+
"metadata": { /* Additional data */ }
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Setup
|
|
84
|
+
|
|
85
|
+
### Prerequisites
|
|
86
|
+
|
|
87
|
+
1. **SKAI Account** - Sign up at [agents.skillfulai.io](https://agents.skillfulai.io)
|
|
88
|
+
2. **SKAI API Key** - Generate from Settings → API Keys
|
|
89
|
+
3. **SKAI Agent** - Create at least one agent
|
|
90
|
+
|
|
91
|
+
### Getting SKAI API Key
|
|
92
|
+
|
|
93
|
+
1. Log in to [SKAI Agents Platform](https://agents.skillfulai.io)
|
|
94
|
+
2. Navigate to Settings → API Keys
|
|
95
|
+
3. Click "Create New API Key"
|
|
96
|
+
4. Copy the key (starts with `sk_`)
|
|
97
|
+
5. Paste into ActivePieces when configuring SKAI Adapters
|
|
98
|
+
|
|
99
|
+
## Usage Examples
|
|
100
|
+
|
|
101
|
+
### Example 1: WhatsApp Auto-Reply with SKAI
|
|
102
|
+
|
|
103
|
+
```
|
|
104
|
+
1. TRIGGER: WhatsApp - New Message
|
|
105
|
+
└─ Output: WhatsApp message
|
|
106
|
+
|
|
107
|
+
2. ACTION: WhatsApp → SKAI Agent
|
|
108
|
+
└─ Input: {{trigger.output}}
|
|
109
|
+
└─ Agent: Customer Support Agent
|
|
110
|
+
└─ Environment: Production
|
|
111
|
+
└─ Output: SKAI response
|
|
112
|
+
|
|
113
|
+
3. ACTION: SKAI → WhatsApp
|
|
114
|
+
└─ Input: {{step2.output}}
|
|
115
|
+
└─ Include Conversation ID: Yes
|
|
116
|
+
└─ Output: Formatted message
|
|
117
|
+
|
|
118
|
+
4. ACTION: WhatsApp - Send Message
|
|
119
|
+
└─ To: {{step3.to}}
|
|
120
|
+
└─ Message: {{step3.text}}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Example 2: Multi-Platform Support
|
|
124
|
+
|
|
125
|
+
**Flow for WhatsApp:**
|
|
126
|
+
```
|
|
127
|
+
WhatsApp New Message
|
|
128
|
+
→ WhatsApp → SKAI
|
|
129
|
+
→ SKAI → WhatsApp
|
|
130
|
+
→ WhatsApp Send Message
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
**Flow for Telegram** (coming soon):
|
|
134
|
+
```
|
|
135
|
+
Telegram New Message
|
|
136
|
+
→ Telegram → SKAI
|
|
137
|
+
→ SKAI → Telegram
|
|
138
|
+
→ Telegram Send Message
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
**Same agent, different platforms!**
|
|
142
|
+
|
|
143
|
+
### Example 3: Conditional Responses
|
|
144
|
+
|
|
145
|
+
```
|
|
146
|
+
1. TRIGGER: WhatsApp - New Message
|
|
147
|
+
|
|
148
|
+
2. ACTION: Code - Check Keywords
|
|
149
|
+
└─ If message contains "urgent"
|
|
150
|
+
|
|
151
|
+
3. BRANCH:
|
|
152
|
+
a) If Urgent:
|
|
153
|
+
WhatsApp → SKAI (Priority Agent)
|
|
154
|
+
|
|
155
|
+
b) If Normal:
|
|
156
|
+
WhatsApp → SKAI (Standard Agent)
|
|
157
|
+
|
|
158
|
+
4. ACTION: SKAI → WhatsApp
|
|
159
|
+
5. ACTION: WhatsApp - Send Message
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
## Supported Platforms
|
|
163
|
+
|
|
164
|
+
### Currently Supported
|
|
165
|
+
- ✅ WhatsApp Business
|
|
166
|
+
|
|
167
|
+
### Coming Soon
|
|
168
|
+
- 🔜 Telegram
|
|
169
|
+
- 🔜 Discord
|
|
170
|
+
- 🔜 SMS (Twilio)
|
|
171
|
+
- 🔜 Slack
|
|
172
|
+
|
|
173
|
+
## Message Type Support
|
|
174
|
+
|
|
175
|
+
### WhatsApp
|
|
176
|
+
- ✅ Text messages
|
|
177
|
+
- ✅ Images (with captions)
|
|
178
|
+
- ✅ Videos (with captions)
|
|
179
|
+
- ✅ Audio messages
|
|
180
|
+
- ✅ Documents
|
|
181
|
+
- ✅ Voice messages
|
|
182
|
+
|
|
183
|
+
All media information is preserved in `genericMessage.metadata`.
|
|
184
|
+
|
|
185
|
+
## API Integration
|
|
186
|
+
|
|
187
|
+
### SKAI Agents API
|
|
188
|
+
|
|
189
|
+
**Endpoints:**
|
|
190
|
+
- `GET /agents` - List user's agents
|
|
191
|
+
- `POST /agents/{id}/process` - Process message with agent
|
|
192
|
+
|
|
193
|
+
**Environments:**
|
|
194
|
+
- Production: `https://api-production.agents.skillfulai.io`
|
|
195
|
+
- Development: `https://api-development.agents.skillfulai.io`
|
|
196
|
+
- Staging: `https://api-staging.agents.skillfulai.io`
|
|
197
|
+
|
|
198
|
+
### Authentication
|
|
199
|
+
|
|
200
|
+
All requests use Bearer token authentication:
|
|
201
|
+
```
|
|
202
|
+
Authorization: Bearer sk_your_api_key_here
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
## Error Handling
|
|
206
|
+
|
|
207
|
+
### Common Errors
|
|
208
|
+
|
|
209
|
+
**"SKAI API error (401)"**
|
|
210
|
+
- Invalid API key
|
|
211
|
+
- API key expired
|
|
212
|
+
- Solution: Regenerate API key in SKAI platform
|
|
213
|
+
|
|
214
|
+
**"SKAI API error (404)"**
|
|
215
|
+
- Agent not found
|
|
216
|
+
- Agent ID invalid
|
|
217
|
+
- Solution: Verify agent exists and is minted
|
|
218
|
+
|
|
219
|
+
**"Failed to fetch agents"**
|
|
220
|
+
- Network issue
|
|
221
|
+
- API key missing
|
|
222
|
+
- Solution: Check authentication and network
|
|
223
|
+
|
|
224
|
+
**"Invalid WhatsApp message: missing required fields"**
|
|
225
|
+
- Malformed input
|
|
226
|
+
- Missing `from` or `messageId`
|
|
227
|
+
- Solution: Ensure WhatsApp trigger output is used
|
|
228
|
+
|
|
229
|
+
### Debugging
|
|
230
|
+
|
|
231
|
+
Enable detailed logging by checking ActivePieces logs:
|
|
232
|
+
```
|
|
233
|
+
✅ Message transformed
|
|
234
|
+
✅ SKAI API response received
|
|
235
|
+
❌ SKAI API error: ...
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
## Advanced Features
|
|
239
|
+
|
|
240
|
+
### Custom Transformers
|
|
241
|
+
|
|
242
|
+
To add support for new platforms, create a transformer:
|
|
243
|
+
|
|
244
|
+
```typescript
|
|
245
|
+
import { GenericMessage, Platform } from '../common/types/generic-message';
|
|
246
|
+
|
|
247
|
+
export class TelegramTransformer {
|
|
248
|
+
transform(telegramMessage: any): GenericMessage {
|
|
249
|
+
return {
|
|
250
|
+
external_id: telegramMessage.chatId,
|
|
251
|
+
platform: Platform.TELEGRAM,
|
|
252
|
+
message: telegramMessage.text,
|
|
253
|
+
// ... other fields
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
### Metadata Preservation
|
|
260
|
+
|
|
261
|
+
All platform-specific metadata is preserved:
|
|
262
|
+
|
|
263
|
+
```javascript
|
|
264
|
+
// WhatsApp metadata includes:
|
|
265
|
+
{
|
|
266
|
+
type: 'image',
|
|
267
|
+
timestamp: '1642511234',
|
|
268
|
+
image: {
|
|
269
|
+
id: 'img_123',
|
|
270
|
+
mimeType: 'image/jpeg',
|
|
271
|
+
caption: 'Check this out!'
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
## Building
|
|
277
|
+
|
|
278
|
+
```bash
|
|
279
|
+
# Build the piece
|
|
280
|
+
npx nx build pieces-skai-adapters
|
|
281
|
+
|
|
282
|
+
# Build all custom pieces
|
|
283
|
+
npx nx run-many -t build --projects=pieces-*
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
## Testing
|
|
287
|
+
|
|
288
|
+
```bash
|
|
289
|
+
# Run unit tests (coming soon)
|
|
290
|
+
npx nx test pieces-skai-adapters
|
|
291
|
+
|
|
292
|
+
# Manual testing
|
|
293
|
+
1. Create test flow in ActivePieces
|
|
294
|
+
2. Send test message from platform
|
|
295
|
+
3. Verify transformation and SKAI response
|
|
296
|
+
4. Check logs for detailed output
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
## Contributing
|
|
300
|
+
|
|
301
|
+
To add support for a new platform:
|
|
302
|
+
|
|
303
|
+
1. Create transformer in `src/lib/transformers/`
|
|
304
|
+
2. Create actions in `src/lib/actions/`
|
|
305
|
+
3. Update `src/index.ts`
|
|
306
|
+
4. Add tests
|
|
307
|
+
5. Update README
|
|
308
|
+
|
|
309
|
+
## Version
|
|
310
|
+
|
|
311
|
+
Current version: 0.0.1
|
|
312
|
+
|
|
313
|
+
## Authors
|
|
314
|
+
|
|
315
|
+
Skillful AI
|
|
316
|
+
|
|
317
|
+
## Support
|
|
318
|
+
|
|
319
|
+
- **Documentation**: [SKAI Agents Docs](https://docs.skillfulai.io)
|
|
320
|
+
- **Issues**: Report bugs in ActivePieces repository
|
|
321
|
+
- **API Status**: [status.skillfulai.io](https://status.skillfulai.io)
|
|
322
|
+
|
|
323
|
+
## License
|
|
324
|
+
|
|
325
|
+
MIT
|
package/package.json
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@skillful-ai/piece-skai-adapters",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"type": "commonjs",
|
|
5
|
+
"main": "./src/index.js",
|
|
6
|
+
"types": "./src/index.d.ts",
|
|
7
|
+
"dependencies": {
|
|
8
|
+
"@activepieces/pieces-common": "*",
|
|
9
|
+
"@activepieces/pieces-framework": "*",
|
|
10
|
+
"@sinclair/typebox": "0.34.11",
|
|
11
|
+
"@skillful-ai/skai-sdk": "*",
|
|
12
|
+
"axios": "1.8.3",
|
|
13
|
+
"axios-retry": "4.4.1",
|
|
14
|
+
"deepmerge-ts": "7.1.0",
|
|
15
|
+
"fastify": "5.4.0",
|
|
16
|
+
"mime-types": "2.1.35",
|
|
17
|
+
"nanoid": "3.3.8",
|
|
18
|
+
"semver": "7.6.0",
|
|
19
|
+
"tslib": "^2.3.0",
|
|
20
|
+
"zod": "3.25.76",
|
|
21
|
+
"@activepieces/shared": "0.22.0"
|
|
22
|
+
},
|
|
23
|
+
"overrides": {
|
|
24
|
+
"@tryfabric/martian": {
|
|
25
|
+
"@notionhq/client": "$@notionhq/client"
|
|
26
|
+
},
|
|
27
|
+
"vite": {
|
|
28
|
+
"rollup": "npm:@rollup/wasm-node"
|
|
29
|
+
},
|
|
30
|
+
"undici": "6.19.8"
|
|
31
|
+
},
|
|
32
|
+
"resolutions": {
|
|
33
|
+
"rollup": "npm:@rollup/wasm-node",
|
|
34
|
+
"undici": "6.19.8"
|
|
35
|
+
}
|
|
36
|
+
}
|
|
Binary file
|
package/src/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const skaiAdapters: import("@activepieces/pieces-framework").Piece<import("@activepieces/pieces-framework").PieceAuthProperty>;
|
package/src/index.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.skaiAdapters = void 0;
|
|
4
|
+
const pieces_framework_1 = require("@activepieces/pieces-framework");
|
|
5
|
+
const skai_to_whatsapp_1 = require("./lib/actions/skai-to-whatsapp");
|
|
6
|
+
const skai_to_telegram_1 = require("./lib/actions/skai-to-telegram");
|
|
7
|
+
const whatsapp_to_skai_1 = require("./lib/actions/whatsapp-to-skai");
|
|
8
|
+
const telegram_to_skai_1 = require("./lib/actions/telegram-to-skai");
|
|
9
|
+
const skai_response_webhook_1 = require("./lib/triggers/skai-response-webhook");
|
|
10
|
+
exports.skaiAdapters = (0, pieces_framework_1.createPiece)({
|
|
11
|
+
displayName: 'SKAI Adapters',
|
|
12
|
+
description: 'Transform messages between messaging platforms and SKAI Agents',
|
|
13
|
+
auth: pieces_framework_1.PieceAuth.None(),
|
|
14
|
+
minimumSupportedRelease: '0.36.1',
|
|
15
|
+
logoUrl: 'https://cdn.activepieces.com/pieces/skai-adapters.png',
|
|
16
|
+
authors: ['Skillful AI'],
|
|
17
|
+
actions: [
|
|
18
|
+
skai_to_whatsapp_1.skaiToWhatsApp,
|
|
19
|
+
skai_to_telegram_1.skaiToTelegram,
|
|
20
|
+
whatsapp_to_skai_1.whatsappToSkai,
|
|
21
|
+
telegram_to_skai_1.telegramToSkai,
|
|
22
|
+
],
|
|
23
|
+
triggers: [skai_response_webhook_1.skaiResponseWebhook],
|
|
24
|
+
});
|
|
25
|
+
//# sourceMappingURL=index.js.map
|
package/src/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../packages/pieces/custom/skai-adapters/src/index.ts"],"names":[],"mappings":";;;AAAA,qEAAwE;AACxE,qEAAgE;AAChE,qEAAgE;AAChE,qEAAgE;AAChE,qEAAgE;AAChE,gFAA2E;AAE9D,QAAA,YAAY,GAAG,IAAA,8BAAW,EAAC;IACvC,WAAW,EAAE,eAAe;IAC5B,WAAW,EAAE,gEAAgE;IAC7E,IAAI,EAAE,4BAAS,CAAC,IAAI,EAAE;IACtB,uBAAuB,EAAE,QAAQ;IACjC,OAAO,EAAE,uDAAuD;IAChE,OAAO,EAAE,CAAC,aAAa,CAAC;IACxB,OAAO,EAAE;QACR,iCAAc;QACd,iCAAc;QACd,iCAAc;QACd,iCAAc;KACd;IACD,QAAQ,EAAE,CAAC,2CAAmB,CAAC;CAC/B,CAAC,CAAC"}
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.skaiToTelegram = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const pieces_framework_1 = require("@activepieces/pieces-framework");
|
|
6
|
+
// Telegram message length limit
|
|
7
|
+
const MAX_TELEGRAM_MESSAGE_LENGTH = 4096;
|
|
8
|
+
/**
|
|
9
|
+
* Split a long message into chunks respecting Telegram's character limit
|
|
10
|
+
* Tries to split at natural boundaries (paragraphs, sentences, words)
|
|
11
|
+
*/
|
|
12
|
+
function splitMessage(text, maxLength = MAX_TELEGRAM_MESSAGE_LENGTH) {
|
|
13
|
+
if (text.length <= maxLength) {
|
|
14
|
+
return [text];
|
|
15
|
+
}
|
|
16
|
+
const messages = [];
|
|
17
|
+
let remainingText = text;
|
|
18
|
+
while (remainingText.length > 0) {
|
|
19
|
+
if (remainingText.length <= maxLength) {
|
|
20
|
+
messages.push(remainingText);
|
|
21
|
+
break;
|
|
22
|
+
}
|
|
23
|
+
// Try to split at paragraph boundary (\n\n)
|
|
24
|
+
let splitIndex = remainingText.lastIndexOf('\n\n', maxLength);
|
|
25
|
+
// If no paragraph boundary, try sentence boundary (. ! ?)
|
|
26
|
+
if (splitIndex === -1 || splitIndex < maxLength * 0.5) {
|
|
27
|
+
const sentenceEndings = ['. ', '! ', '? ', '.\n', '!\n', '?\n'];
|
|
28
|
+
for (const ending of sentenceEndings) {
|
|
29
|
+
const idx = remainingText.lastIndexOf(ending, maxLength);
|
|
30
|
+
if (idx > splitIndex) {
|
|
31
|
+
splitIndex = idx + ending.length;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
// If no sentence boundary, try word boundary (space)
|
|
36
|
+
if (splitIndex === -1 || splitIndex < maxLength * 0.5) {
|
|
37
|
+
splitIndex = remainingText.lastIndexOf(' ', maxLength);
|
|
38
|
+
}
|
|
39
|
+
// Last resort: hard split at maxLength
|
|
40
|
+
if (splitIndex === -1 || splitIndex < maxLength * 0.5) {
|
|
41
|
+
splitIndex = maxLength;
|
|
42
|
+
}
|
|
43
|
+
messages.push(remainingText.substring(0, splitIndex).trim());
|
|
44
|
+
remainingText = remainingText.substring(splitIndex).trim();
|
|
45
|
+
}
|
|
46
|
+
return messages;
|
|
47
|
+
}
|
|
48
|
+
exports.skaiToTelegram = (0, pieces_framework_1.createAction)({
|
|
49
|
+
name: 'skai_to_telegram',
|
|
50
|
+
displayName: 'SKAI → Telegram',
|
|
51
|
+
description: 'Transform SKAI webhook response to Telegram message format (with auto message splitting)',
|
|
52
|
+
props: {
|
|
53
|
+
webhookPayload: pieces_framework_1.Property.Json({
|
|
54
|
+
displayName: 'SKAI Webhook Payload',
|
|
55
|
+
description: 'Output from SKAI Response Webhook trigger',
|
|
56
|
+
required: true,
|
|
57
|
+
}),
|
|
58
|
+
},
|
|
59
|
+
run(context) {
|
|
60
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
61
|
+
var _a, _b;
|
|
62
|
+
const { webhookPayload } = context.propsValue;
|
|
63
|
+
try {
|
|
64
|
+
// Parse webhook payload
|
|
65
|
+
const payload = webhookPayload;
|
|
66
|
+
// Validate platform
|
|
67
|
+
if (!payload.platform || payload.platform !== 'telegram') {
|
|
68
|
+
throw new Error(`Invalid platform: expected 'telegram', got '${payload.platform || 'undefined'}'`);
|
|
69
|
+
}
|
|
70
|
+
// Validate required fields
|
|
71
|
+
if (!payload.external_id || !payload.message) {
|
|
72
|
+
throw new Error('Missing required fields: external_id or message');
|
|
73
|
+
}
|
|
74
|
+
console.log('Transforming SKAI response to Telegram format');
|
|
75
|
+
console.log('Chat ID:', payload.external_id);
|
|
76
|
+
console.log('Message preview:', ((_a = payload.message) === null || _a === void 0 ? void 0 : _a.substring(0, 50)) + '...');
|
|
77
|
+
console.log('Message length:', ((_b = payload.message) === null || _b === void 0 ? void 0 : _b.length) || 0);
|
|
78
|
+
// Split message if it exceeds Telegram's limit
|
|
79
|
+
const messageParts = splitMessage(payload.message);
|
|
80
|
+
if (messageParts.length > 1) {
|
|
81
|
+
console.log(`Message exceeds ${MAX_TELEGRAM_MESSAGE_LENGTH} chars, split into ${messageParts.length} parts`);
|
|
82
|
+
}
|
|
83
|
+
const telegramMessages = [];
|
|
84
|
+
const hasMedia = payload.media_urls && payload.media_urls.length > 0;
|
|
85
|
+
const hasText = payload.message && payload.message.trim().length > 0;
|
|
86
|
+
// Map generic media types to Telegram-specific fields
|
|
87
|
+
const mediaTypeMapping = {
|
|
88
|
+
'image': 'photo',
|
|
89
|
+
'photo': 'photo',
|
|
90
|
+
'video': 'video',
|
|
91
|
+
'audio': 'audio',
|
|
92
|
+
'voice': 'voice',
|
|
93
|
+
'document': 'document',
|
|
94
|
+
'file': 'document',
|
|
95
|
+
};
|
|
96
|
+
// Handle media URLs
|
|
97
|
+
if (hasMedia) {
|
|
98
|
+
const mediaUrls = payload.media_urls;
|
|
99
|
+
const mediaTypes = payload.media_types || [];
|
|
100
|
+
console.log(`Processing ${mediaUrls.length} media item(s)`);
|
|
101
|
+
// If text exists, combine first text part with first media
|
|
102
|
+
if (hasText && messageParts.length > 0) {
|
|
103
|
+
const firstMediaUrl = mediaUrls[0];
|
|
104
|
+
const firstMediaTypeRaw = mediaTypes.length > 0
|
|
105
|
+
? mediaTypes[0].toLowerCase()
|
|
106
|
+
: 'photo';
|
|
107
|
+
const firstMediaType = mediaTypeMapping[firstMediaTypeRaw] || 'document';
|
|
108
|
+
console.log('First message: text + media 0 (', firstMediaType, '-', firstMediaUrl, ')');
|
|
109
|
+
// First message: text + first media
|
|
110
|
+
telegramMessages.push({
|
|
111
|
+
chatId: payload.external_id,
|
|
112
|
+
text: messageParts[0],
|
|
113
|
+
mediaUrl: firstMediaUrl,
|
|
114
|
+
mediaType: firstMediaType,
|
|
115
|
+
reference_id: payload.reference_id,
|
|
116
|
+
partNumber: 1,
|
|
117
|
+
totalParts: messageParts.length + mediaUrls.length - 1,
|
|
118
|
+
});
|
|
119
|
+
// Remaining text parts (if any) as separate text messages
|
|
120
|
+
for (let i = 1; i < messageParts.length; i++) {
|
|
121
|
+
telegramMessages.push({
|
|
122
|
+
chatId: payload.external_id,
|
|
123
|
+
text: messageParts[i],
|
|
124
|
+
reference_id: payload.reference_id,
|
|
125
|
+
partNumber: i + 1,
|
|
126
|
+
totalParts: messageParts.length + mediaUrls.length - 1,
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
// Remaining media items as separate media-only messages
|
|
130
|
+
for (let i = 1; i < mediaUrls.length; i++) {
|
|
131
|
+
const mediaTypeRaw = mediaTypes.length > i
|
|
132
|
+
? mediaTypes[i].toLowerCase()
|
|
133
|
+
: 'photo';
|
|
134
|
+
const mediaType = mediaTypeMapping[mediaTypeRaw] || 'document';
|
|
135
|
+
console.log(`Media ${i}:`, mediaType, '-', mediaUrls[i]);
|
|
136
|
+
telegramMessages.push({
|
|
137
|
+
chatId: payload.external_id,
|
|
138
|
+
mediaUrl: mediaUrls[i],
|
|
139
|
+
mediaType: mediaType,
|
|
140
|
+
reference_id: payload.reference_id,
|
|
141
|
+
partNumber: messageParts.length + i,
|
|
142
|
+
totalParts: messageParts.length + mediaUrls.length - 1,
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
// No text, send all media as separate messages
|
|
148
|
+
for (let i = 0; i < mediaUrls.length; i++) {
|
|
149
|
+
const mediaTypeRaw = mediaTypes.length > i
|
|
150
|
+
? mediaTypes[i].toLowerCase()
|
|
151
|
+
: 'photo';
|
|
152
|
+
const mediaType = mediaTypeMapping[mediaTypeRaw] || 'document';
|
|
153
|
+
console.log(`Media ${i}:`, mediaType, '-', mediaUrls[i]);
|
|
154
|
+
telegramMessages.push({
|
|
155
|
+
chatId: payload.external_id,
|
|
156
|
+
mediaUrl: mediaUrls[i],
|
|
157
|
+
mediaType: mediaType,
|
|
158
|
+
reference_id: payload.reference_id,
|
|
159
|
+
partNumber: i + 1,
|
|
160
|
+
totalParts: mediaUrls.length,
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
// No media, just text messages
|
|
167
|
+
telegramMessages.push(...messageParts.map((part, index) => ({
|
|
168
|
+
chatId: payload.external_id,
|
|
169
|
+
text: part,
|
|
170
|
+
reference_id: payload.reference_id,
|
|
171
|
+
partNumber: index + 1,
|
|
172
|
+
totalParts: messageParts.length,
|
|
173
|
+
})));
|
|
174
|
+
}
|
|
175
|
+
console.log(`Message formatted for Telegram: ${telegramMessages.length} message(s) to send`);
|
|
176
|
+
// Return all message parts (array if split, single item array if not)
|
|
177
|
+
return {
|
|
178
|
+
messages: telegramMessages,
|
|
179
|
+
requiresMultipleSends: telegramMessages.length > 1,
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
catch (error) {
|
|
183
|
+
console.error('Error in SKAI → Telegram:', error);
|
|
184
|
+
return {
|
|
185
|
+
success: false,
|
|
186
|
+
error: error.message || 'Failed to transform SKAI response to Telegram format',
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
},
|
|
191
|
+
});
|
|
192
|
+
//# sourceMappingURL=skai-to-telegram.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skai-to-telegram.js","sourceRoot":"","sources":["../../../../../../../../packages/pieces/custom/skai-adapters/src/lib/actions/skai-to-telegram.ts"],"names":[],"mappings":"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"}
|