|
1 | 1 | # Telemetry Deck JavaScript SDK |
2 | 2 |
|
3 | | -This package allows you to send signals to [TelemetryDeck](https://telemetrydeck.com) from your JavaScript code. |
| 3 | +This package allows you to send signals to [TelemetryDeck](https://telemetrydeck.com) from JavaScript code. |
4 | 4 |
|
5 | | -It has no package dependencies and supports **modern evergreen browsers** which support [cryptography](https://caniuse.com/cryptography). |
| 5 | +TelemetryDeck allows you to capture and analyize users moving through your app and get help deciding how to grow, all without compromising privacy! |
6 | 6 |
|
7 | | -Signals sent with this version of the SDK automatically send the following payload items: |
| 7 | +> [!NOTE] |
| 8 | +> If you want to use TelemetryDeck for your blog or static website, we recommend the [TelemetryDeck Web SDK](https://github.com/TelemetryDeck/WebSDK) instead of this JavaScript SDK. |
8 | 9 |
|
9 | | -- `url` |
10 | | -- `useragent` |
11 | | -- `locale` |
12 | | -- `platform` |
| 10 | +# Set Up |
13 | 11 |
|
14 | | -You can filter and show these values in the TelemetryDeck dashboard. |
| 12 | +The TelemetryDeck SDK has no dependencies and supports **modern evergreen browsers** and **modern versions of Node.js** with support for [cryptography](https://caniuse.com/cryptography). |
15 | 13 |
|
16 | | -Test Mode is currently not supported. |
| 14 | +## Set up in Browser Based Applications that use a bundler (React, Vue, Angular, Svelte, Ember, …) |
17 | 15 |
|
18 | | -## Usage |
| 16 | +### 1. Installing the package |
19 | 17 |
|
20 | | -### 📄 Usage via Script tag |
| 18 | +Please install the package using npm or the package manager of your choice |
21 | 19 |
|
22 | | -For websites and to try out the code quickly, you can use [UNPKG](https://unpkg.com), a free CDN which allows you to load files from any npm package. |
| 20 | +### 2. Initializing TelemetryDeck |
23 | 21 |
|
24 | | -Include the following snippet inside the `<head>` of your HTML page: |
| 22 | +Initialize the TelemetryDeck SDK with your app ID and your user's user identifer. |
25 | 23 |
|
26 | | -```html |
27 | | -<script src="https://unpkg.com/@telemetrydeck/sdk/dist/telemetrydeck.min.js" defer></script> |
| 24 | +```javascript |
| 25 | +import TelemetryDeck from '@telemetrydeck/sdk'; |
| 26 | + |
| 27 | +const td = new TelemetryDeck({ |
| 28 | + appID: '<YOUR_APP_ID>' |
| 29 | + user: '<YOUR_USER_IDENTIFIER>', |
| 30 | +}); |
28 | 31 | ``` |
29 | 32 |
|
30 | | -Then add a second script tag after it like this to send a signal once every time the page loads: |
| 33 | +Please replace `<YOUR_APP_ID>` with the app ID in TelemetryDeck ([Dashboard](https://dashboard.telemetrydeck.com) -> App -> Set Up App). |
31 | 34 |
|
32 | | -```html |
33 | | -<script> |
34 | | - window.td = window.td || []; |
35 | | - td.push(['app', YOUR_APP_ID], ['user', USER_IDENTIFIER], ['signal']); |
36 | | -</script> |
37 | | -``` |
| 35 | +You also need to identify your logged in user. Instead of `<YOUR_USER_IDENTIFIER>`, pass in any string that uniquely identifies your user, such as an email address. It will be cryptographically anonymized with a hash function. |
38 | 36 |
|
39 | | -Please replace `YOUR_APP_ID` with the app ID you received from TelemetryDeck, and `USER_IDENTIFIER` with a user identifier. If you have none, consider `anonymous`. |
40 | | - |
41 | | -You can add as many signals as you need to track different interactions with your page. Once the page and script are fully loaded, signals will be sent immediately. |
42 | | - |
43 | | -#### Alternative usage for more complex tracking needs |
44 | | - |
45 | | -```html |
46 | | -<script> |
47 | | - // Required: queue setup |
48 | | - td = window.td || []; |
49 | | - // Required: Set your application id |
50 | | - td.push(['app', YOUR_APP_ID]); |
51 | | - // Required: Set a user idenfitier. `anonymous` is a recommended default |
52 | | - td.push(['user', USER_IDENTIFIER ?? 'anonymous']); |
53 | | -
|
54 | | - // Custom payload sent with the signal |
55 | | - td.push(['signal']); |
56 | | - td.push([ |
57 | | - 'signal', |
58 | | - { |
59 | | - route: 'some/page/path', |
60 | | - }, |
61 | | - ]); |
62 | | -</script> |
63 | | -``` |
| 37 | +If can't specify a user identifer at initialization, you can set it later by setting `td.clientUser`. |
64 | 38 |
|
65 | | -### 📦 Advanced usage for applications that use a bundler (like Webpack, Rollup, …) |
| 39 | +Please note that `td.signal` is an async function that returns a promise. |
66 | 40 |
|
67 | | -After installing the package via NPM, use it like this: |
| 41 | +## Set up in Node.js Applications |
68 | 42 |
|
69 | | -```js |
70 | | -import { TelemetryDeck } from '@telemetrydeck/sdk'; |
| 43 | +### 1. Installing the package |
71 | 44 |
|
72 | | -const td = new TelemetryDeck({ app: YOUR_APP_ID, user: YOUR_USER_IDENTIFIER }); |
| 45 | +Please install the package using npm or the package manager of your choice |
73 | 46 |
|
74 | | -// Basic signal |
75 | | -td.signal(); |
| 47 | +### 2. Initializing TelemetryDeck |
76 | 48 |
|
77 | | -// Adanced: Signal with custom payload |
78 | | -td.signal({ |
79 | | - route: 'some/page/path', |
80 | | -}); |
| 49 | +Initialize the TelemetryDeck SDK with your app ID and your user's user identifer. Since `globalThis.crypto.subtle.digest` does not exist in Node.js, you need to pass in an alternative implementation provided by Node.js. |
| 50 | + |
| 51 | +```javascript |
| 52 | +import TelemetryDeck from '@telemetrydeck/sdk'; |
| 53 | +import crypto from 'crypto'; |
81 | 54 |
|
| 55 | +const td = new TelemetryDeck({ |
| 56 | + appID: '<YOUR_APP_ID>' |
| 57 | + user: '<YOUR_USER_IDENTIFIER>', |
| 58 | + cryptoDigest: crypto.webcrypto.subtle.digest, |
| 59 | +}); |
82 | 60 | ``` |
83 | 61 |
|
84 | | -Please replace `YOUR_APP_ID` with the app ID you received from TelemetryDeck. If you have any string that identifies your user, such as an email address, use it as `YOUR_USER_IDENTIFIER` – it will be cryptographically anonymized with a hash function. |
| 62 | +Please replace `<YOUR_APP_ID>` with the app ID in TelemetryDeck ([Dashboard](https://dashboard.telemetrydeck.com) -> App -> Set Up App). |
85 | 63 |
|
86 | | -If you want to pass optional parameters to the signal being sent, add them to the optional payload object. |
| 64 | +You also need to identify your logged in user. Instead of `<YOUR_USER_IDENTIFIER>`, pass in any string that uniquely identifies your user, such as an email address. It will be cryptographically anonymized with a hash function. |
87 | 65 |
|
88 | | -You can also update your user identifier or queue events like this: |
| 66 | +If can't specify a user identifer at initialization, you can set it later by setting `td.clientUser`. |
89 | 67 |
|
90 | | -```js |
91 | | -// Optional: Update app or user identifier |
92 | | -td.app(YOUR_NEW_APP_ID); |
93 | | -td.user(YOUR_NEW_USER_IDENTIFIER); |
| 68 | +Please note that `td.signal` is an async function that returns a promise. |
94 | 69 |
|
95 | | -// Optional: Process any events that have been qeued up |
96 | | -// Queued signals do not contain a client side timestamp and will be timestamped |
97 | | -// on the server at the time of arrival. Consider adding a timestamp value to |
98 | | -// your payloads if you need to be able to correlate them. |
99 | | -const queuedEvents = [ |
100 | | - ['app', YOUR_APP_ID], |
101 | | - ['user', YOUR_USER_IDENTIFIER], |
102 | | - ['signal'], |
103 | | - ['signal', { route: 'some/page/path' }], |
104 | | -]; |
105 | | -td.ingest(qeuedEvents); |
106 | | -``` |
| 70 | +> [!NOTE] |
| 71 | +> If you are using React Native, React Native does not support the `crypto` module, which is required for the SDK to work. We found [react-native-quick-crypto](https://github.com/margelo/react-native-quick-crypto) to be a suitable polyfill. Please note that this is not an officially supported solution. |
107 | 72 |
|
108 | | -## More Info |
| 73 | +## Advanced Initalization Options |
109 | 74 |
|
110 | | -### 📱 You need an App ID |
| 75 | +See the [source code](./src/telemetrydeck.js#L6-L17) for a full list of availble options acepted by the `TelemetryDeck` constructor. |
111 | 76 |
|
112 | | -Every application and website registered to TelemetryDeck has its own unique ID that we use to assign incoming signals to the correct app. To get started, create a new app in the TelemetryDeck UI and copy its ID. |
| 77 | +# Sending Signals |
113 | 78 |
|
114 | | -### 👤 Optional: User Identifiers |
| 79 | +Send a basic signal by calling `td.signal()` with a signal type: |
115 | 80 |
|
116 | | -TelemetryDeck can count users if you assign it a unique identifier for each user that doesn't change. This identifier can be any string that is unique to the user, such as their email address, or a randomly generated UUID. |
| 81 | +```javascript |
| 82 | +td.signal('<SIGNAL_TYPE>'); |
| 83 | +``` |
| 84 | + |
| 85 | +Send a signal with a custom payload by passing an object as the second argument. The payload's values will be [converted to Strings](./src/tests/store.test.js.js#L278-L310), except for `floatValue`, which can be a Float. |
| 86 | + |
| 87 | +```javascript |
| 88 | +td.signal('Volume.Set', { |
| 89 | + band: 'Spinal Tap', |
| 90 | + floatValue: 11.0, |
| 91 | +}); |
| 92 | +``` |
| 93 | + |
| 94 | +# Advanced: Queueing Signals |
117 | 95 |
|
118 | | -Feel free to use personally identifiable information as the user identifier: We use a cryptographically secure double-hasing process on client and server to make sure the data that arrives at our servers is anonymized and can not be traced back to individual users via their identifiers. A user's identifier is hashed inside the library, and then salted+hashed again on arrival at the server. This way the data is anonymized as defined by the GDPR and you don't have to ask for user consent for procesing or storing this data. |
| 96 | +The `TelemetryDeck` class comes with a built-in queuing mechanism for storing signals until they are flushed in a single request. Queued signals are sent with `receivedAt` prefilled with the time they were queued. |
119 | 97 |
|
120 | | -### 🚛 Optional: Payload |
| 98 | +This uses an in-memory store by default. The store is not persisted between page reloads or app restarts. If you want to persist the store, you can pass a `store` object to the `TelemetryDeck` constructor. The store must implement the following interface: |
| 99 | + |
| 100 | +```javascript |
| 101 | +export class Store { |
| 102 | + async push() // signal bodys are async and need to be awaited before stored |
| 103 | + clear() // called after flush |
| 104 | + values() // returns an array of resolved signal bodys in the order they were pushed |
| 105 | +} |
| 106 | +``` |
121 | 107 |
|
122 | | -You can optionally attach an object with string values to the signal. This will allow you to filter and aggregate signal by these values in the dashboard. |
| 108 | +The default implementation can be found in `src/utils/store.js`. |
123 | 109 |
|
124 | | -### 📚 Full Docs |
| 110 | +--- |
125 | 111 |
|
126 | | -Go to [telemetrydeck.com/docs](https://telemetrydeck.com/docs) to see all documentation articles |
| 112 | +[TelemetryDeck](https://telemetrydeck.com?source=github) helps you build better products with live usage data. Try it out for free. |
0 commit comments