@@ -2,6 +2,7 @@ import { v4 as uuidv4 } from 'uuid';
22import got from 'got' ;
33import { app , nativeTheme , screen } from 'electron' ;
44import os from 'os' ;
5+ import net from 'net' ;
56import pTimeout from 'p-timeout' ;
67import { appConf } from './store' ;
78import { logMain } from './logger' ;
@@ -28,15 +29,23 @@ class Analytics {
2829 private customParams : Record < string , unknown > = { } ;
2930 private userProperties : Record < string , unknown > | null = null ;
3031 private device : DeviceInfo ;
32+ private publicIp : string = '' ;
3133
3234 private baseURL = 'https://www.google-analytics.com/mp' ;
3335 private collectURL = '/collect' ;
3436
35- constructor ( trackingId : string , secretKey : string , clientId ?: string , sessionId ?: string ) {
37+ constructor (
38+ trackingId : string ,
39+ secretKey : string ,
40+ clientId ?: string ,
41+ sessionId ?: string ,
42+ publicIp ?: string ,
43+ ) {
3644 this . trackingId = trackingId ;
3745 this . secretKey = secretKey ;
3846 this . clientId = clientId ;
3947 this . sessionId = sessionId ;
48+ this . publicIp = publicIp ;
4049
4150 const platformMap : Record < string , string > = {
4251 darwin : 'MacOS' ,
@@ -99,24 +108,26 @@ class Analytics {
99108 }
100109
101110 event ( eventName : string , params ?: Record < string , unknown > ) {
102- const payload = {
103- client_id : this . clientId ,
104- events : [
105- {
106- name : eventName ,
107- params : {
108- session_id : this . sessionId ,
109- ...this . customParams ,
110- ...params ,
111+ const payload = JSON . parse (
112+ JSON . stringify ( {
113+ client_id : this . clientId ,
114+ events : [
115+ {
116+ name : eventName ,
117+ params : {
118+ session_id : this . sessionId ,
119+ ...this . customParams ,
120+ ...params ,
121+ } ,
111122 } ,
112- } ,
113- ] ,
114- device : this . device ,
115- } ;
123+ ] ,
124+ user_properties : this . userProperties ,
125+ device : this . device ,
126+ ip_override : this . publicIp ,
127+ } ) ,
128+ ) ;
116129
117- if ( this . userProperties ) {
118- Object . assign ( payload , { user_properties : this . userProperties } ) ;
119- }
130+ console . log ( ' ??? payload:' , payload ) ;
120131
121132 return got . post (
122133 `${ this . baseURL } ${ this . collectURL } ?measurement_id=${ this . trackingId } &api_secret=${ this . secretKey } ` ,
@@ -150,7 +161,27 @@ class Tracker {
150161 }
151162 }
152163
153- init ( ) {
164+ private async fetchPublicIp ( ) {
165+ const services = [ 'https://api.ip.sb/ip' , 'https://ifconfig.me/ip' ] ;
166+
167+ for ( const service of services ) {
168+ try {
169+ const response = await got . get ( service , { timeout : 10000 } ) ;
170+ const ip = response . body . trim ( ) ;
171+ if ( ip && net . isIP ( ip ) ) {
172+ logMain . info ( '[track.fetchPublicIp] success:' , ip ) ;
173+ return ip ;
174+ }
175+ } catch ( err ) {
176+ logMain . warn ( `[track.fetchPublicIp] failed from ${ service } :` , err ) ;
177+ continue ;
178+ }
179+ }
180+ logMain . warn ( '[track.fetchPublicIp] all services failed' ) ;
181+ return undefined ;
182+ }
183+
184+ async init ( ) {
154185 let uid = appConf . get ( 'uid' ) ;
155186 if ( ! uid ) {
156187 uid = appConf . get ( 'uid' ) || uuidv4 ( ) ;
@@ -160,7 +191,8 @@ class Tracker {
160191
161192 if ( process . env . GA_TC && process . env . GA_MP ) {
162193 logMain . info ( '[track.init] initializing GA' ) ;
163- this . analytics = new Analytics ( process . env . GA_TC , process . env . GA_MP , uid , uuidv4 ( ) ) ;
194+ const publicIp = await this . fetchPublicIp ( ) ;
195+ this . analytics = new Analytics ( process . env . GA_TC , process . env . GA_MP , uid , uuidv4 ( ) , publicIp ) ;
164196 this . analytics . setUserProperties ( {
165197 app_version : {
166198 value : app . getVersion ( ) ,
0 commit comments