amplitude / amplitude-node Goto Github PK
View Code? Open in Web Editor NEWServer-side Node.js SDK for Amplitude
License: MIT License
Server-side Node.js SDK for Amplitude
License: MIT License
How do you enable this includeUtm for nodejs sdk?
When setting platform it is never received as sent
Platform is always overridden to "Node.js"
{
user_id: '60245c08b45ec4007022ec13',
device_id: 'c3dae446-7d15-44fb-9751-16e4b38df58b',
event_type: 'ACTION_INSERT_TOPIC_THREAD_COMMENT',
insert_id: 'bbe59f0d-2bc2-47a7-8543-684072e7785d',
time: 1612996899714,
session_id: '1612996076612',
app_version: '@bubbles/[email protected]',
language: 'en-US',
ip: '71.198.20.116',
platform: '[email protected]',
os_name: 'Mac OS',
os_version: '10.15.7',
device_brand: undefined,
device_model: undefined,
event_properties: {
viewId: 'e155c739-3f77-46f7-8123-2dd5dea599fc',
originTopicId: 'e155c739-3f77-46f7-8123-2dd5dea599fc',
originUserEmail: undefined,
originUserName: 'Amplitude2',
isUserAction: false,
actionType: 'INSERT_TOPIC_THREAD_COMMENT',
actionId: 'bbe59f0d-2bc2-47a7-8543-684072e7785d',
isServerGenerated: undefined,
userAgent: {
ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.146 Safari/537.36',
browser: { name: 'Chrome', version: '88.0.4324.146', major: '88' },
engine: { name: 'Blink', version: '88.0.4324.146' },
os: { name: 'Mac OS', version: '10.15.7' },
device: { vendor: undefined, model: undefined, type: undefined },
cpu: { architecture: undefined }
},
payload: {
threadId: '01cdebcd-39b5-4714-9321-c5644da49f32',
archived: false,
topicId: 'e155c739-3f77-46f7-8123-2dd5dea599fc',
participantEmails: [ [length]: 0 ],
name: 'Amplitude2',
id: '2c916ba6-ec74-4632-9a54-c5ca652102ec',
body: 'test2',
userId: '60245c08b45ec4007022ec13',
timestamp: 1612996899918
}
},
user_properties: {
originUserEmail: undefined,
originUserName: 'Amplitude2',
userAgent: {
ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.146 Safari/537.36',
browser: { name: 'Chrome', version: '88.0.4324.146', major: '88' },
engine: { name: 'Blink', version: '88.0.4324.146' },
os: { name: 'Mac OS', version: '10.15.7' },
device: { vendor: undefined, model: undefined, type: undefined },
cpu: { architecture: undefined }
}
}
}
Node.js
:{
"$insert_id": "9eb32219-3af0-47dd-91f6-359438c901dc",
"$row_source": "realtime",
"$schema": 12,
"_time": 1612996625311,
"adid": null,
"amplitude_attribution_ids": null,
"amplitude_event_type": null,
"amplitude_id": 233091255869,
"app": 310020,
"city": "San Francisco",
"client_event_time": "2021-02-10T22:37:05.311",
"client_upload_time": "2021-02-10T22:37:15.619",
"country": "United States",
"data": {
},
"device_brand": null,
"device_carrier": null,
"device_family": null,
"device_id": "c3dae446-7d15-44fb-9751-16e4b38df58b",
"device_manufacturer": null,
"device_model": null,
"device_type": null,
"display_name": "ACTION_INSERT_TOPIC_THREAD_COMMENT",
"dma": "San Francisco-Oakland-San Jose, CA",
"event_id": 854747387,
"event_properties": {
"actionId": "9eb32219-3af0-47dd-91f6-359438c901dc",
"actionType": "INSERT_TOPIC_THREAD_COMMENT",
"isUserAction": false,
"originTopicId": "e155c739-3f77-46f7-8123-2dd5dea599fc",
"originUserName": "Amplitude2",
"payload.archived": false,
"payload.body": "test",
"payload.id": "0743bb3b-cf46-47c3-aaf6-bd2a3f820683",
"payload.name": "Amplitude2",
"payload.participantEmails": [
],
"payload.threadId": "01cdebcd-39b5-4714-9321-c5644da49f32",
"payload.timestamp": 1612996624513,
"payload.topicId": "e155c739-3f77-46f7-8123-2dd5dea599fc",
"payload.userId": "60245c08b45ec4007022ec13",
"userAgent.browser.major": "88",
"userAgent.browser.name": "Chrome",
"userAgent.browser.version": "88.0.4324.146",
"userAgent.engine.name": "Blink",
"userAgent.engine.version": "88.0.4324.146",
"userAgent.os.name": "Mac OS",
"userAgent.os.version": "10.15.7",
"userAgent.ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.146 Safari/537.36",
"viewId": "e155c739-3f77-46f7-8123-2dd5dea599fc"
},
"event_time": "2021-02-10T22:37:05.311",
"event_type": "ACTION_INSERT_TOPIC_THREAD_COMMENT",
"group_properties": {
},
"groups": {
},
"idfa": null,
"ip_address": "71.198.20.116",
"is_attribution_event": false,
"language": "English",
"library": "amplitude-node/1.3.2",
"location_lat": null,
"location_lng": null,
"os": "Mac OS 10.15.7",
"os_name": "Mac OS",
"os_version": "10.15.7",
"paying": null,
"platform": "Node.js",
"region": "California",
"sample_rate": null,
"server_received_time": "2021-02-10 22:37:15.619000",
"server_upload_time": "2021-02-10T22:37:15.641",
"session_id": 1612996076612,
"start_version": "@bubbles/[email protected]",
"timeline_hidden": false,
"user_creation_time": "2021-02-10T22:19:55.227",
"user_id": "60245c08b45ec4007022ec13",
"user_properties": {
"originUserAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.146 Safari/537.36",
"originUserName": "Amplitude2",
"userAgent.browser.major": "88",
"userAgent.browser.name": "Chrome",
"userAgent.browser.version": "88.0.4324.146",
"userAgent.engine.name": "Blink",
"userAgent.engine.version": "88.0.4324.146",
"userAgent.os.name": "Mac OS",
"userAgent.os.version": "10.15.7",
"userAgent.ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.146 Safari/537.36"
},
"uuid": "8771ca20-6bf0-11eb-9ed4-0231551a9deb",
"version_name": "@bubbles/[email protected]"
}
Hi! We use amplitude-node/1.9.0. And send the events using just event_type, user_id and a single user_properties item:
await amplitudeClient.logEvent({
event_type: 'business_subscription_linked',
user_id: user.id,
user_properties: {
business_subscription_account: subscription.accountId
}
});
In some cases the event received contains inherited user properties from the previously sent client events, but often it doesn't โ including even standard system properties like Platform, IP or Start Version.
There seems to be no place to fail from our side (it's just too simple), so I suppose it could be an Amplitude bug.
Hello,
I've had this code successfully sending events to Amplitude for months. Starting on May 7th, they stopped sending. I'm not sure how to debug this or what happened.
Here is the code:
var client = amplitude.init(process.env.MY_AMPLITUDE_API_KEY);
client.logEvent({
event_type: "text_received",
user_id: num,
event_properties: {
body: ${event.Body}
,
ApiVersion: ${event.ApiVersion}
,
},
user_properties: {
$set: {
"date_joined": contactDateJoined,
"week_joined":contactWeekJoined
},
$add: {
"messages_received": +1
}
}
});
var client = amplitude.init(process.env.MY_AMPLITUDE_API_KEY); client.logEvent({ event_type: "text_received", user_id: num, event_properties: { body:
${event.Body}, ApiVersion:
${event.ApiVersion}, }, user_properties: { $set: { "date_joined": contactDateJoined, "week_joined":contactWeekJoined }, $add: { "messages_received": +1 } } });
See that user look up is empty: (this use to have data in it)
and replies drop to 0 on May 7th even though I have record of the events in my database.
Instead of:
export const AMPLITUDE_API_HOST = 'api.amplitude.com'
it should be export const AMPLITUDE_API_HOST = 'api2.amplitude.com'
Right now this throws an error:
[Amplitude|Error] Event is not submitted. { Error: certificate has expired
at TLSSocket.onConnectSecure (_tls_wrap.js:1041:34)
at TLSSocket.emit (events.js:160:13)
at TLSSocket._finishInit (_tls_wrap.js:638:8) code: 'CERT_HAS_EXPIRED' }
This one is hard to explain so I just made a screen recording going over the latest source code:
https://app.usebubbles.com/bpPaAzXS3vWMpZh8tZU3N9/amplitude-retry-behavior-issues
Please let me know your thoughts. We're seeing 429s on our amplitude dashboard and we're looking to catch these 429 so that we can push them to a retry queue for future consumption.
Also, in your readme you say we can create our own retry class with a sendEventsWithRetry method, but then how do we access the underlying transport method?
This would require something like:
this._transport = this._options.transportClass ?? setupDefaultTransport(this._options);
But your setupDefaultTransport
function is not exported as part of the npm module as far as we can see
Similarly, to create a retry handler we'll need to implement RetryClass
, but RetryClass
is not exported:
export class CustomRetryHandler implements RetryClass { // Cannot find name 'RetryClass'
Additionally, it seems like the retry logic is currently ignoring the most common kind of throttling. An example of a response payload for a throttled device is:
{
"status":"rate_limit",
"statusCode":429,
"body":{
"error":"Too many requests for some devices and users",
"epsThreshold":15,
"throttledDevices":{
"0ddbe854-d786-4aef-bc9e-b8b7c43e5200":66
},
"throttledUsers":{
"604ac1eb9b1b7a00699d006e":66
},
"exceededDailyQuotaDevices":{},
"exceededDailyQuotaUsers":{},
"throttledEvents":[0,1,2,3,4..]
}
}
So in addition to looking at exceededDailyQuotaDevices and exceededDailyQuotaUsers, the props throttledDevices and throttledUsers should be considered. We are now going to write custom logic to handle this case in our own retry class, but it's not ideal. Unfortunately, the "plug and play" promise of Amplitude is far from a reality at the moment
When you call amplitude.flush without previously calling amplitude.logEvent (which is common if you iterate over a list of events and it just so happens that the list of events is empty), the library will throw with:
ERROR Invoke Error
{
"errorType": "TypeError",
"errorMessage": "Cannot read property 'length' of undefined",
"stack": [
"TypeError: Cannot read property 'length' of undefined",
" at Object.<anonymous> (/var/task/node_modules/@amplitude/node/dist/src/nodeClient.js:51:42)",
" at step (/var/task/node_modules/tslib/tslib.js:139:27)",
" at Object.next (/var/task/node_modules/tslib/tslib.js:120:57)",
" at /var/task/node_modules/tslib/tslib.js:113:75",
" at new Promise (<anonymous>)",
" at Object.__awaiter (/var/task/node_modules/tslib/tslib.js:109:16)",
" at Object.NodeClient.flush [as flushAmplitude] (/var/task/node_modules/@amplitude/node/dist/src/nodeClient.js:40:24)",
" at Runtime.exports.eventBusTrackingFanout [as handler] (/var/task/dist/eventsProcessor.js:28:23)"
]
}
Unexpected error on Timeout when calling Amplitude logEvent.
at Timeout._onTimeout (/workspace/node_modules/@amplitude/utils/dist/src/queue.js:67:48)
at ontimeout (timers.js:436:11)
at tryOnTimeout (timers.js:300:5)
at listOnTimeout (timers.js:263:5)
at Timer.processTimers (timers.js:223:10)
Didn't happen in previous SDKs. Looks like there were some recent code changes to that queue.js file.
Happens occasionally on calls to logEvent.
Dear @amplitude/types maintainers,
Thank you for your contribution to the open-source community.
We've noticed that sdk.dev, a new maintainer, just published version 1.10.0 of @amplitude/types to npm.
As part of our efforts to fight software supply chain attacks, we would like to verify this release is known and intended, and not a result of an unauthorized activity.
This issue was automatically created by ChainAlert.
If you find this behavior legitimate, kindly close and ignore this issue. Read more
Dear @amplitude/utils maintainers,
Thank you for your contribution to the open-source community.
We've noticed that sdk.dev, a new maintainer, just published version 1.10.0 of @amplitude/utils to npm.
As part of our efforts to fight software supply chain attacks, we would like to verify this release is known and intended, and not a result of an unauthorized activity.
This issue was automatically created by ChainAlert.
If you find this behavior legitimate, kindly close and ignore this issue. Read more
I used Batch API to send an event with event_type = "track" and self generated device_id. "track" event is visible in Amplitude. But "New User" is not created itself as according to my understanding is created by default when a user is created in amplitude. I created users with Identity API with some user_properties.
This error is crashing our server unrecoverabley and forcing us to replace the entire instance whenever it happens:
Hoping an urgent fix or info on how to avoid is available!
Unhandled rejection in index.js TypeError: Cannot read property 'length' of null
Apr 02 21:06:36 at /var/app/current/node_modules/@amplitude/node/src/retryHandler.ts:102:18
Apr 02 21:06:36 at Array.forEach (<anonymous>)
Apr 02 21:06:36 at RetryHandler._pruneEvents (/var/app/current/node_modules/@amplitude/node/src/retryHandler.ts:99:12)
Apr 02 21:06:36 at RetryHandler.<anonymous> (/var/app/current/node_modules/@amplitude/node/src/retryHandler.ts:61:31)
Apr 02 21:06:36 at step (/var/app/current/node_modules/tslib/tslib.js:141:27)
Apr 02 21:06:36 at Object.next (/var/app/current/node_modules/tslib/tslib.js:122:57)
Apr 02 21:06:36 at /var/app/current/node_modules/tslib/tslib.js:115:75
Apr 02 21:06:36 at new Promise (<anonymous>)
Apr 02 21:06:36 at Object.__awaiter (/var/app/current/node_modules/tslib/tslib.js:111:16)
Hello,
Thanks for providing a node
SDK for developers.
I have been working with it lately, but it was very hard to debug the request because I didn't manage to catch the status of the HTTP request made during logEvent
.
Is there any way to return a promise from the logEvent
function so we can do debug better when we integrate with Amplitude ?
Thanks for your help ๐
When sending os_name amplitude should pickup the OS
The OS is set to undefined
Honor the os_name field
{
user_id: '60245c08b45ec4007022ec13',
device_id: 'c3dae446-7d15-44fb-9751-16e4b38df58b',
event_type: 'ACTION_INSERT_TOPIC_THREAD_COMMENT',
insert_id: 'bbe59f0d-2bc2-47a7-8543-684072e7785d',
time: 1612996899714,
session_id: '1612996076612',
app_version: '@bubbles/[email protected]',
language: 'en-US',
ip: '71.198.20.116',
platform: '[email protected]',
os_name: 'Mac OS',
os_version: '10.15.7',
device_brand: undefined,
device_model: undefined,
event_properties: {
viewId: 'e155c739-3f77-46f7-8123-2dd5dea599fc',
originTopicId: 'e155c739-3f77-46f7-8123-2dd5dea599fc',
originUserEmail: undefined,
originUserName: 'Amplitude2',
isUserAction: false,
actionType: 'INSERT_TOPIC_THREAD_COMMENT',
actionId: 'bbe59f0d-2bc2-47a7-8543-684072e7785d',
isServerGenerated: undefined,
userAgent: {
ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.146 Safari/537.36',
browser: { name: 'Chrome', version: '88.0.4324.146', major: '88' },
engine: { name: 'Blink', version: '88.0.4324.146' },
os: { name: 'Mac OS', version: '10.15.7' },
device: { vendor: undefined, model: undefined, type: undefined },
cpu: { architecture: undefined }
},
payload: {
threadId: '01cdebcd-39b5-4714-9321-c5644da49f32',
archived: false,
topicId: 'e155c739-3f77-46f7-8123-2dd5dea599fc',
participantEmails: [ [length]: 0 ],
name: 'Amplitude2',
id: '2c916ba6-ec74-4632-9a54-c5ca652102ec',
body: 'test2',
userId: '60245c08b45ec4007022ec13',
timestamp: 1612996899918
}
},
user_properties: {
originUserEmail: undefined,
originUserName: 'Amplitude2',
userAgent: {
ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.146 Safari/537.36',
browser: { name: 'Chrome', version: '88.0.4324.146', major: '88' },
engine: { name: 'Blink', version: '88.0.4324.146' },
os: { name: 'Mac OS', version: '10.15.7' },
device: { vendor: undefined, model: undefined, type: undefined },
cpu: { architecture: undefined }
}
}
}
https://app.usebubbles.com/wSsTyZ7XMMan6v8LVPufRN/amplitude-os-undefined/
This is another case where the SDK is creating friction and we regret not using the base HTTP API.
Per the documentation at https://developers.amplitude.com/docs/identify-api an identify call can have a user_properties prop that supports deep objects up to 40 levels. Yet the Amplitude-Node Identify implementation only supports numbers, strings, or arrays thereof.
Until a solution is found, is there a way to override the types so that we can move forward? Assuming the sdk passes them directly to the user_properties prop of the underlying HTTP API call?
When the server is unavailable (no internet connection for example) the logEvent throws an unhandled rejection
Do not throws an unhandled rejection
Throws an unhandled rejection
Catch node errors in line
serverUrl
config to any non-existent addresslogEvent
unhandledRejection Error: getaddrinfo ENOTFOUND api2.amplitude.com
at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:69:26) {
errno: -3008,
code: 'ENOTFOUND',
syscall: 'getaddrinfo',
hostname: 'api2.amplitude.com'
}
In the documentation for the HTTP API, https://developers.amplitude.com/docs/http-api-v2#properties-2
, a min_id_length
is mentioned that allows overriding the check that user_id
must be at least 5 chars long:
Validation on user_id length (must be 5 or more characters unless overrided with min_id_length)
I have some user ids which are < 5 chars and am getting 400
responses when sending events. Is there any way to set this min_id_length
if using the node SDK? It doesn't seem possible from looking at the codebase.
Shouldn't log warnings
When importing the file import { init } from '@amplitude/node';
, it yields the following output:
warn - ./node_modules/@amplitude/node/esm/src/constants.js
Should not import the named export 'version' (reexported as 'SDK_VERSION') from default-exporting module (only default export is available soon)
It's hard to tell if it's a warning or an error. The warning is displayed at every rebuild.
It seems to be related to webpack 5, the @amplitude/node
package might not be compatible with Webpack 5. This affects Next.js 10+. (Webpack 5 is enabled by default in Next.js 11)
git clone [email protected]:UnlyEd/next-right-now.git nrn-refactor-amplitude && cd nrn-refactor-amplitude && git checkout refactor-amplitude && cp .env.local.example .env.local && yarn && yarn start
localhost:8888/api/status
and look at the server consoleHi, how do we set/update user properties using this lib?
It seems like it only has logEvent(), flush() and getOptions() methods - is it possible to update user props at all using this library?
If not, could you point in the right direction on how to accomplish it from server side?
Firstly, thank you for publishing a Node SDK! I greatly appreciate it.
When requiring @amplitude/node
, I see Error: Cannot find module 'tslib'
.
Environment setup:
$ node --version
v10.14.1
$ npm --version
6.14.5
$mkdir test && cd test
$ npm init
# I used all default suggested values
$ npm install --save @amplitude-node
$ node
# In the Node.js REPL:
> require('@amplitude/node')
{ Error: Cannot find module 'tslib'
at Function.Module._resolveFilename (internal/modules/cjs/loader.js:580:15)
at Function.Module._load (internal/modules/cjs/loader.js:506:25)
at Module.require (internal/modules/cjs/loader.js:636:17)
at require (internal/modules/cjs/helpers.js:20:18) code: 'MODULE_NOT_FOUND' }
I did not find any direct references to tslib
in src/
, but I did some investigation after cloning Amplitude-Node
:
Amplitude-Node $ npm ls tslib
@amplitude/[email protected] .../packages/Amplitude-Node
โโโฌ @typescript-eslint/[email protected]
โ โโโฌ [email protected]
โ โโโ [email protected]
โโโฌ [email protected]
โโโฌ [email protected]
โโโฌ [email protected]
โโโ [email protected] deduped
The top-level packages using tslib
are only devDependencies
, so tslib
would not be published with @amplitude/node
. I wondered why tslib
was used by the built package:
Amplitude-Node $ npm run build
dist/nodeClient.js
contains the following:
var NodeClient = /** @class */ (function (_super) {
tslib_1.__extends(NodeClient, _super);
I don't know which compiler/tsconfig settings cause tslib
to be used for extends
in the distributed code, but I have found a workaround: in my project that uses @amplitude/node
, I also install tslib
as a dependency. That resolves the error, at least short-term. Long-term, in @amplitude/node
itself, I don't know if it's the best way to solve the error, but I have found one workable solution: merely adding tslib
to dependencies
does seem to fix the issue.
Hi everyone.
I've implemented the Amplitude NodeJS SDK in my application. It is a simple GraphQL server that serves content to one of our websites.
I've been facing a big issue with the Amplitude SDK. When I dispatch an identify
event, it usually takes too long to resolve. Sometimes that hangs my server completely. This is especially complicated because sometimes (when Amplitude hangs the identity response for too long) my server mixes two user's requests, leading to potentially problematic issues.
Regarding "mixing two requests" I've already debugged and found out that it is indeed related to Amplitude. I've created a simple bash test script that dispatches 2 requests at the same time. Whenever I add the Amplitude identify event, that issue happens, when I remove it, the issue disappears (same request, same payload, same endpoint, only with/without Amplitude identify event)
How can I solve this? It is possible to dispatch the identify event alongside the event itself? If I don't identify the users, I would have some kind of trouble when logging the event? Since my users are already identified by my front-end application, I wonder if I truly need the identify in the backend too.
Thanks for your attention.
npm module should contain ... the module
there's no code in the module
release the code together with the module
$ yarn add @amplitude/node
$ cd node_modules/@amplitude/node
$ cat package.json | grep index
"main": "dist/index.js",
"module": "esm/index.js",
"types": "dist/index.d.ts",
$ ls dist/index.js esm/index.js dist/index.d.ts
ls: dist/index.d.ts: No such file or directory
ls: dist/index.js: No such file or directory
ls: esm/index.js: No such file or directory
There's a flaw in the default retry behavior on line 59: whenever an error occurs, a new call stack is created and we immediately return.
Instead of returning, we should await this._onEventsError
here and ensure that onEventsError is a promise.
Currently waiting for amplitude.flush causes the node.js event loop to never clear in the case of a rate limit error.
Here's an example integration test without a rate limit using jest:
And here's one with a rate limit, notice how jest never exits:
At https://developers.amplitude.com/docs/http-api-v2 it's clearly stated that you highly recommend always passing in a insert_id, yet the sdk does not support this property? It is not part of the typescript typings.
Similarly, lots of properties are missing, e.g. os_name, app_version, etc.
There is a way to configure a time upon which the request to api is cancelled. At the moment its hardcoded to 10 seconds:
https://github.com/amplitude/Amplitude-Node/blob/main/packages/node/src/transports/http.ts#L25
Make it possible to configure the waiting time for requests in queue before removing it
Event sent using @amplitude/node should be available on the Amplitude Dashboard
Events aren't available in Amplitude, as if they were never received.
Logs:
info - ready on http://localhost:8888
2021-06-22T18:09:53.157Z [modules/core/amplitude/amplitudeServerClient] Logging Amplitude event "api-invoked" with properties: { apiEndpoint: 'status' }
2021-06-22T18:09:53.157Z [modules/core/amplitude/amplitudeServerClient] NodeClient {
_events: [],
_responseListeners: [],
_flushTimer: null,
_apiKey: '5ea02d86a6840c165fcc01377131fa13',
_options: {
serverUrl: 'https://api2.amplitude.com/2/httpapi',
debug: true,
maxCachedEvents: 16000,
logLevel: 3,
optOut: false,
retryTimeouts: [
100, 100, 200, 200,
400, 400, 800, 800,
1600, 1600, 3200, 3200
],
retryClass: null,
transportClass: null,
uploadIntervalInSec: 0,
minIdLength: null
},
_transportWithRetry: RetryHandler {
_apiKey: '5ea02d86a6840c165fcc01377131fa13',
_options: {
serverUrl: 'https://api2.amplitude.com/2/httpapi',
debug: true,
maxCachedEvents: 16000,
logLevel: 3,
optOut: false,
retryTimeouts: [Array],
retryClass: null,
transportClass: null,
uploadIntervalInSec: 0,
minIdLength: null
},
_transport: HTTPTransport {
options: [Object],
_uploadInProgress: false,
_requestQueue: [AsyncQueue],
module: [Object]
},
_idToBuffer: Map(0) {},
_eventsInRetry: 0
}
} 5ea02d86a6840c165fcc01377131fa13
response {
status: 'success',
statusCode: 200,
body: {
eventsIngested: 0,
payloadSizeBytes: 58,
serverUploadTime: 1624385394010
}
}
The API key is defined, the response is sent and awaited for, the result is a success, but there are no data in the Amplitude Dashboard. The @amplitude/react-amplitude
package works fine on the browser, though.
It doesn't work locally, and it doesn't work on Vercel either.
I'm not sure what's wrong.
Potentially related to flushing and https://vercel.com/docs/platform/limits#streaming-responses, but I've flushed and awaited for the flush to avoid any issue. Also, it doesn't even work locally.
git clone [email protected]:UnlyEd/next-right-now.git nrn-refactor-amplitude && cd nrn-refactor-amplitude && git checkout refactor-amplitude && cp .env.local.example .env.local && yarn && yarn start
localhost:8888/api/status
and look at the server consoleI am sending 13 events with logEvent at about the same time. I am not awaiting for the promise to resolve.
Later on, before I terminate, I am calling flush to make sure all events will be sent.
Flush responds with status: skipped
All events to be logged
Some events are missing, sometimes 1, sometimes more
I guess the request is still ongoing for some events?
But flush doesn't know about it?
Hello,
We are currently using the Identify API to store users related information.
Although it works well, we are also trying to use the Node SDK to logEvent
.
It would be nice to add identify API support to the SDK, so we could use it to do both event logging and user identifying.
Thanks a lot,
We are using Amplitude Node SDK for events reporting.
While implementing, we've noticed that when trying to log an event and attach it a user id
that its length is lower than 5 chars, we get an error:
Status code: 400, Status: invalid, Response body: {"error":"Invalid id length for user_id or device_id", ...}
.
To overcome this error, we concatenated 5 leading spaces, after that, the error has gone and the logEvent
function succeeded (we also validated that the leading spaces are trimmed in the Amplitude analytics site).
Could you please fix this issue, to avoid the 5 leading spaces trick?
1.5.3
15.6.0
TypeError: The "listener" argument must be of type Function. Received type object
My code block is nearly identical to the example:
const client = Amplitude.init(config.amplitude.key);
client.logEvent({
event_type: "Node Event",
user_id: "Test",
});
I am in a TypeScript project and making the call in ComponentDidMount
. Additionally, I added the @amplitude/types
package (Should update your README for that).
Any assistance would be appreciated!
The way timeout exceptions are thrown make it not possible to catch them explicitly as its just a generic rejections with an empty new Error():
https://github.com/amplitude/Amplitude-Node/blob/main/packages/utils/src/queue.ts#L56
Filter timeout exceptions and being able to handle them specifically
From https://developers.amplitude.com/docs/nodejs you can see that "Amplitude" is caps in one place but lowercase in "amplitude.init()"
This obviously results in the error "ReferenceError: amplitude is not defined"
const Amplitude = require('@amplitude/node');
// ES6 Syntax
import * as Amplitude from '@amplitude/node';
var client = amplitude.init(<AMPLITUDE_API_KEY>);
client.logEvent({
event_type: 'Node.js Event',
user_id: '[email protected]',
location_lat: 37.77,
location_lng: -122.39,
ip: '127.0.0.1',
event_properties: {
keyString: 'valueString',
keyInt: 11,
keyBool: true
}
});
// Send any events that are currently queued for sending.
// Will automatically happen on the next event loop.
client.flush();```
When I do this.client.flush(), it says that function is not implemented.
Is there a workaround? I want to make sure that all the pending logs are sent to the server before my rest api returns a response.
I am using nuxtjs with the amplitude-node package. I would like to know how do I let amplitude auto generate device ID for anonymous user.(non-logged in user)
Thank you
If I send a user_id
of 123
, I get a 200
response, but the event never appears in the web app, although I can see it in the "Successful requests" in "Sources".
400
response, as user_id
should be a string
Hi, I am looking into implementing this SDK on my Next.js project as it is server side rendered.
The documentation isn't clear, so I am unsure on how to actually get started, on my app.tsx I want to init amplitude and have it available on all pages and components.
import '../styles.css';
import React from 'react';
import { ProvideAuth } from 'utils/auth';
import * as Amplitude from '@amplitude/node';
import Layout from 'components/Layout';
type Props = {
Component: React.ElementType;
pageProps: React.Props<unknown>;
};
let client = Amplitude.init(process.env.AMPLITUDE_API_KEY)
export default function MyApp({ Component, pageProps }: Props) {
// The context is provided to the user so the userCtx is accessible anywhere with useContext hook.
return (
<ProvideAuth>
<Layout title="OWNRS" description="">
<Component {...pageProps} />
</Layout>
</ProvideAuth>
);
}
With the above, it is not initialised, as I do not use client for anything, can I simply do Amplitude.init(process.env.AMPLITUDE_API_KEY)
if not, how can I make this global?
With the client side SDK, I could init on the index.js and use amplitude.getInstance() to log an event
My question is, do I need to create a utils file that does the following
import * as Amplitude from '@amplitude/node';
const amplitude = Amplitude.init(process.env.AMPLITUDE_API_KEY);
export default amplitude;
and import it on every page, then log events?
import amplitude from 'utils/amplitude'
amplitude.logEvent({
event_type: 'Node.js Event',
user_id: '[email protected]',
location_lat: 37.77,
location_lng: -122.39,
ip: '127.0.0.1',
event_properties: {
keyString: 'valueString',
keyInt: 11,
keyBool: true
}
});
How can I make this globally available within my app so that way data can be logged?
Hi there,
When I call the log event function from this module, I get the 200 response. But the number of 'eventsIngested' returns 0. And I am not able to see the events in the dashboard either.
{ status: 'success', statusCode: 200, body: { eventsIngested: 0, payloadSizeBytes: 58, serverUploadTime: 1605483387446 } }
The event was as simple as just this
{event_type: 'test'}
What would be the issue? Appreciate your help guys. Thanks.
Hello,
I've filed this report with the support team, but they recommended opening a ticket here as well. I got word that the node SDK is swallowing some errors, so I wanted to create a ticket here to track it. I am willing to help out with a PR if necessary also.
We have this running on a system with Google pubsub, so we are retrying messages when we receive this error. Our messages backlog eventually goes down to 0, so they appear to succeed on retry, but it would be helpful to understand what this error is.
When pushing events to Amplitude via client.logEvent()
, it should return a meaningful error message.
We are receiving a lot of errors like the following:
{
"status": "unknown",
"statusCode": 0
}
Unsure
import * as Amplitude from '@amplitude/node';
// amplitude client
const client = Amplitude.init(AMPLITUDE_API_KEY);
(async function () {
// an array of events
let events = [
{ event_type: 'app_did_launch', ...restEvent },
{ event_type: 'view_post', ...restEvent },
...restEvents
];
// log each event
events.forEach(client.logEvent);
// flush events
const response = await client.flush();
console.log(response); // occasionally, we will receive { status: 'unknown', statusCode: 0 }
})();
Send multiple events with logEvent
Avoid multiple HTTP calls :)
Upgrade to 1.8.1 from 1.8.0 shouldn't introduce build failures
Upgrading from 1.8.1 requires setting requestTimeoutMillis
now
requestTimeoutMillis
should be optional defaulting to the constant, which appears unused
Write some code that compiles for 1.8.0 th
I use "amplitude-js": "^7.4.3". Using this version, I found that it is not possible to pass the "insert_id" parameter, but it is described in the HTTP API V2 and you recommend passing it!! How to pass this parameter?
Last week, our back-end using the Amplitude Node package stopped logging events. Our events have a user_id, but no device_id. While trying to debug, we added a dummy device_id and logged started working again. Removing it and using just a user_id does not work.
In the case of using just a user_id, we see the following response:
Amplitude request completed, status code: 200, status: success, nr ingested: 0
When including a dummy device_id, we get:
Amplitude request completed, status code: 200, status: success, nr ingested: 1
Our js looks approximately like this:
client.logEvent({
event_type: "test-dummy",
// device_id: "test_device",
user_id: user_id,
ip: req_data.ip
}).then((res) => {
console.log("Amplitude request completed, status code: " +
res.statusCode +
", status: " + res.status +
", nr ingested: " + res.body.eventsIngested );
});
Events have to be emitted.
Some events are not sent to the Amplitude because of an error:
2020-12-08T23:15:37: TypeError: Cannot read property 'length' of null 2020-12-08T23:15:37: at /var/www/socialcomm/source/server/node_modules/@amplitude/node/src/retryHandler.ts:91:18 2020-12-08T23:15:37: at Array.forEach (<anonymous>) 2020-12-08T23:15:37: at RetryHandler._pruneEvents (/var/www/socialcomm/source/server/node_modules/@amplitude/node/src/retryHandler.ts:89:12) 2020-12-08T23:15:37: at RetryHandler.<anonymous> (/var/www/socialcomm/source/server/node_modules/@amplitude/node/src/retryHandler.ts:51:31) 2020-12-08T23:15:37: at step (/var/www/socialcomm/source/server/node_modules/tslib/tslib.js:141:27) 2020-12-08T23:15:37: at Object.next (/var/www/socialcomm/source/server/node_modules/tslib/tslib.js:122:57) 2020-12-08T23:15:37: at /var/www/socialcomm/source/server/node_modules/tslib/tslib.js:115:75 2020-12-08T23:15:37: at new Promise (<anonymous>) 2020-12-08T23:15:37: at Object.__awaiter (/var/www/socialcomm/source/server/node_modules/tslib/tslib.js:111:16) 2020-12-08T23:15:37: at RetryHandler.sendEventsWithRetry (/var/www/socialcomm/source/server/node_modules/@amplitude/node/dist/src/retryHandler.js:40:24)
If a user has an OS user property set from an event logged via the client-side library, then a subsequent event from the node library that omits user attributes in the payload should not override attributes with empty strings, namely the os_name attribute.
Starting with a client event we get:
and after sending the node event we get an empty string that overrides the User's OS attribute:
Somewhere in the API2 service the absence of an os_name
in the payload is being interpreted as an empty string and that should be resolved.
Please see here for a simple React application demonstrating this bug.
src/App.js
file with an appropriate Amplitude Project API keyyarn start
Tried to set a user property to true
/false
Boolean user property didn't get set in Amplitude using @amplitude/identify
library. As a workaround, I've been casting to string
first before calling amplitudeClient.identify()
.
Tried doing something like:
const identify = new Identify();
identify.set("someProperty", true);
amplitudeClient.identify(userId, deviceId, identify);
to set someProperty
user property to true
but it didn't get set.
As a workaround, am currently doing:
const identify = new Identify();
identify.set("someProperty", String(true));
amplitudeClient.identify(userId, deviceId, identify);
to get it set.
Some packages are marked with sideEffects: false
even when there might be side effects (e.g. appending to the global variable) and some are not marked with any pattern for sideEffects
- which may cause issues for dead code elimination.
Mostly an investigation on how well we're doing in this area + a few minor cleanups in a few repos.
Also, set the precedence for how to handle + investigate + audit this later on and record it somewhere (internal threads, readme, etc.)
Smaller code bundles :)
Deployed our app to Vercel with the latest @amplitude/node installed; received the following:
2021-01-30T00:59:37.035Z undefined ERROR Server is not listening Error: Cannot find module 'tslib'
Require stack:
- /var/task/node_modules/@amplitude/identify/dist/src/identify.js
- /var/task/node_modules/@amplitude/identify/dist/src/index.js
- /var/task/node_modules/@amplitude/node/dist/src/nodeClient.js
- /var/task/node_modules/@amplitude/node/dist/src/index.js
- /var/task/__sapper__/build/server/server.js
- /var/task/launcher.js
- /var/runtime/UserFunction.js
- /var/runtime/index.js
at Function.Module._resolveFilename (internal/modules/cjs/loader.js:815:15)
at Function.Module._load (internal/modules/cjs/loader.js:667:27)
at Module.require (internal/modules/cjs/loader.js:887:19)
at require (internal/modules/cjs/helpers.js:74:18)
at Object.<anonymous> (/var/task/node_modules/@amplitude/identify/dist/src/identify.js:3:15)
at Module._compile (internal/modules/cjs/loader.js:999:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)
at Module.load (internal/modules/cjs/loader.js:863:32)
at Function.Module._load (internal/modules/cjs/loader.js:708:14)
at Module.require (internal/modules/cjs/loader.js:887:19) {
code: 'MODULE_NOT_FOUND',
requireStack: [
'/var/task/node_modules/@amplitude/identify/dist/src/identify.js',
'/var/task/node_modules/@amplitude/identify/dist/src/index.js',
'/var/task/node_modules/@amplitude/node/dist/src/nodeClient.js',
'/var/task/node_modules/@amplitude/node/dist/src/index.js',
'/var/task/__sapper__/build/server/server.js',
'/var/task/launcher.js',
'/var/runtime/UserFunction.js',
'/var/runtime/index.js'
]
}
RequestId: 4fd597ba-c037-440f-bcd5-c5295200fe93 Error: Runtime exited with error: exit status 1
Runtime.ExitError
We rolled back to 1.1.1 and the issue was resolved.
Hey,
We are currently using the node SDK for amplitude in one of our backends. It seems that in order to log an event to amplitude, the device id or user id is required as specified here:
https://developers.amplitude.com/docs/http-api-v2#properties-1
Currently our backend does not track our users. We wanted to pass a variable for the device_id such as : service_server
which would just be the name of our backend.
const amplitude = init(AMPLITUDE_TOKEN, { device_id: AMPLITUDE_DEVICE_ID });
This would allow us to avoid passing the deviceId every time we want to log an event, which is not ideal since it is always the same anyways.
Don't hesitate to let me know if there is a better way of doing this. I'm new to using amplitude :)
I created a function for logging events in amplitude, the response I get is
{ status: 'success', statusCode: 200, body: { eventsIngested: 2, payloadSizeBytes: 539, serverUploadTime: 1654620336284 } }
But when entering the Amplitued dashboard, I can't find it
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.