Skip to content

Commit b7c640d

Browse files
committed
refactor analytics and profile data handling for improved efficiency and logging
1 parent edc2273 commit b7c640d

3 files changed

Lines changed: 34 additions & 38 deletions

File tree

profile/analytics.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11

22

33
// --- Simple, robust analytics collector for profile actions with per-device, per-action timestamp checks ---
4+
console.log("[analytics.js] loaded");
45
const ANALYTICS_ENDPOINT = "https://script.google.com/macros/s/AKfycbw8tkRI9dHsspu07YS6agXF4wrT1X8tyt9_4D_TnbffQliyLdp1a71fPu197gw3tiWe/exec";
56

67
let analyticsProfile = { link: null };
@@ -15,6 +16,7 @@ let analyticsState = {
1516
};
1617

1718
function analyticsTracking(link, _email, status) {
19+
console.log("[analyticsTracking] called", { link, status });
1820
if (status !== "active") return;
1921
analyticsProfile = { link };
2022
loadAnalyticsState();

profile/main.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ const CONFIG = {
22
defaultBg: "url(https://tccards.tn/Assets/background.png) center fixed",
33
defaultProfilePic: "https://tccards.tn/Assets/default.png",
44
databases: {
5-
id: "AKfycbzPv8Rr4jM6Fcyjm6uelUtqw2hHLCFWYhXJlt6nWTIKaqUL_9j_41rwzhFGMlkF2nrG",
5+
id: "AKfycbw8tkRI9dHsspu07YS6agXF4wrT1X8tyt9_4D_TnbffQliyLdp1a71fPu197gw3tiWe",
66
plan: "basic",
77
},
88
styles: {
@@ -72,7 +72,7 @@ async function searchProfile(identifier, isIdLookup) {
7272

7373
// Helper function with timeout
7474
async function fetchWithTimeout(resource, options = {}) {
75-
const { timeout = 8000 } = options;
75+
const { timeout = 18000 } = options;
7676

7777
const controller = new AbortController();
7878
const id = setTimeout(() => controller.abort(), timeout);

profile/profile.gs

Lines changed: 30 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
function findRow(identifier, byId = false) {
2-
const CACHE_EXPIRATION = 300; // 5 minutes instead of 10
2+
const CACHE_EXPIRATION = 300; // 5 minutes
33
const cache = CacheService.getScriptCache();
4-
const cacheKey = (byId ? 'id_' : 'link_') + identifier.toLowerCase().trim();
5-
4+
const cacheKey = (byId ? 'id_' : 'link_') + identifier.trim();
5+
66
// Check cache
77
const cachedData = cache.get(cacheKey);
88
if (cachedData) {
@@ -19,48 +19,42 @@ function findRow(identifier, byId = false) {
1919
const sheet = spreadsheet.getSheetByName('Form');
2020
if (!sheet) throw new Error('Form sheet not found');
2121

22-
// Get data more efficiently
2322
const lastRow = sheet.getLastRow();
2423
const lastCol = sheet.getLastColumn();
2524
if (lastRow <= 1) return null; // No data rows
26-
27-
const data = sheet.getRange(1, 1, lastRow, lastCol).getValues();
28-
const headers = data[0];
29-
30-
// Clean and normalize identifier
31-
const cleanIdentifier = identifier.trim().toLowerCase();
25+
26+
const headers = sheet.getRange(1, 1, 1, lastCol).getValues()[0];
27+
const cleanIdentifier = identifier.trim();
3228
const columnName = byId ? 'ID' : 'Link';
3329
const columnIndex = headers.findIndex(h => h.toString().trim() === columnName);
3430
if (columnIndex === -1) throw new Error(`${columnName} column not found`);
3531

36-
// Search for match
37-
for (let i = 1; i < data.length; i++) {
38-
const rowValue = String(data[i][columnIndex]).trim().toLowerCase();
39-
const toCompare = byId ? cleanIdentifier : cleanIdentifier.replace(/^@/, '');
40-
41-
if (rowValue === toCompare || (!byId && rowValue === `@${toCompare}`)) {
42-
const responseData = {};
43-
headers.forEach((header, index) => {
44-
// Basic data cleaning
45-
responseData[header] = data[i][index] !== null ?
46-
String(data[i][index]).trim() : '';
47-
});
48-
49-
// Validate required fields
50-
if (!responseData.Name) {
51-
throw new Error('Profile data missing required Name field');
52-
}
53-
54-
try {
55-
cache.put(cacheKey, JSON.stringify(responseData), CACHE_EXPIRATION);
56-
} catch (e) {
57-
console.error('Failed to cache data:', e);
58-
}
59-
60-
return responseData;
32+
// Use TextFinder for efficient, case-sensitive search
33+
const colRange = sheet.getRange(2, columnIndex + 1, lastRow - 1, 1); // skip header
34+
const toCompare = byId ? cleanIdentifier : cleanIdentifier.replace(/^@/, '');
35+
let found = colRange.createTextFinder(toCompare).matchCase(true).matchEntireCell(true).findNext();
36+
// If not found, try with @ prefix (for link only)
37+
if (!found && !byId && !toCompare.startsWith('@')) {
38+
found = colRange.createTextFinder('@' + toCompare).matchCase(true).matchEntireCell(true).findNext();
39+
}
40+
if (found) {
41+
const rowIdx = found.getRow();
42+
const rowData = sheet.getRange(rowIdx, 1, 1, lastCol).getValues()[0];
43+
const responseData = {};
44+
headers.forEach((header, index) => {
45+
responseData[header] = rowData[index] !== null ? String(rowData[index]).trim() : '';
46+
});
47+
// Validate required fields
48+
if (!responseData.Name) {
49+
throw new Error('Profile data missing required Name field');
50+
}
51+
try {
52+
cache.put(cacheKey, JSON.stringify(responseData), CACHE_EXPIRATION);
53+
} catch (e) {
54+
console.error('Failed to cache data:', e);
6155
}
56+
return responseData;
6257
}
63-
6458
return null;
6559
}
6660

0 commit comments

Comments
 (0)