Skip to content

Commit ba1bee1

Browse files
authored
fix(analytics): improve dapp details tracking and SDK RPC request analytics (#1179)
* feat: add analytics tracking for SDK RPC requests - Implemented analytics tracking for SDK RPC requests when not sending via network. - Integrated SendAnalytics function to log SDK_RPC_REQUEST events with relevant parameters. * refactor: improve analytics event handling and caching logic - Removed deprecated SDK version ID and updated channelId declaration to use const. - Enhanced caching logic for channel information, ensuring validation of cached data. - Added logging for cases with empty cached channel info to improve debugging. - Refactored incrementRedisCacheOperation calls for better readability.
1 parent 86052b0 commit ba1bee1

File tree

2 files changed

+48
-8
lines changed

2 files changed

+48
-8
lines changed

packages/sdk-socket-server-next/src/analytics-api.ts

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,6 @@ import {
2828

2929
const logger = getLogger();
3030

31-
// SDK version prev 0.27.0 uses 'sdk' as the default id, below value is the sha1 hash of 'sdk'
32-
const SDK_EXTENSION_DEFAULT_ID = '5a374dcd2e5eb762b527af3a5bab6072a4d24493';
33-
3431
// Initialize Redis Cluster client
3532
let redisNodes: {
3633
host: string;
@@ -246,7 +243,7 @@ app.post('/evt', evtMetricsMiddleware, async (_req, res) => {
246243
return res.status(400).json({ error: 'wrong event name' });
247244
}
248245

249-
let channelId: string = body.id || 'sdk';
246+
const channelId: string = body.id || 'sdk';
250247
// Prevent caching of events coming from extension since they are not re-using the same id and prevent increasing redis queue size.
251248
let isExtensionEvent = body.from === 'extension';
252249

@@ -272,7 +269,10 @@ app.post('/evt', evtMetricsMiddleware, async (_req, res) => {
272269
? crypto.createHash('sha1').update(channelId).digest('hex')
273270
: await pubClient.get(channelId);
274271

275-
incrementRedisCacheOperation('analytics-get-channel-id', !!userIdHash);
272+
incrementRedisCacheOperation(
273+
'analytics-get-channel-id',
274+
Boolean(userIdHash),
275+
);
276276

277277
if (!userIdHash) {
278278
userIdHash = crypto.createHash('sha1').update(channelId).digest('hex');
@@ -294,23 +294,40 @@ app.post('/evt', evtMetricsMiddleware, async (_req, res) => {
294294
await inspectRedis(channelId);
295295
}
296296

297-
let channelInfo: ChannelInfo | null;
297+
let channelInfo: ChannelInfo | null = null;
298298
const cachedChannelInfo = isAnonUser
299299
? null
300300
: await pubClient.get(userIdHash);
301301

302+
// Potential issue because we may have a cached channel info but the url inside may be empty and dappId "N/A".
303+
// We then need to actually fully parse the string and extract the channelInfo object to validate the url and dappId.
304+
const hasCachedChannelInfo = Boolean(cachedChannelInfo);
305+
302306
incrementRedisCacheOperation(
303307
'analytics-get-channel-info',
304-
!!cachedChannelInfo,
308+
hasCachedChannelInfo,
305309
);
306310

311+
let hasValidCachedChannelInfo = false;
312+
307313
if (cachedChannelInfo) {
308314
logger.debug(
309315
`Found cached channel info for ${userIdHash}`,
310316
cachedChannelInfo,
311317
);
312318
channelInfo = JSON.parse(cachedChannelInfo);
313-
} else {
319+
hasValidCachedChannelInfo =
320+
channelInfo !== null &&
321+
Boolean(channelInfo.url && channelInfo.url.length > 0);
322+
323+
if (!hasValidCachedChannelInfo) {
324+
logger.warn(
325+
`event: ${body.event} channelId: ${channelId} - empty cached channel info for ${userIdHash} dAppId=${channelInfo?.dappId}`,
326+
);
327+
}
328+
}
329+
330+
if (!hasValidCachedChannelInfo) {
314331
logger.info(
315332
`event: ${body.event} channelId: ${channelId} - No cached channel info found for ${userIdHash}`,
316333
);

packages/sdk/src/services/RemoteCommunicationPostMessageStream/write.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
import {
2+
TrackingEvents,
3+
SendAnalytics,
4+
DEFAULT_SERVER_URL,
5+
} from '@metamask/sdk-communication-layer';
16
import { RemoteCommunicationPostMessageStream } from '../../PostMessageStream/RemoteCommunicationPostMessageStream';
27
import { METHODS_TO_REDIRECT, RPC_METHODS } from '../../config';
38
import {
@@ -67,6 +72,24 @@ export async function write(
6772
.catch((err: unknown) => {
6873
logger(`[RCPMS: _write()] error sending message`, err);
6974
});
75+
} else {
76+
try {
77+
// Only send analytics if we are not sending via network.
78+
await SendAnalytics(
79+
{
80+
id: channelId,
81+
event: TrackingEvents.SDK_RPC_REQUEST,
82+
params: {
83+
method: targetMethod,
84+
from: 'mobile',
85+
},
86+
},
87+
instance.state.remote?.state.communicationServerUrl ??
88+
DEFAULT_SERVER_URL,
89+
);
90+
} catch (error) {
91+
logger(`[RCPMS: _write()] error sending analytics`, error);
92+
}
7093
}
7194

7295
if (!isSecure) {

0 commit comments

Comments
 (0)