Skip to content

Commit

Permalink
Merge pull request #17 from mixpanel/jake-values-shift-left
Browse files Browse the repository at this point in the history
Properly map cohort properties
  • Loading branch information
JakeWymer authored Sep 14, 2023
2 parents 2dd4103 + ec97b82 commit 7869171
Show file tree
Hide file tree
Showing 8 changed files with 68 additions and 10 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ creds.json
/tmp/*
!tmp/.gitkeep
.env
env.js
env.js
env.gs
2 changes: 1 addition & 1 deletion Code.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
-----------------------------
*/

const APP_VERSION = "1.15";
const APP_VERSION = "1.16";

/**
* some important things to know about google apps script
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
connect your google sheet with mixpanel! no coding required!

[Install Now!](https://workspace.google.com/marketplace/app/sheets_%E2%87%94_mixpanel/1078767167468)
See sample data [here](https://docs.google.com/spreadsheets/d/1-9ifFSMDk4DUrNHyUgl0L-aIxxVjno5dPkJReu0E-nk/edit?usp=sharing)

<div id="tldr"></div>

Expand Down
7 changes: 4 additions & 3 deletions components/dataExport.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ DATA OUT OF MP
* export data; if not called with a config, uses last known
*
* @param {MpSheetConfig} [config]
* @returns {[string, ReportMeta | CohortMeta | DashMeta]} string + metadata `[csv, {}]`
* @returns {[string | string[][], ReportMeta | CohortMeta | DashMeta]} string + metadata `[csv, {}]`
*/
function exportData(config) {
//use last known config if unset
Expand All @@ -33,7 +33,7 @@ function exportData(config) {
try {
const meta = getCohortMeta(config);
const profiles = getCohort(config);
const csv = JSONtoCSV(profiles);
const csv = profilesToCsvArray(profiles);
return [csv, meta];
} catch (e) {
throw e;
Expand Down Expand Up @@ -65,6 +65,7 @@ function exportData(config) {

throw `${type} is unsupported`;
}

/**
* @param {MpSheetConfig} config
* @returns {DashMeta}
Expand Down Expand Up @@ -394,5 +395,5 @@ if (typeof module !== "undefined") {
module.exports = { exportData };
const { getConfig } = require("../utilities/storage.js");
const { validateCreds } = require("../utilities/validate.js");
const { JSONtoCSV } = require("../utilities/misc.js");
const { JSONtoCSV, profilesToCsvArray } = require("../utilities/misc.js");
}
17 changes: 17 additions & 0 deletions env-sample.js
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,23 @@ const TEST_CONFIG_GROUPS_DATA = [
}
];

/** @type {SheetMpConfigAlways & EventMappings} */
const TEST_CONFIG_AD_SPENT = {
config_type: "sheet-to-mixpanel",
record_type: "event",
event_name_col: "hardcode",
hardcode_event_name: "ad spent",
distinct_id_col: "",
time_col: "timestamp",
insert_id_col: "campaign id",
project_id: PROJECT_ID,
token: TOKEN,
region: "US",
auth_type: "service_account",
service_acct: SERVICE_ACCOUNT,
service_secret: SERVICE_SECRET
};

/** @type {SheetMpConfigAlways & TableMappings} */
const TEST_CONFIG_TABLES = {
config_type: "sheet-to-mixpanel",
Expand Down
11 changes: 10 additions & 1 deletion tests/all.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,15 @@ function runTests() {
return Misc.JSONtoCSV([{ foo: "bar", baz: "qux" }]) === expected;
});

test.assert("turns profiles into string[][]", () => {
const expected = [
[`foo`, `baz`, `third`],
[`bar`, `qu,x`, ``],
[`bar`, ``, `exists`]
];
return JSON.stringify(Misc.profilesToCsvArray([{ foo: "bar", baz: "qu,x" }, {foo: "bar", third: "exists"}])) === JSON.stringify(expected);
});

test.assert("forms pretty dates?", () => {
const expected = `3/3/1901 @ 4:20am`;
return Misc.formatDate(new Date(1, 2, 3, 4, 20)) === expected;
Expand Down Expand Up @@ -218,7 +227,7 @@ function runTests() {
validateCreds(BAD_API_SECRET);
});

test.catchErr("THROWS: bad api project?", `Mismatch between project secret's project ID and URL project ID`, () => {
test.catchErr("THROWS: bad api project?", `Credentials in request did not match project_id URL parameter`, () => {
validateCreds(BAD_PROJECT_API_SECRET);
});

Expand Down
31 changes: 30 additions & 1 deletion utilities/misc.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,35 @@ function JSONtoCSV(arr) {
.join("\n");
}

/**
* @param {ProfileData[]} profiles
* @returns {string[][]}
*/
function profilesToCsvArray(profiles) {
const headers = new Set();

// Need to check all profile keys in case some are missing that prop
profiles.forEach(profile => {
Object.keys(profile).forEach(key => {
headers.add(key);
});
});

const headersArr = Array.from(headers);

const properties = [];

profiles.forEach(profile => {
const profileProps = headersArr.map(header => {
const prop = profile[header] !== undefined ? `${profile[header]}` : "";
return prop;
});
properties.push(profileProps);
})

return [headersArr, ...properties];
}

function sliceIntoChunks(arr, chunkSize = 2000) {
const res = [];
for (let i = 0; i < arr.length; i += chunkSize) {
Expand Down Expand Up @@ -105,5 +134,5 @@ function isObject(object) {
}

if (typeof module !== "undefined") {
module.exports = { comma, JSONtoCSV, sliceIntoChunks, formatDate, serial, isDeepEqual, isObject, clone };
module.exports = { comma, JSONtoCSV, sliceIntoChunks, formatDate, serial, isDeepEqual, isObject, clone, profilesToCsvArray };
}
6 changes: 3 additions & 3 deletions utilities/sheet.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,12 +108,12 @@ function getEmptyRow(sheet) {
/**
* overwrites the contents of a spreadsheet with new data
*
* @param {string} csvString
* @param {string | string[][]} csv
* @param {GoogleAppsScript.Spreadsheet.Sheet} sheet
* @returns {SheetInfo}
*/
function overwriteSheet(csvString, sheet) {
var csvData = Utilities.parseCsv(csvString);
function overwriteSheet(csv, sheet) {
const csvData = typeof csv === `string` ? Utilities.parseCsv(csv) : csv;
sheet.getRange(1, 1, csvData.length, csvData[0].length).setValues(csvData);
return getSheetInfo(sheet);
}
Expand Down

0 comments on commit 7869171

Please sign in to comment.