Skip to content

Commit f1faef3

Browse files
committed
wip
1 parent c3dbd52 commit f1faef3

File tree

1 file changed

+55
-43
lines changed

1 file changed

+55
-43
lines changed

packages/node/README.md

Lines changed: 55 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,25 @@
33
https://www.npmjs.com/package/@segment/analytics-node
44

55
### OFFICIAL DOCUMENTATION (FULL)
6+
67
- https://segment.com/docs/connections/sources/catalog/libraries/server/node
78

89
### LEGACY NODE SDK MIGRATION GUIDE:
9-
- https://segment.com/docs/connections/sources/catalog/libraries/server/node/migration
1010

11+
- https://segment.com/docs/connections/sources/catalog/libraries/server/node/migration
1112

1213
## Runtime Support
14+
1315
- Node.js >= 18
1416
- AWS Lambda
1517
- Cloudflare Workers
1618
- Vercel Edge Functions
1719
- Web Workers / Browser (no device mode destination support)
1820

1921
## Quick Start
22+
2023
### Install library
24+
2125
```bash
2226
# npm
2327
npm install @segment/analytics-node
@@ -28,7 +32,9 @@ pnpm install @segment/analytics-node
2832
```
2933

3034
### Usage
35+
3136
Assuming some express-like web framework.
37+
3238
```ts
3339
import { Analytics } from '@segment/analytics-node'
3440
// or, if you use require:
@@ -38,9 +44,9 @@ const { Analytics } = require('@segment/analytics-node')
3844
const analytics = new Analytics({ writeKey: '<MY_WRITE_KEY>' })
3945

4046
app.post('/login', (req, res) => {
41-
analytics.identify({
42-
userId: req.body.userId,
43-
previousId: req.body.previousId
47+
analytics.identify({
48+
userId: req.body.userId,
49+
previousId: req.body.previousId,
4450
})
4551
res.sendStatus(200)
4652
})
@@ -49,48 +55,46 @@ app.post('/cart', (req, res) => {
4955
analytics.track({
5056
userId: req.body.userId,
5157
event: 'Add to cart',
52-
properties: { productId: '123456' }
58+
properties: { productId: '123456' },
5359
})
54-
res.sendStatus(201)
55-
});
60+
res.sendStatus(201)
61+
})
5662
```
5763

58-
5964
## Settings & Configuration
65+
6066
See the documentation: https://segment.com/docs/connections/sources/catalog/libraries/server/node/#configuration
6167

6268
You can also see the complete list of settings in the [AnalyticsSettings interface](src/app/settings.ts).
6369

64-
6570
## Plugin Architecture
66-
- See segment's [documentation for plugin architecture](https://segment.com/docs/connections/sources/catalog/libraries/website/javascript/#plugin-architecture).
67-
6871

72+
- See segment's [documentation for plugin architecture](https://segment.com/docs/connections/sources/catalog/libraries/website/javascript/#plugin-architecture).
6973

7074
## Usage in non-node runtimes
75+
7176
### Usage in AWS Lambda
77+
7278
- [AWS lambda execution environment](https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtime-environment.html) is challenging for typically non-response-blocking async activites like tracking or logging, since the runtime terminates / freezes after a response is emitted.
7379

7480
Here is an example of using analytics.js within a handler:
81+
7582
```ts
7683
const { Analytics } = require('@segment/analytics-node');
7784

78-
// since analytics has the potential to be stateful if there are any plugins added,
79-
// to be on the safe side, we should instantiate a new instance of analytics on every request (the cost of instantiation is low).
80-
const analytics = () => new Analytics({
81-
flushAt: 1,
85+
// Preferable to create a new analytics instance per-invocation. Otherwise, we may get a warning about overlapping flush calls. Also, custom plugins have the potential to be stateful, so we prevent those kind of race conditions.
86+
const createAnalytics = () => new Analytics({
8287
writeKey: '<MY_WRITE_KEY>',
83-
})
84-
.on('error', console.error);
88+
}).on('error', console.error);
8589

8690
module.exports.handler = async (event) => {
87-
...
88-
// we need to await before returning, otherwise the lambda will exit before sending the request.
89-
await new Promise((resolve) =>
90-
analytics().track({ ... }, resolve)
91-
)
91+
const analytics = createAnalytics()
92+
93+
analytics.identify({ ... })
94+
analytics.track({ ... })
95+
96+
await analytics.flush()
9297

93-
...
9498
return {
9599
statusCode: 200,
96100
};
@@ -99,61 +103,68 @@ module.exports.handler = async (event) => {
99103
```
100104

101105
### Usage in Vercel Edge Functions
106+
102107
```ts
103108
import { Analytics } from '@segment/analytics-node';
104109
import { NextRequest, NextResponse } from 'next/server';
105110

106-
export const analytics = new Analytics({
111+
const createAnalytics = () => new Analytics({
107112
writeKey: '<MY_WRITE_KEY>',
108-
flushAt: 1,
109-
})
110-
.on('error', console.error)
113+
}).on('error', console.error)
111114

112115
export const config = {
113116
runtime: 'edge',
114117
};
115118

116119
export default async (req: NextRequest) => {
117-
await new Promise((resolve) =>
118-
analytics.track({ ... }, resolve)
119-
);
120+
const analytics = createAnalytics()
121+
122+
analytics.identify({ ... })
123+
analytics.track({ ... })
124+
125+
await analytics.flush()
126+
120127
return NextResponse.json({ ... })
121128
};
122129
```
123130

124131
### Usage in Cloudflare Workers
132+
125133
```ts
126134
import { Analytics, Context } from '@segment/analytics-node';
127135

136+
137+
const createAnalytics = () => new Analytics({
138+
writeKey: '<MY_WRITE_KEY>',
139+
}).on('error', console.error);
140+
128141
export default {
129142
async fetch(
130143
request: Request,
131144
env: Env,
132145
ctx: ExecutionContext
133146
): Promise<Response> {
134-
const analytics = new Analytics({
135-
flushAt: 1,
136-
writeKey: '<MY_WRITE_KEY>',
137-
}).on('error', console.error);
147+
const analytics = createAnalytics()
138148

139-
await new Promise((resolve, reject) =>
140-
analytics.track({ ... }, resolve)
141-
);
149+
analytics.identify({ ... })
150+
analytics.track({ ... })
151+
152+
await analytics.flush()
142153

143-
...
144154
return new Response(...)
145155
},
146156
};
147157

148158
```
149159

150160
### OAuth 2
151-
In order to guarantee authorized communication between your server environment and Segment's Tracking API, you can [enable OAuth 2 in your Segment workspace](https://segment.com/docs/partners/enable-with-segment/). To support the non-interactive server environment, the OAuth workflow used is a signed client assertion JWT. You will need a public and private key pair where the public key is uploaded to the segment dashboard and the private key is kept in your server environment to be used by this SDK. Your server will verify its identity by signing a token request and will receive a token that is used to to authorize all communication with the Segment Tracking API.
152161

153-
You will also need to provide the OAuth Application ID and the public key's ID, both of which are provided in the Segment dashboard. You should ensure that you are implementing handling for Analytics SDK errors. Good logging will help distinguish any configuration issues.
162+
In order to guarantee authorized communication between your server environment and Segment's Tracking API, you can [enable OAuth 2 in your Segment workspace](https://segment.com/docs/partners/enable-with-segment/). To support the non-interactive server environment, the OAuth workflow used is a signed client assertion JWT. You will need a public and private key pair where the public key is uploaded to the segment dashboard and the private key is kept in your server environment to be used by this SDK. Your server will verify its identity by signing a token request and will receive a token that is used to to authorize all communication with the Segment Tracking API.
163+
164+
You will also need to provide the OAuth Application ID and the public key's ID, both of which are provided in the Segment dashboard. You should ensure that you are implementing handling for Analytics SDK errors. Good logging will help distinguish any configuration issues.
154165

155166
```ts
156-
import { Analytics, OAuthSettings } from '@segment/analytics-node';
167+
import { Analytics, OAuthSettings } from '@segment/analytics-node'
157168
import { readFileSync } from 'fs'
158169

159170
const privateKey = readFileSync('private.pem', 'utf8')
@@ -169,8 +180,9 @@ const analytics = new Analytics({
169180
oauthSettings: settings,
170181
})
171182

172-
analytics.on('error', (err) => { console.error(err) })
183+
analytics.on('error', (err) => {
184+
console.error(err)
185+
})
173186

174187
analytics.track({ userId: 'foo', event: 'bar' })
175-
176188
```

0 commit comments

Comments
 (0)