From 71542ddb03099661fe656cb499ec68525e29f6ab Mon Sep 17 00:00:00 2001 From: LongYinan Date: Thu, 25 Jul 2024 22:24:26 +0800 Subject: [PATCH] fix(telemetry): send to custom.io --- packages/telemetry/package.json | 1 + packages/telemetry/src/index.ts | 42 ++++++++- packages/telemetry/worker-configuration.d.ts | 1 + pnpm-lock.yaml | 92 ++++++++++++++++++++ 4 files changed, 134 insertions(+), 2 deletions(-) diff --git a/packages/telemetry/package.json b/packages/telemetry/package.json index fd56505..bb97e31 100644 --- a/packages/telemetry/package.json +++ b/packages/telemetry/package.json @@ -10,6 +10,7 @@ }, "devDependencies": { "@cloudflare/workers-types": "^4.20231218.0", + "@customerio/cdp-analytics-node": "^0.2.0", "typescript": "^5.5.2", "wrangler": "^3.60.3" } diff --git a/packages/telemetry/src/index.ts b/packages/telemetry/src/index.ts index 5f7997f..bd7cdb3 100644 --- a/packages/telemetry/src/index.ts +++ b/packages/telemetry/src/index.ts @@ -1,5 +1,7 @@ +import { Analytics } from '@customerio/cdp-analytics-node'; + export default { - async fetch(request): Promise { + async fetch(request, env: Env): Promise { // https://github.com/mixpanel/tracking-proxy/blob/master/nginx.conf const headers = new Headers(request.headers); if (request.method !== 'POST' && request.method !== 'OPTIONS') { @@ -19,7 +21,43 @@ export default { headers.set('Host', 'api-js.mixpanel.com'); const url = new URL(request.url); url.host = 'api-js.mixpanel.com'; - const req = new Request(url, request); + const req = new Request(url, request.clone()); + try { + const body = await request.text(); + const requestData = decodeURIComponent(body).split('data='); + const payload = requestData[1]; + if (payload) { + const events = JSON.parse(atob(payload)); + const eventsToSend = events.filter((payload: any) => !payload.event?.includes?.('page_view') && payload.properties?.$user_id); + if (eventsToSend.length) { + const sendQueue: Promise[] = []; + const analytics = new Analytics({ + writeKey: env.CUSTOM_IO_KEY, + flushInterval: 10, + maxEventsInBatch: eventsToSend.length, + }); + for (const event of eventsToSend) { + sendQueue.push( + new Promise((resolve) => { + analytics.track( + { + userId: event.properties.$user_id, + event: event.event, + properties: event.properties, + }, + () => { + resolve(); + }, + ); + }), + ); + } + await Promise.all(sendQueue); + } + } + } catch (e) { + console.error(`event can not be parsed`, e); + } const res = await fetch(req, { headers, }); diff --git a/packages/telemetry/worker-configuration.d.ts b/packages/telemetry/worker-configuration.d.ts index 5b2319b..a85dfde 100644 --- a/packages/telemetry/worker-configuration.d.ts +++ b/packages/telemetry/worker-configuration.d.ts @@ -1,4 +1,5 @@ // Generated by Wrangler // After adding bindings to `wrangler.toml`, regenerate this interface via `npm run cf-typegen` interface Env { + CUSTOM_IO_KEY: string; } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2e9af51..90fa57a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -65,6 +65,9 @@ importers: '@cloudflare/workers-types': specifier: ^4.20231218.0 version: 4.20240722.0 + '@customerio/cdp-analytics-node': + specifier: ^0.2.0 + version: 0.2.0 typescript: specifier: ^5.5.2 version: 5.5.4 @@ -160,6 +163,13 @@ packages: resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} engines: {node: '>=12'} + '@customerio/cdp-analytics-core@0.2.0': + resolution: {integrity: sha512-kOdH7h5KQ1sylcZtK4zyu0PP0Alw1mY/yzkxgwyue+JYgwXfy8wigaR7QxmqmjUZPsig7YILATPZ9pcL/8urdA==} + + '@customerio/cdp-analytics-node@0.2.0': + resolution: {integrity: sha512-ISBlCN/9urbL3U/c6nLMOMq89Zfzk7XPHVzJBZPwIGCHDpU+HsRUFIgmYOekRc82tjYF6OTYqCXc10hXBfjxvg==} + engines: {node: '>=14'} + '@emnapi/core@1.2.0': resolution: {integrity: sha512-E7Vgw78I93we4ZWdYCb4DGAwRROGkMIXk7/y87UmANR+J6qsWusmC3gLt0H+O0KOt5e6O38U8oJamgbudrES/w==} @@ -325,6 +335,14 @@ packages: '@jridgewell/trace-mapping@0.3.9': resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + '@lukeed/csprng@1.1.0': + resolution: {integrity: sha512-Z7C/xXCiGWsg0KuKsHTKJxbWhpI3Vs5GwLfOean7MGyVFGqdRgBbAjOCh6u4bbjPc/8MJ2pZmK/0DLdCbivLDA==} + engines: {node: '>=8'} + + '@lukeed/uuid@2.0.1': + resolution: {integrity: sha512-qC72D4+CDdjGqJvkFMMEAtancHUQ7/d/tAiHf64z8MopFDmcrtbcJuerDtFceuAfQJ2pDSfCKCtbqoGBNnwg0w==} + engines: {node: '>=8'} + '@napi-rs/wasm-runtime@0.2.4': resolution: {integrity: sha512-9zESzOO5aDByvhIAsOy9TbpZ0Ur2AJbUI7UT73kcUTS2mxAMHOBaa1st/jAymNoCtvrit99kkzT1FZuXVcgfIQ==} @@ -462,6 +480,9 @@ packages: buffer@5.7.1: resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + buffer@6.0.3: + resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + capnp-ts@0.7.0: resolution: {integrity: sha512-XKxXAC3HVPv7r674zP0VC3RTXz+/JKhfyw94ljvF80yynK6VkTnqE3jMuN8b3dUVmmc43TjyxjW4KTsmB3c86g==} @@ -510,6 +531,10 @@ packages: resolution: {integrity: sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==} engines: {node: '>=8'} + dset@3.1.3: + resolution: {integrity: sha512-20TuZZHCEZ2O71q9/+8BwKwZ0QtD9D8ObhrihJPr+vLLYlSuAU3/zL4cSlgbfeoGHTjCSJBa7NGcrF9/Bx/WJQ==} + engines: {node: '>=4'} + end-of-stream@1.4.4: resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} @@ -649,6 +674,15 @@ packages: node-fetch-native@1.6.4: resolution: {integrity: sha512-IhOigYzAKHd244OC0JIMIUrjzctirCmPkaIfhDeGcEETWof5zKYUW7e7MYvChGWh/4CJeXEgsRyGzuF334rOOQ==} + node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + node-forge@1.3.1: resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==} engines: {node: '>= 6.13.0'} @@ -781,6 +815,9 @@ packages: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} + tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + tslib@2.6.2: resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} @@ -811,6 +848,16 @@ packages: util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + uuid@9.0.1: + resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} + hasBin: true + + webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + + whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + workerd@1.20240718.0: resolution: {integrity: sha512-w7lOLRy0XecQTg/ujTLWBiJJuoQvzB3CdQ6/8Wgex3QxFhV9Pbnh3UbwIuUfMw3OCCPQc4o7y+1P+mISAgp6yg==} engines: {node: '>=16'} @@ -880,6 +927,23 @@ snapshots: dependencies: '@jridgewell/trace-mapping': 0.3.9 + '@customerio/cdp-analytics-core@0.2.0': + dependencies: + '@lukeed/uuid': 2.0.1 + dset: 3.1.3 + tslib: 2.6.3 + + '@customerio/cdp-analytics-node@0.2.0': + dependencies: + '@customerio/cdp-analytics-core': 0.2.0 + '@lukeed/uuid': 2.0.1 + buffer: 6.0.3 + node-fetch: 2.7.0 + tslib: 2.6.3 + uuid: 9.0.1 + transitivePeerDependencies: + - encoding + '@emnapi/core@1.2.0': dependencies: '@emnapi/wasi-threads': 1.0.1 @@ -983,6 +1047,12 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.0 + '@lukeed/csprng@1.1.0': {} + + '@lukeed/uuid@2.0.1': + dependencies: + '@lukeed/csprng': 1.1.0 + '@napi-rs/wasm-runtime@0.2.4': dependencies: '@emnapi/core': 1.2.0 @@ -1117,6 +1187,11 @@ snapshots: base64-js: 1.5.1 ieee754: 1.2.1 + buffer@6.0.3: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + capnp-ts@0.7.0: dependencies: debug: 4.3.5 @@ -1160,6 +1235,8 @@ snapshots: detect-libc@2.0.2: {} + dset@3.1.3: {} + end-of-stream@1.4.4: dependencies: once: 1.4.0 @@ -1300,6 +1377,10 @@ snapshots: node-fetch-native@1.6.4: {} + node-fetch@2.7.0: + dependencies: + whatwg-url: 5.0.0 + node-forge@1.3.1: {} normalize-path@3.0.0: {} @@ -1442,6 +1523,8 @@ snapshots: dependencies: is-number: 7.0.0 + tr46@0.0.3: {} + tslib@2.6.2: optional: true @@ -1472,6 +1555,15 @@ snapshots: util-deprecate@1.0.2: {} + uuid@9.0.1: {} + + webidl-conversions@3.0.1: {} + + whatwg-url@5.0.0: + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + workerd@1.20240718.0: optionalDependencies: '@cloudflare/workerd-darwin-64': 1.20240718.0