autotel-subscribers 4.0.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.
Files changed (87) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +669 -0
  3. package/dist/amplitude.cjs +2486 -0
  4. package/dist/amplitude.cjs.map +1 -0
  5. package/dist/amplitude.d.cts +49 -0
  6. package/dist/amplitude.d.ts +49 -0
  7. package/dist/amplitude.js +2463 -0
  8. package/dist/amplitude.js.map +1 -0
  9. package/dist/event-subscriber-base-CnF3V56W.d.cts +182 -0
  10. package/dist/event-subscriber-base-CnF3V56W.d.ts +182 -0
  11. package/dist/factories.cjs +16660 -0
  12. package/dist/factories.cjs.map +1 -0
  13. package/dist/factories.d.cts +304 -0
  14. package/dist/factories.d.ts +304 -0
  15. package/dist/factories.js +16624 -0
  16. package/dist/factories.js.map +1 -0
  17. package/dist/index.cjs +16575 -0
  18. package/dist/index.cjs.map +1 -0
  19. package/dist/index.d.cts +179 -0
  20. package/dist/index.d.ts +179 -0
  21. package/dist/index.js +16539 -0
  22. package/dist/index.js.map +1 -0
  23. package/dist/middleware.cjs +220 -0
  24. package/dist/middleware.cjs.map +1 -0
  25. package/dist/middleware.d.cts +227 -0
  26. package/dist/middleware.d.ts +227 -0
  27. package/dist/middleware.js +208 -0
  28. package/dist/middleware.js.map +1 -0
  29. package/dist/mixpanel.cjs +2940 -0
  30. package/dist/mixpanel.cjs.map +1 -0
  31. package/dist/mixpanel.d.cts +47 -0
  32. package/dist/mixpanel.d.ts +47 -0
  33. package/dist/mixpanel.js +2932 -0
  34. package/dist/mixpanel.js.map +1 -0
  35. package/dist/posthog.cjs +4115 -0
  36. package/dist/posthog.cjs.map +1 -0
  37. package/dist/posthog.d.cts +299 -0
  38. package/dist/posthog.d.ts +299 -0
  39. package/dist/posthog.js +4113 -0
  40. package/dist/posthog.js.map +1 -0
  41. package/dist/segment.cjs +6822 -0
  42. package/dist/segment.cjs.map +1 -0
  43. package/dist/segment.d.cts +49 -0
  44. package/dist/segment.d.ts +49 -0
  45. package/dist/segment.js +6794 -0
  46. package/dist/segment.js.map +1 -0
  47. package/dist/slack.cjs +368 -0
  48. package/dist/slack.cjs.map +1 -0
  49. package/dist/slack.d.cts +126 -0
  50. package/dist/slack.d.ts +126 -0
  51. package/dist/slack.js +366 -0
  52. package/dist/slack.js.map +1 -0
  53. package/dist/webhook.cjs +100 -0
  54. package/dist/webhook.cjs.map +1 -0
  55. package/dist/webhook.d.cts +53 -0
  56. package/dist/webhook.d.ts +53 -0
  57. package/dist/webhook.js +98 -0
  58. package/dist/webhook.js.map +1 -0
  59. package/examples/quickstart-custom-subscriber.ts +144 -0
  60. package/examples/subscriber-bigquery.ts +219 -0
  61. package/examples/subscriber-databricks.ts +280 -0
  62. package/examples/subscriber-kafka.ts +326 -0
  63. package/examples/subscriber-kinesis.ts +307 -0
  64. package/examples/subscriber-posthog.ts +421 -0
  65. package/examples/subscriber-pubsub.ts +336 -0
  66. package/examples/subscriber-snowflake.ts +232 -0
  67. package/package.json +141 -0
  68. package/src/amplitude.test.ts +231 -0
  69. package/src/amplitude.ts +148 -0
  70. package/src/event-subscriber-base.ts +325 -0
  71. package/src/factories.ts +197 -0
  72. package/src/index.ts +50 -0
  73. package/src/middleware.ts +489 -0
  74. package/src/mixpanel.test.ts +194 -0
  75. package/src/mixpanel.ts +134 -0
  76. package/src/mock-event-subscriber.ts +333 -0
  77. package/src/posthog.test.ts +629 -0
  78. package/src/posthog.ts +530 -0
  79. package/src/segment.test.ts +228 -0
  80. package/src/segment.ts +148 -0
  81. package/src/slack.ts +383 -0
  82. package/src/streaming-event-subscriber.ts +323 -0
  83. package/src/testing/index.ts +37 -0
  84. package/src/testing/mock-webhook-server.ts +242 -0
  85. package/src/testing/subscriber-test-harness.ts +365 -0
  86. package/src/webhook.test.ts +264 -0
  87. package/src/webhook.ts +158 -0
@@ -0,0 +1,421 @@
1
+ /**
2
+ * PostHog Subscriber - Complete Feature Showcase
3
+ *
4
+ * This example demonstrates all PostHog subscriber capabilities:
5
+ * - Basic event tracking
6
+ * - Feature flags and A/B testing
7
+ * - Person and group events (B2B SaaS)
8
+ * - Serverless configuration
9
+ * - Custom client injection
10
+ * - Error handling
11
+ *
12
+ * Install dependencies:
13
+ * ```bash
14
+ * pnpm add autotel autotel-subscribers posthog-node
15
+ * ```
16
+ */
17
+
18
+ import { Events } from 'autotel/events';
19
+ import { PostHogSubscriber } from 'autotel-subscribers/posthog';
20
+ import { PostHog } from 'posthog-node';
21
+
22
+ // ============================================================================
23
+ // Example 1: Basic Event Tracking
24
+ // ============================================================================
25
+
26
+ async function basicEventTracking() {
27
+ const events = new Events('my-app', {
28
+ subscribers: [
29
+ new PostHogSubscriber({
30
+ apiKey: process.env.POSTHOG_API_KEY!,
31
+ host: 'https://us.i.posthog.com', // or 'https://eu.i.posthog.com' for EU cloud
32
+ }),
33
+ ],
34
+ });
35
+
36
+ // Track events
37
+ events.trackEvent('user.signed_up', {
38
+ userId: 'user-123',
39
+ plan: 'premium',
40
+ source: 'landing_page',
41
+ });
42
+
43
+ // Track funnel steps
44
+ events.trackFunnelStep('checkout', 'started', {
45
+ userId: 'user-123',
46
+ cartValue: 99.99,
47
+ });
48
+
49
+ events.trackFunnelStep('checkout', 'completed', {
50
+ userId: 'user-123',
51
+ orderId: 'order-456',
52
+ });
53
+
54
+ // Track outcomes
55
+ events.trackOutcome('payment.processing', 'success', {
56
+ userId: 'user-123',
57
+ amount: 99.99,
58
+ });
59
+
60
+ // Track values/metrics
61
+ events.trackValue('revenue', 99.99, {
62
+ userId: 'user-123',
63
+ currency: 'USD',
64
+ });
65
+
66
+ await events.shutdown();
67
+ }
68
+
69
+ // ============================================================================
70
+ // Example 2: Feature Flags and A/B Testing
71
+ // ============================================================================
72
+
73
+ async function featureFlagsExample() {
74
+ const _subscriber = new PostHogSubscriber({
75
+ apiKey: process.env.POSTHOG_API_KEY!,
76
+ });
77
+
78
+ const userId = 'user-123';
79
+
80
+ // Check if a feature is enabled (boolean)
81
+ const hasNewCheckout = await subscriber.isFeatureEnabled('new-checkout', userId);
82
+
83
+ if (hasNewCheckout) {
84
+ console.log('Show new checkout UI');
85
+ } else {
86
+ console.log('Show old checkout UI');
87
+ }
88
+
89
+ // Get feature flag value (for multivariate tests)
90
+ const experimentVariant = await subscriber.getFeatureFlag('pricing-experiment', userId);
91
+
92
+ switch (experimentVariant) {
93
+ case 'control': {
94
+ console.log('Show $99/month price');
95
+ break;
96
+ }
97
+ case 'test-1': {
98
+ console.log('Show $89/month price');
99
+ break;
100
+ }
101
+ case 'test-2': {
102
+ console.log('Show $79/month price');
103
+ break;
104
+ }
105
+ default: {
106
+ console.log('User not in experiment');
107
+ }
108
+ }
109
+
110
+ // Get all flags for a user (useful for client-side rendering)
111
+ const allFlags = await subscriber.getAllFlags(userId);
112
+ console.log('All feature flags:', allFlags);
113
+ // { 'new-checkout': true, 'pricing-experiment': 'test-1', ... }
114
+
115
+ // Feature flags with person properties
116
+ const isPremiumFeatureEnabled = await subscriber.getFeatureFlag('premium-events', userId, {
117
+ personProperties: {
118
+ plan: 'premium',
119
+ signupDate: '2025-01-01',
120
+ },
121
+ });
122
+ console.log('Premium events enabled:', isPremiumFeatureEnabled);
123
+
124
+ // Feature flags with group context (for B2B features)
125
+ const isBetaEnabled = await subscriber.isFeatureEnabled('beta-features', userId, {
126
+ groups: { company: 'acme-corp' },
127
+ groupProperties: {
128
+ company: {
129
+ plan: 'enterprise',
130
+ employees: 500,
131
+ },
132
+ },
133
+ });
134
+ console.log('Beta features enabled:', isBetaEnabled);
135
+
136
+ // Reload feature flags from server (without restarting)
137
+ await subscriber.reloadFeatureFlags();
138
+
139
+ await subscriber.shutdown();
140
+ }
141
+
142
+ // ============================================================================
143
+ // Example 3: Person and Group Events (B2B SaaS)
144
+ // ============================================================================
145
+
146
+ async function personAndGroupEvents() {
147
+ const _subscriber = new PostHogSubscriber({
148
+ apiKey: process.env.POSTHOG_API_KEY!,
149
+ });
150
+
151
+ // Identify a user and set their properties
152
+ await subscriber.identify('user-123', {
153
+ $set: {
154
+ email: 'user@acme-corp.com',
155
+ name: 'John Doe',
156
+ plan: 'premium',
157
+ company: 'Acme Corporation',
158
+ },
159
+ });
160
+
161
+ // Set properties only once (won't update if already exists)
162
+ await subscriber.identify('user-123', {
163
+ $set_once: {
164
+ signup_date: '2025-01-17',
165
+ first_utm_source: 'google',
166
+ },
167
+ });
168
+
169
+ // Identify a group (e.g., company/organization)
170
+ await subscriber.groupIdentify('company', 'acme-corp', {
171
+ $set: {
172
+ name: 'Acme Corporation',
173
+ industry: 'SaaS',
174
+ employees: 500,
175
+ plan: 'enterprise',
176
+ mrr: 50_000,
177
+ },
178
+ });
179
+
180
+ // Track events with group context
181
+ await subscriber.trackEventWithGroups(
182
+ 'feature.used',
183
+ {
184
+ userId: 'user-123',
185
+ feature: 'advanced-events',
186
+ },
187
+ {
188
+ company: 'acme-corp',
189
+ team: 'engineering',
190
+ },
191
+ );
192
+
193
+ // This allows you to:
194
+ // 1. Analyze usage by company/team in PostHog
195
+ // 2. Enable features for specific companies
196
+ // 3. Track company-level metrics
197
+
198
+ await subscriber.shutdown();
199
+ }
200
+
201
+ // ============================================================================
202
+ // Example 4: Serverless Configuration (AWS Lambda, Vercel, Cloudflare)
203
+ // ============================================================================
204
+
205
+ async function serverlessConfiguration() {
206
+ // For serverless environments, optimize for immediate sending
207
+ const _subscriber = new PostHogSubscriber({
208
+ apiKey: process.env.POSTHOG_API_KEY!,
209
+
210
+ // Send events immediately (don't batch)
211
+ flushAt: 1,
212
+
213
+ // Disable interval-based flushing
214
+ flushInterval: 0,
215
+
216
+ // Reduce request timeout for faster function execution
217
+ requestTimeout: 3000,
218
+
219
+ // Disable geoip lookup to reduce request size
220
+ disableGeoip: true,
221
+ });
222
+
223
+ // In a Lambda handler:
224
+ // exports.handler = async (event) => {
225
+ // const events = new Events('my-lambda', {
226
+ // subscribers: [adapter]
227
+ // });
228
+ //
229
+ // events.trackEvent('lambda.invoked', { userId: event.userId });
230
+ //
231
+ // // IMPORTANT: Always call shutdown in serverless!
232
+ // // This ensures events are flushed before function terminates
233
+ // await events.shutdown();
234
+ //
235
+ // return { statusCode: 200 };
236
+ // }
237
+
238
+ await subscriber.shutdown();
239
+ }
240
+
241
+ // ============================================================================
242
+ // Example 5: Custom PostHog Client
243
+ // ============================================================================
244
+
245
+ async function customClientExample() {
246
+ // Create your own PostHog client with custom configuration
247
+ const customClient = new PostHog(process.env.POSTHOG_API_KEY!, {
248
+ host: 'https://eu.i.posthog.com',
249
+ flushAt: 10,
250
+ flushInterval: 5000,
251
+ requestTimeout: 10_000,
252
+ // Any other PostHog client options...
253
+ });
254
+
255
+ // Pass the custom client to the subscriber
256
+ const _subscriber = new PostHogSubscriber({
257
+ client: customClient,
258
+ });
259
+
260
+ // Now you can use the subscriber with your custom client configuration
261
+ const events = new Events('my-app', {
262
+ subscribers: [adapter],
263
+ });
264
+
265
+ events.trackEvent('custom.event', { userId: 'user-123' });
266
+
267
+ await events.shutdown();
268
+ }
269
+
270
+ // ============================================================================
271
+ // Example 6: Error Handling and Debugging
272
+ // ============================================================================
273
+
274
+ async function errorHandlingExample() {
275
+ const _subscriber = new PostHogSubscriber({
276
+ apiKey: process.env.POSTHOG_API_KEY!,
277
+
278
+ // Enable debug logging
279
+ debug: true,
280
+
281
+ // Custom error handler
282
+ onError: (error) => {
283
+ console.error('PostHog error:', error);
284
+
285
+ // Send to your error tracking service
286
+ // Sentry.captureException(error);
287
+ // or
288
+ // logger.error('PostHog error', { error });
289
+ },
290
+ });
291
+
292
+ const events = new Events('my-app', {
293
+ subscribers: [adapter],
294
+ });
295
+
296
+ // If PostHog API is down, errors will be caught and logged
297
+ // but won't crash your application
298
+ events.trackEvent('test.event', { userId: 'user-123' });
299
+
300
+ await events.shutdown();
301
+ }
302
+
303
+ // ============================================================================
304
+ // Example 7: Complete B2B SaaS Example
305
+ // ============================================================================
306
+
307
+ async function completeSaaSExample() {
308
+ const _subscriber = new PostHogSubscriber({
309
+ apiKey: process.env.POSTHOG_API_KEY!,
310
+ onError: (error) => console.error('PostHog error:', error),
311
+ });
312
+
313
+ const events = new Events('my-saas-app', {
314
+ subscribers: [adapter],
315
+ });
316
+
317
+ const userId = 'user-123';
318
+ const companyId = 'acme-corp';
319
+
320
+ // 1. User signs up
321
+ await subscriber.identify(userId, {
322
+ $set: {
323
+ email: 'john@acme-corp.com',
324
+ name: 'John Doe',
325
+ role: 'Admin',
326
+ },
327
+ $set_once: {
328
+ signup_date: new Date().toISOString(),
329
+ },
330
+ });
331
+
332
+ events.trackEvent('user.signed_up', {
333
+ userId,
334
+ plan: 'trial',
335
+ });
336
+
337
+ // 2. Identify the company
338
+ await subscriber.groupIdentify('company', companyId, {
339
+ $set: {
340
+ name: 'Acme Corporation',
341
+ plan: 'trial',
342
+ employees: 50,
343
+ },
344
+ });
345
+
346
+ // 3. Check if company has access to beta features
347
+ const hasBetaAccess = await subscriber.isFeatureEnabled('beta-features', userId, {
348
+ groups: { company: companyId },
349
+ });
350
+
351
+ if (hasBetaAccess) {
352
+ // 4. Track feature usage with company context
353
+ await subscriber.trackEventWithGroups(
354
+ 'beta_feature.used',
355
+ {
356
+ userId,
357
+ feature: 'advanced-events',
358
+ },
359
+ { company: companyId },
360
+ );
361
+ }
362
+
363
+ // 5. User upgrades to premium
364
+ await subscriber.identify(userId, {
365
+ $set: { plan: 'premium' },
366
+ });
367
+
368
+ await subscriber.groupIdentify('company', companyId, {
369
+ $set: {
370
+ plan: 'premium',
371
+ upgraded_at: new Date().toISOString(),
372
+ },
373
+ });
374
+
375
+ events.trackOutcome('upgrade.flow', 'success', {
376
+ userId,
377
+ plan: 'premium',
378
+ amount: 99.99,
379
+ });
380
+
381
+ events.trackValue('revenue', 99.99, {
382
+ userId,
383
+ plan: 'premium',
384
+ });
385
+
386
+ await events.shutdown();
387
+ }
388
+
389
+ // ============================================================================
390
+ // Run Examples
391
+ // ============================================================================
392
+
393
+ async function main() {
394
+ console.log('PostHog Subscriber Examples\n');
395
+
396
+ // Uncomment the examples you want to run:
397
+ // await basicEventTracking();
398
+ // await featureFlagsExample();
399
+ // await personAndGroupEvents();
400
+ // await serverlessConfiguration();
401
+ // await customClientExample();
402
+ // await errorHandlingExample();
403
+ // await completeSaaSExample();
404
+
405
+ console.log('\nExamples completed!');
406
+ }
407
+
408
+ // Run if this file is executed directly
409
+ if (require.main === module) {
410
+ main().catch(console.error);
411
+ }
412
+
413
+ export {
414
+ basicEventTracking,
415
+ featureFlagsExample,
416
+ personAndGroupEvents,
417
+ serverlessConfiguration,
418
+ customClientExample,
419
+ errorHandlingExample,
420
+ completeSaaSExample,
421
+ };