amplitude.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. const crypto = require('crypto');
  2. const geoip = require('fxa-geodb')();
  3. const fetch = require('node-fetch');
  4. const config = require('./config');
  5. const pkg = require('../package.json');
  6. const HOUR = 1000 * 60 * 60;
  7. function truncateToHour(timestamp) {
  8. return Math.floor(timestamp / HOUR) * HOUR;
  9. }
  10. function orderOfMagnitude(n) {
  11. return Math.floor(Math.log10(n));
  12. }
  13. function userId(fileId, ownerId) {
  14. const hash = crypto.createHash('sha256');
  15. hash.update(fileId);
  16. hash.update(ownerId);
  17. return hash.digest('hex').substring(32);
  18. }
  19. function location(ip) {
  20. try {
  21. return geoip(ip);
  22. } catch (e) {
  23. return {};
  24. }
  25. }
  26. function statUploadEvent(data) {
  27. const loc = location(data.ip);
  28. const event = {
  29. session_id: -1,
  30. country: loc.country,
  31. region: loc.state,
  32. user_id: userId(data.id, data.owner),
  33. app_version: pkg.version,
  34. time: truncateToHour(Date.now()),
  35. event_type: 'server_upload',
  36. user_properties: {
  37. download_limit: data.dlimit,
  38. time_limit: data.timeLimit,
  39. size: orderOfMagnitude(data.size),
  40. anonymous: data.anonymous
  41. },
  42. event_properties: {
  43. agent: data.agent
  44. },
  45. event_id: 0
  46. };
  47. return sendBatch([event]);
  48. }
  49. function statDownloadEvent(data) {
  50. const loc = location(data.ip);
  51. const event = {
  52. session_id: -1,
  53. country: loc.country,
  54. region: loc.state,
  55. user_id: userId(data.id, data.owner),
  56. app_version: pkg.version,
  57. time: truncateToHour(Date.now()),
  58. event_type: 'server_download',
  59. event_properties: {
  60. agent: data.agent,
  61. download_count: data.download_count,
  62. ttl: data.ttl
  63. },
  64. event_id: data.download_count
  65. };
  66. return sendBatch([event]);
  67. }
  68. function statDeleteEvent(data) {
  69. const loc = location(data.ip);
  70. const event = {
  71. session_id: -1,
  72. country: loc.country,
  73. region: loc.state,
  74. user_id: userId(data.id, data.owner),
  75. app_version: pkg.version,
  76. time: truncateToHour(Date.now()),
  77. event_type: 'server_delete',
  78. event_properties: {
  79. agent: data.agent,
  80. download_count: data.download_count,
  81. ttl: data.ttl
  82. },
  83. event_id: data.download_count + 1
  84. };
  85. return sendBatch([event]);
  86. }
  87. function clientEvent(event, ua, language, session_id, deltaT, platform, ip) {
  88. const loc = location(ip);
  89. const ep = event.event_properties || {};
  90. const up = event.user_properties || {};
  91. const event_properties = {
  92. browser: ua.browser.name,
  93. browser_version: ua.browser.version,
  94. status: ep.status,
  95. age: ep.age,
  96. downloaded: ep.downloaded,
  97. download_limit: ep.download_limit,
  98. duration: ep.duration,
  99. entrypoint: ep.entrypoint,
  100. file_count: ep.file_count,
  101. password_protected: ep.password_protected,
  102. referrer: ep.referrer,
  103. size: ep.size,
  104. time_limit: ep.time_limit,
  105. trigger: ep.trigger,
  106. ttl: ep.ttl,
  107. utm_campaign: ep.utm_campaign,
  108. utm_content: ep.utm_content,
  109. utm_medium: ep.utm_medium,
  110. utm_source: ep.utm_source,
  111. utm_term: ep.utm_term,
  112. experiment: ep.experiment,
  113. variant: ep.variant
  114. };
  115. const user_properties = {
  116. active_count: up.active_count,
  117. anonymous: up.anonymous,
  118. experiments: up.experiments,
  119. first_action: up.first_action
  120. };
  121. return {
  122. app_version: pkg.version,
  123. country: loc.country,
  124. device_id: event.device_id,
  125. event_properties,
  126. event_type: event.event_type,
  127. language,
  128. os_name: ua.os.name,
  129. os_version: ua.os.version,
  130. platform,
  131. region: loc.state,
  132. session_id,
  133. time: event.time + deltaT,
  134. user_id: event.user_id,
  135. user_properties
  136. };
  137. }
  138. async function sendBatch(events, timeout = 1000) {
  139. if (!config.amplitude_id) {
  140. return 200;
  141. }
  142. try {
  143. const result = await fetch('https://api.amplitude.com/batch', {
  144. method: 'POST',
  145. headers: { 'Content-Type': 'application/json' },
  146. body: JSON.stringify({
  147. api_key: config.amplitude_id,
  148. events
  149. }),
  150. timeout
  151. });
  152. return result.status;
  153. } catch (e) {
  154. return 500;
  155. }
  156. }
  157. module.exports = {
  158. statUploadEvent,
  159. statDownloadEvent,
  160. statDeleteEvent,
  161. clientEvent,
  162. sendBatch
  163. };