@hiliosai/sdk 0.1.2 → 0.1.4

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.
@@ -9,7 +9,7 @@ Integration Services are specialized Moleculer services that provide a standardi
9
9
  The Integration Service pattern solves several key challenges:
10
10
 
11
11
  1. **Platform Abstraction**: Provides unified interface for different messaging platforms
12
- 2. **Webhook Security**: Implements signature validation and replay attack prevention
12
+ 2. **Webhook Security**: Implements signature validation and replay attack prevention
13
13
  3. **Message Normalization**: Converts platform-specific messages to unified format
14
14
  4. **Retry Logic**: Handles transient failures with exponential backoff
15
15
  5. **Event Broadcasting**: Emits standardized events for message processing
@@ -25,15 +25,15 @@ graph TB
25
25
  DC[Discord]
26
26
  SL[Slack]
27
27
  end
28
-
28
+
29
29
  subgraph "Integration Layer"
30
30
  subgraph "Integration Services"
31
31
  WAS[WhatsApp Service]
32
- TGS[Telegram Service]
32
+ TGS[Telegram Service]
33
33
  DCS[Discord Service]
34
34
  SLS[Slack Service]
35
35
  end
36
-
36
+
37
37
  subgraph "Service Actions"
38
38
  RW[i_receiveWebhook]
39
39
  SM[i_sendMessage]
@@ -43,20 +43,20 @@ graph TB
43
43
  VC[i_validateCredentials]
44
44
  end
45
45
  end
46
-
46
+
47
47
  subgraph "Core Application"
48
48
  subgraph "Message Processing"
49
49
  MP[Message Processor]
50
50
  MR[Message Router]
51
51
  MS[Message Store]
52
52
  end
53
-
53
+
54
54
  subgraph "Event System"
55
55
  EB[Event Bus]
56
56
  EH[Event Handlers]
57
57
  end
58
58
  end
59
-
59
+
60
60
  subgraph "Infrastructure"
61
61
  DS[Datasources]
62
62
  CA[Cache]
@@ -69,29 +69,29 @@ graph TB
69
69
  TG -->|Webhook| TGS
70
70
  DC -->|Webhook| DCS
71
71
  SL -->|Webhook| SLS
72
-
72
+
73
73
  %% Integration service actions
74
74
  WAS --> RW
75
75
  WAS --> SM
76
76
  WAS --> HC
77
-
77
+
78
78
  %% Service infrastructure
79
79
  WAS --> DS
80
80
  TGS --> CA
81
81
  DCS --> PE
82
82
  SLS --> CH
83
-
83
+
84
84
  %% Event flows
85
85
  RW -->|integration.message.received| EB
86
86
  SM -->|integration.message.sent| EB
87
87
  SM -->|integration.message.failed| EB
88
-
88
+
89
89
  %% Processing flows
90
90
  EB --> EH
91
91
  EH --> MP
92
92
  MP --> MR
93
93
  MR --> MS
94
-
94
+
95
95
  %% Response flows
96
96
  MP -->|Send Response| SM
97
97
  ```
@@ -109,29 +109,29 @@ graph TB
109
109
 
110
110
  All integration services automatically get these actions:
111
111
 
112
- | Action | REST Endpoint | Purpose |
113
- |--------|---------------|---------|
114
- | `i_receiveWebhook` | `POST /webhook` | Receive and process incoming webhooks |
115
- | `i_sendMessage` | `POST /send` | Send messages to external platform |
116
- | `i_healthCheck` | `GET /health` | Check integration health status |
117
- | `i_verifyWebhook` | `GET /webhook` | Verify webhook subscriptions |
118
- | `i_status` | `GET /status` | Get integration status information |
119
- | `i_validateCredentials` | `POST /validate` | Validate platform credentials |
112
+ | Action | REST Endpoint | Purpose |
113
+ | ----------------------- | ---------------- | ------------------------------------- |
114
+ | `i_receiveWebhook` | `POST /webhook` | Receive and process incoming webhooks |
115
+ | `i_sendMessage` | `POST /send` | Send messages to external platform |
116
+ | `i_healthCheck` | `GET /health` | Check integration health status |
117
+ | `i_verifyWebhook` | `GET /webhook` | Verify webhook subscriptions |
118
+ | `i_status` | `GET /status` | Get integration status information |
119
+ | `i_validateCredentials` | `POST /validate` | Validate platform credentials |
120
120
 
121
121
  ### Service Methods
122
122
 
123
123
  Integration-specific logic is implemented as service methods:
124
124
 
125
- | Method | Purpose | Required |
126
- |--------|---------|----------|
127
- | `normalize()` | Convert platform message to unified format | ✅ |
128
- | `sendMessage()` | Send message to platform | ✅ |
129
- | `transform()` | Transform outbound message to platform format | ❌ |
130
- | `validateWebhook()` | Validate webhook payload structure | ❌ |
131
- | `validateSignature()` | Validate webhook signature | ❌ |
132
- | `verifyWebhook()` | Handle webhook verification challenge | ❌ |
133
- | `checkHealth()` | Custom health check logic | ❌ |
134
- | `validateCredentials()` | Validate platform credentials | ❌ |
125
+ | Method | Purpose | Required |
126
+ | ----------------------- | --------------------------------------------- | -------- |
127
+ | `normalize()` | Convert platform message to unified format | ✅ |
128
+ | `sendMessage()` | Send message to platform | ✅ |
129
+ | `transform()` | Transform outbound message to platform format | ❌ |
130
+ | `validateWebhook()` | Validate webhook payload structure | ❌ |
131
+ | `validateSignature()` | Validate webhook signature | ❌ |
132
+ | `verifyWebhook()` | Handle webhook verification challenge | ❌ |
133
+ | `checkHealth()` | Custom health check logic | ❌ |
134
+ | `validateCredentials()` | Validate platform credentials | ❌ |
135
135
 
136
136
  ## Usage Example
137
137
 
@@ -139,9 +139,9 @@ Integration-specific logic is implemented as service methods:
139
139
 
140
140
  ```typescript
141
141
  import {defineIntegration} from '@pkg/sdk';
142
- import type {BaseIntegration, NormalizedMessage, WebhookEvent} from '@pkg/sdk';
142
+ import type {BaseSpec, NormalizedMessage, WebhookEvent} from '@pkg/sdk';
143
143
 
144
- const whatsappIntegration: BaseIntegration = {
144
+ const whatsappIntegration: BaseSpec = {
145
145
  id: 'whatsapp-business',
146
146
  name: 'WhatsApp Business',
147
147
  platform: 'whatsapp',
@@ -152,13 +152,13 @@ const whatsappIntegration: BaseIntegration = {
152
152
 
153
153
  export default defineIntegration({
154
154
  name: 'whatsapp',
155
- integration: whatsappIntegration,
156
-
155
+ spec: whatsappIntegration,
156
+
157
157
  // Required: Convert WhatsApp webhook to normalized message
158
158
  async normalize(webhook: WebhookEvent): Promise<NormalizedMessage[]> {
159
159
  const messages: NormalizedMessage[] = [];
160
-
161
- for (const entry of webhook.rawPayload.entry || []) {
160
+
161
+ for (const entry of webhook.payload.entry || []) {
162
162
  for (const change of entry.changes || []) {
163
163
  if (change.field === 'messages') {
164
164
  for (const message of change.value.messages || []) {
@@ -190,7 +190,7 @@ export default defineIntegration({
190
190
  }
191
191
  }
192
192
  }
193
-
193
+
194
194
  return messages;
195
195
  },
196
196
 
@@ -198,7 +198,7 @@ export default defineIntegration({
198
198
  async sendMessage(ctx, message, config) {
199
199
  const phoneNumberId = config.credentials.phoneNumberId;
200
200
  const accessToken = config.credentials.accessToken;
201
-
201
+
202
202
  const response = await fetch(
203
203
  `https://graph.facebook.com/v18.0/${phoneNumberId}/messages`,
204
204
  {
@@ -235,14 +235,14 @@ export default defineIntegration({
235
235
  validateSignature(webhook) {
236
236
  const signature = webhook.headers['x-hub-signature-256'];
237
237
  const secret = process.env.WHATSAPP_WEBHOOK_SECRET;
238
-
238
+
239
239
  if (!signature || !secret) return false;
240
-
241
- const expectedSignature = 'sha256=' +
240
+
241
+ const expectedSignature = 'sha256=' +
242
242
  crypto.createHmac('sha256', secret)
243
243
  .update(webhook.rawBody || '')
244
244
  .digest('hex');
245
-
245
+
246
246
  return SecurityHelpers.secureCompare(signature, expectedSignature);
247
247
  },
248
248
 
@@ -250,7 +250,7 @@ export default defineIntegration({
250
250
  verifyWebhook(params) {
251
251
  const { mode, token, challenge } = params;
252
252
  const verifyToken = process.env.WHATSAPP_VERIFY_TOKEN;
253
-
253
+
254
254
  if (mode === 'subscribe' && token === verifyToken) {
255
255
  return challenge;
256
256
  }
@@ -268,7 +268,7 @@ export default defineIntegration({
268
268
  }
269
269
  }
270
270
  );
271
-
271
+
272
272
  return {
273
273
  status: response.ok ? 'healthy' : 'unhealthy',
274
274
  message: response.ok ? 'WhatsApp API accessible' : 'WhatsApp API error',
@@ -296,13 +296,13 @@ import {WhatsAppDatasource} from './datasources';
296
296
 
297
297
  export default defineIntegration({
298
298
  name: 'whatsapp',
299
- integration: whatsappIntegration,
300
-
299
+ spec: whatsappIntegration,
300
+
301
301
  // Configure per-service datasources
302
302
  datasources: {
303
303
  whatsapp: WhatsAppDatasource
304
304
  },
305
-
305
+
306
306
  // Configure per-service cache
307
307
  cache: {
308
308
  redisUrl: process.env.WHATSAPP_REDIS_URL,
@@ -321,20 +321,20 @@ export default defineIntegration({
321
321
  // Use cache for rate limiting
322
322
  const rateLimitKey = `rate_limit:${config.credentials.phoneNumberId}`;
323
323
  const currentCount = await ctx.cache.get(rateLimitKey) || 0;
324
-
324
+
325
325
  if (currentCount >= 1000) {
326
326
  return {
327
327
  success: false,
328
328
  error: new Error('Rate limit exceeded')
329
329
  };
330
330
  }
331
-
331
+
332
332
  // Send message...
333
333
  const result = await this.sendToWhatsApp(message, config);
334
-
334
+
335
335
  // Update rate limit counter
336
336
  await ctx.cache.set(rateLimitKey, currentCount + 1, 60 * 60 * 1000);
337
-
337
+
338
338
  return result;
339
339
  }
340
340
  });
@@ -345,7 +345,7 @@ export default defineIntegration({
345
345
  ### Inbound Message Flow
346
346
 
347
347
  1. **Webhook Received** → `i_receiveWebhook` action
348
- 2. **Security Validation** → Timestamp, signature, payload checks
348
+ 2. **Security Validation** → Timestamp, signature, payload checks
349
349
  3. **Message Normalization** → Convert to unified format
350
350
  4. **Event Emission** → `integration.message.received` event
351
351
  5. **Message Processing** → Application-specific logic
@@ -391,4 +391,4 @@ Integration services automatically inherit:
391
391
  - **Health Monitoring**: Automated health checks
392
392
  - **Event System**: Pub/sub event broadcasting
393
393
 
394
- This architecture provides a robust, scalable foundation for building messaging platform integrations while maintaining consistency, security, and observability across all platforms.
394
+ This architecture provides a robust, scalable foundation for building messaging platform integrations while maintaining consistency, security, and observability across all platforms.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hiliosai/sdk",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": "./src/index.ts"
@@ -91,15 +91,11 @@ export function defineIntegration<
91
91
  i_receiveWebhook: {
92
92
  rest: {
93
93
  method: 'POST' as const,
94
- path: '/webhook',
94
+ path: '/:tenantId',
95
95
  },
96
96
  params: {
97
97
  tenantId: 'string',
98
- channelId: 'string',
99
- integrationId: 'string',
100
- platform: 'string',
101
- rawPayload: 'any',
102
- rawBody: {type: 'string', optional: true},
98
+ payload: 'object',
103
99
  headers: 'object',
104
100
  timestamp: 'number',
105
101
  },
@@ -181,20 +177,20 @@ export function defineIntegration<
181
177
  () => config.sendMessage(ctx, message, integrationConfig),
182
178
  3,
183
179
  1000,
184
- `Send message via ${config.integration.platform}`
180
+ `Send message via ${config.spec.platform}`
185
181
  );
186
182
 
187
183
  // Emit event based on result
188
184
  if (result.success) {
189
185
  ctx.emit('integration.message.sent', {
190
186
  messageId: result.messageId,
191
- platform: config.integration.platform,
187
+ platform: config.spec.platform,
192
188
  metadata: result.metadata,
193
189
  });
194
190
  } else {
195
191
  ctx.emit('integration.message.failed', {
196
192
  error: result.error,
197
- platform: config.integration.platform,
193
+ platform: config.spec.platform,
198
194
  message,
199
195
  });
200
196
  }
@@ -224,12 +220,12 @@ export function defineIntegration<
224
220
 
225
221
  return {
226
222
  status: 'healthy',
227
- message: `${config.integration.name} integration is running`,
223
+ message: `${config.spec.name} integration is running`,
228
224
  details: {
229
- integration: config.integration.id,
230
- version: config.integration.version,
225
+ id: config.spec.id,
226
+ version: config.spec.version,
231
227
  timestamp: new Date().toISOString(),
232
- capabilities: config.integration.capabilities,
228
+ capabilities: config.spec.capabilities,
233
229
  },
234
230
  };
235
231
  } catch (error: unknown) {
@@ -238,7 +234,7 @@ export function defineIntegration<
238
234
  status: 'unhealthy',
239
235
  message: err.message,
240
236
  details: {
241
- integration: config.integration.id,
237
+ id: config.spec.id,
242
238
  timestamp: new Date().toISOString(),
243
239
  },
244
240
  };
@@ -249,9 +245,10 @@ export function defineIntegration<
249
245
  i_verifyWebhook: {
250
246
  rest: {
251
247
  method: 'GET' as const,
252
- path: '/webhook',
248
+ path: '/:tenantId',
253
249
  },
254
250
  params: {
251
+ tenantId: 'string',
255
252
  mode: 'string',
256
253
  token: 'string',
257
254
  challenge: 'string',
@@ -259,7 +256,7 @@ export function defineIntegration<
259
256
  handler(
260
257
  ctx: AppContext<
261
258
  TDatasources,
262
- {mode: string; token: string; challenge: string}
259
+ {tenantId: string; mode: string; token: string; challenge: string}
263
260
  >
264
261
  ): string {
265
262
  if (config.verifyWebhook) {
@@ -277,12 +274,12 @@ export function defineIntegration<
277
274
  },
278
275
  handler(): object {
279
276
  return {
280
- id: config.integration.id,
281
- name: config.integration.name,
282
- platform: config.integration.platform,
283
- version: config.integration.version,
284
- status: config.integration.status,
285
- capabilities: config.integration.capabilities,
277
+ id: config.spec.id,
278
+ name: config.spec.name,
279
+ platform: config.spec.platform,
280
+ version: config.spec.version,
281
+ status: config.spec.status,
282
+ capabilities: config.spec.capabilities,
286
283
  };
287
284
  },
288
285
  },
@@ -316,7 +313,7 @@ export function defineIntegration<
316
313
  datasources: config.datasources,
317
314
  metadata: {
318
315
  ...config.metadata,
319
- integration: config.integration,
316
+ spec: config.spec,
320
317
  },
321
318
  actions,
322
319
  events: config.events ?? {},
@@ -338,7 +335,6 @@ export function defineIntegration<
338
335
  validateSignature: config.validateSignature,
339
336
  }),
340
337
  },
341
- hooks: config.hooks ?? {},
342
338
  created: config.created,
343
339
  started: config.started,
344
340
  stopped: config.stopped,
@@ -347,7 +343,7 @@ export function defineIntegration<
347
343
  // Return the service schema - integration methods are available via service methods
348
344
  return {
349
345
  ...baseService,
350
- // Only add the integration metadata
351
- integration: config.integration,
346
+ // Only add the integration spec
347
+ spec: config.spec,
352
348
  } as IntegrationServiceSchema<TPlatformMessage, TSettings>;
353
349
  }
@@ -5,7 +5,7 @@ import type {
5
5
  IntegrationStatus,
6
6
  } from './platform';
7
7
 
8
- export interface BaseIntegration {
8
+ export interface BaseSpec {
9
9
  id: string;
10
10
  name: string;
11
11
  platform: IntegrationPlatform;
@@ -74,7 +74,7 @@ export interface NormalizedMessage {
74
74
 
75
75
  export interface PlatformMessage {
76
76
  platform: IntegrationPlatform;
77
- rawPayload: any;
77
+ payload: any;
78
78
  }
79
79
 
80
80
  export interface WebhookEvent {
@@ -82,8 +82,7 @@ export interface WebhookEvent {
82
82
  channelId: string;
83
83
  integrationId: string;
84
84
  platform: IntegrationPlatform;
85
- rawPayload: any;
86
- rawBody?: string;
85
+ payload: any;
87
86
  headers: Record<string, string>;
88
87
  timestamp: number;
89
88
  }
@@ -9,7 +9,7 @@ import type {
9
9
 
10
10
  import type {DatasourceConstructorRegistry} from '../middlewares/datasource.middleware';
11
11
  import type {AppContext} from './context';
12
- import type {BaseIntegration, IntegrationConfig} from './integration';
12
+ import type {BaseSpec, IntegrationConfig} from './integration';
13
13
  import type {
14
14
  NormalizedMessage,
15
15
  PlatformMessage,
@@ -134,7 +134,7 @@ export interface IntegrationServiceConfig<
134
134
  TDatasources = unknown
135
135
  > extends ServiceConfig<TSettings, TDatasources> {
136
136
  name: string;
137
- integration: BaseIntegration;
137
+ spec: BaseSpec;
138
138
 
139
139
  // Core integration methods
140
140
  normalize(webhook: WebhookEvent): Promise<NormalizedMessage[]>;
@@ -177,7 +177,7 @@ export interface IntegrationServiceSchema<
177
177
  TPlatformMessage extends PlatformMessage = PlatformMessage,
178
178
  TSettings = unknown
179
179
  > extends MoleculerServiceSchema<TSettings> {
180
- integration: BaseIntegration;
180
+ spec: BaseSpec;
181
181
  normalize(webhook: WebhookEvent): Promise<NormalizedMessage[]>;
182
182
  transform?(
183
183
  message: NormalizedMessage,