Skip to content

Commit

Permalink
include mailing_version in posthog analytics (#401)
Browse files Browse the repository at this point in the history
* implement the comment, not sure why this was never implemented?

* scripts/prepare-release sed's in MAILING_VERSION

* send mailing_version with events to posthog

* try it here

* include mailing version and mailing core version in server side events

* use 0.9.5-next.0 in cli and web

* Revert "use 0.9.5-next.0 in cli and web"

This reverts commit 08fe115.

* update tests and ignore undefined

* read the versions from package.json

* refactor capture and test core

* cli actually does expect to send in dev, oops

* test vercel deploy

* revert

* return early if POSTHOG_API_KEY to avoid throwing page errors & 401's if POSTHOG_API_KEY is undefined

* test api/sendMail

* Revert "test api/sendMail"

This reverts commit acfa8da.

* load consts in next components with project paths so they load from node_modules in an installed app (where they've been replaced with string literals)

* export MAILING_VERSION and POSTHOG_API_KEY from packages/cli/src/index.ts and import those from "mailing" in the frontend tsx

* move cli code from index.ts -> cli.ts

* Revert "move cli code from index.ts -> cli.ts"

This reverts commit 6a4096f.

* Revert "export MAILING_VERSION and POSTHOG_API_KEY from packages/cli/src/index.ts and import those from "mailing" in the frontend tsx"

This reverts commit ab7eb75.

* Revert "load consts in next components with project paths so they load from node_modules in an installed app (where they've been replaced with string literals)"

This reverts commit 6922bca.

* search and replace in release script (and then undo after release)

* wwooops

* mailing-core should more properly add mailing_core_version

* fix test

* try to fix error when using mailing-core in production:

mailing calling capture with {"event":"mail sent","distinctId":"unknown","properties":{"mailing_version":"0.9.6-next.0","recipientCount":1,"analyticsEnabled":false}}
mailing posthog capture error TypeError: Cannot read properties of undefined (reading 'reInit')
    at PostHog.capture (/var/task/node_modules/posthog-node/lib/index.cjs.js:2043:10)
    at _callee$ (/var/task/.mailing/.next/server/chunks/3414.js:727:13)
    at tryCatch (/var/task/.mailing/.next/server/chunks/3414.js:167:17)
    at Generator._invoke (/var/task/.mailing/.next/server/chunks/3414.js:150:24)
    at Generator.next (/var/task/.mailing/.next/server/chunks/3414.js:192:21)
    at asyncGeneratorStep (/var/task/.mailing/.next/server/chunks/3414.js:457:24)
    at _next (/var/task/.mailing/.next/server/chunks/3414.js:476:9)
    at /var/task/.mailing/.next/server/chunks/3414.js:481:7
    at new Promise (<anonymous>)
    at /var/task/.mailing/.next/server/chunks/3414.js:473:12

* better type

* changeset

* now that we are searching and replacing in src, it's unneccessary to search and replace in dist.  this is the same and simpler / less code

* update snapshots
  • Loading branch information
alexfarrill authored Dec 9, 2022
1 parent 37c6a82 commit 164940f
Show file tree
Hide file tree
Showing 13 changed files with 197 additions and 28 deletions.
7 changes: 7 additions & 0 deletions .changeset/slow-roses-destroy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"mailing": patch
"mailing-core": patch
"web": patch
---

To better help us improve mailing, anonymous analytics now includes the version of mailing and mailing-core that you are using.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
"prepublish": "yarn build",
"postinstall": "husky install && preconstruct dev",
"watch": "preconstruct watch",
"release": "yarn build && ./scripts/prepare-release && yarn changeset publish"
"release": "./scripts/release"
},
"devDependencies": {
"@babel/core": "^7.18.5",
Expand Down
12 changes: 9 additions & 3 deletions packages/cli/src/components/PosthogScript.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { POSTHOG_API_KEY } from "../util/postHog/posthogApiKey";
import { MAILING_VERSION } from "../const/mailingVersion";

export default function PosthogScript() {
if (process.env.NODE_ENV !== "production") {
if (process.env.NODE_ENV !== "production" || POSTHOG_API_KEY === undefined) {
return null;
}

Expand All @@ -12,8 +13,13 @@ export default function PosthogScript() {
dangerouslySetInnerHTML={{
__html: `
${loadPosthogScript}
posthog.init('${POSTHOG_API_KEY}', {api_host: 'https://app.posthog.com'})
`,
posthog.init('${POSTHOG_API_KEY}', {
api_host: 'https://app.posthog.com',
loaded: function(posthog) {
posthog.register({ 'mailing_version': '${MAILING_VERSION}' });
}
});`,
}}
></script>
);
Expand Down
1 change: 1 addition & 0 deletions packages/cli/src/const/mailingVersion.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const MAILING_VERSION = process.env.MAILING_VERSION;
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { PostHog } from "posthog-node";
describe("postHog", () => {
const MM_DEV_OG = process.env.MM_DEV;
const MM_DEV_E2E_OG = process.env.MM_E2E;

let mockPostHogClient: PostHog;
let mockPostHogClientWithShutdownError: PostHog;

Expand Down Expand Up @@ -48,6 +49,7 @@ describe("postHog", () => {
expect(mockPostHogClient.capture).toHaveBeenCalledWith({
distinctId: "abc",
event: "ate pizza",
properties: {},
});
});

Expand All @@ -69,6 +71,7 @@ describe("postHog", () => {
expect(mockPostHogClient.capture).toHaveBeenCalledWith({
distinctId: "config-xyz",
event: "ate pizza",
properties: {},
});
});

Expand All @@ -88,6 +91,7 @@ describe("postHog", () => {
expect(mockPostHogClient.capture).toHaveBeenCalledWith({
distinctId: "generated-xyz",
event: "ate pizza",
properties: {},
});
});

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { capture } from "..";
import * as postHogClient from "../client";
import { PostHog } from "posthog-node";

jest.mock("../../../const/mailingVersion", () => ({
MAILING_VERSION: "mock-mailing-version",
}));

describe("posthog", () => {
const MM_DEV_OG = process.env.MM_DEV;
const MM_DEV_E2E_OG = process.env.MM_E2E;

let mockPostHogClient: PostHog;
beforeEach(() => {
mockPostHogClient = { capture: jest.fn() } as unknown as PostHog;
jest.restoreAllMocks();
delete process.env.MM_DEV;
delete process.env.MM_E2E;
});

afterEach(() => {
process.env.MM_DEV = MM_DEV_OG;
process.env.MM_E2E = MM_DEV_E2E_OG;
});

it("should include MAILING_VERSION because it is defined", () => {
jest
.spyOn(postHogClient, "postHogClient")
.mockImplementation(() => mockPostHogClient);

capture({
distinctId: "abc",
event: "ate pizza",
});

expect(mockPostHogClient.capture).toHaveBeenCalledWith({
distinctId: "abc",
event: "ate pizza",
properties: {
mailing_version: "mock-mailing-version",
},
});
});
});
5 changes: 5 additions & 0 deletions packages/cli/src/util/postHog/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { getConfig } from "../moduleManifestUtil";
import { getGeneratedAnonymousId } from "../config/anonymousId";

import { postHogClient, getPostHogClient } from "./client";
import { MAILING_VERSION } from "../../const/mailingVersion";

// ** modified from posthog-node
interface IdentifyMessageV1 {
Expand Down Expand Up @@ -35,6 +36,10 @@ export function capture(options: EventMessageV1) {
const captureOpts = {
...options,
distinctId,
properties: {
mailing_version: MAILING_VERSION,
...options.properties,
},
};

debug(`calling capture with ${JSON.stringify(captureOpts)}`);
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/const/mailingCoreVersion.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const MAILING_CORE_VERSION = process.env.MAILING_CORE_VERSION;
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { capture } from "..";
import * as postHogClient from "../client";
import { PostHog } from "posthog-node";

jest.mock("../../../const/mailingCoreVersion", () => ({
MAILING_CORE_VERSION: "mock-mailing-core-version",
}));

describe("posthog", () => {
const MM_DEV_OG = process.env.MM_DEV;
const MM_DEV_E2E_OG = process.env.MM_E2E;

let mockPostHogClient: PostHog;
beforeEach(() => {
mockPostHogClient = { capture: jest.fn() } as unknown as PostHog;
jest.restoreAllMocks();
delete process.env.MM_DEV;
delete process.env.MM_E2E;
});

afterEach(() => {
process.env.MM_DEV = MM_DEV_OG;
process.env.MM_E2E = MM_DEV_E2E_OG;
});

it("should include MAILING_CORE_VERSION because it is defined", async () => {
jest
.spyOn(postHogClient, "postHogClient")
.mockImplementation(() => mockPostHogClient);

await capture({
distinctId: "abc",
event: "ate pizza",
});

expect(mockPostHogClient.capture).toHaveBeenCalledWith({
distinctId: "abc",
event: "ate pizza",
properties: {
mailing_core_version: "mock-mailing-core-version",
},
});
});
});
3 changes: 2 additions & 1 deletion packages/core/src/util/postHog/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ const POSTHOG_API_KEY = process.env.POSTHOG_API_KEY;
let client: PostHog | undefined;

export function postHogClient(): PostHog | undefined {
if (process.env.MM_E2E || "test" === process.env.NODE_ENV) return;
if (process.env.MM_E2E || process.env.CI || "test" === process.env.NODE_ENV)
return;

if (undefined === POSTHOG_API_KEY) {
debug("POSTHOG_API_KEY is undefined");
Expand Down
28 changes: 23 additions & 5 deletions packages/core/src/util/postHog/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { MAILING_CORE_VERSION } from "../../const/mailingCoreVersion";
import { debug } from "../serverLogger";

import { postHogClient } from "./client";

// ** modified from posthog-node
Expand All @@ -14,13 +14,15 @@ interface EventMessageV1 extends IdentifyMessageV1 {
sendFeatureFlags?: boolean;
}
export async function capture(options: EventMessageV1) {
if (process.env.NODE_ENV !== "production") return;

const distinctId = options.distinctId;

const captureOpts = {
...options,
distinctId,
properties: {
mailing_core_version: MAILING_CORE_VERSION,
...options.properties,
},
};

debug(`calling capture with ${JSON.stringify(captureOpts)}`);
Expand All @@ -31,8 +33,24 @@ export async function capture(options: EventMessageV1) {
}

try {
postHogClient()?.capture(captureOpts);
await postHogClient()?.shutdownAsync();
const client = postHogClient();
if (!client) return;

if (process.env.NODE_ENV === "production") {
client.capture(captureOpts);
} else if (process.env.NODE_ENV === "test") {
// call capture if it has been mocked
const capture = client.capture as typeof client.capture & {
mock?: any;
};
if (capture.mock) capture(captureOpts);
} else {
debug(
`returning early from capture because NODE_ENV is ${process.env.NODE_ENV}`
);
}

await client.shutdownAsync();
} catch (e) {
debug("posthog capture error", e);
}
Expand Down
18 changes: 0 additions & 18 deletions scripts/prepare-release

This file was deleted.

56 changes: 56 additions & 0 deletions scripts/release
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#!/usr/bin/env bash

# load .env file
if [[ -f .env ]]; then
source .env
fi

# throw an error if $POSTHOG_API_KEY is not set
if [[ -z "$POSTHOG_API_KEY" ]]; then
echo "Must provide POSTHOG_API_KEY in environment" 1>&2
exit 1
fi

# set variables MAILING_VERSION and MAILING_CORE_VERSION to the value of the "version" attribute from each package.json
MAILING_VERSION=$(awk -F'"' '/"version": ".+"/{ print $4; exit; }' packages/cli/package.json)
MAILING_CORE_VERSION=$(awk -F'"' '/"version": ".+"/{ print $4; exit; }' packages/core/package.json)

# throw an error if $MAILING_VERSION is empty
if [[ -z "$MAILING_VERSION" ]]; then
echo "Failed to set MAILING_VERSION" 1>&2
exit 1
fi

# throw an error if $MAILING_CORE_VERSION is empty
if [[ -z "$MAILING_CORE_VERSION" ]]; then
echo "Must provide MAILING_CORE_VERSION in environment" 1>&2
exit 1
fi

##
# Search and replace in src directories -- these will be undone in the post-release script

# search cli and core src and replace "process.env.POSTHOG_API_KEY" with "\"${process.env.POSTHOG_API_KEY}\""
find 'packages/cli/src' 'packages/core/src' -type f \( -name '*.ts' -o -name '*.tsx' \) -exec sed -i '' "s/process\.env\.POSTHOG_API_KEY/\"$POSTHOG_API_KEY\"/g" {} +

# search cli src and replace "process.env.MAILING_VERSION" with "\"${process.env.MAILING_VERSION}\""
find 'packages/cli/src' -type f \( -name '*.ts' -o -name '*.tsx' \) -exec sed -i '' "s/MAILING_VERSION = process\.env\.MAILING_VERSION/MAILING_VERSION = \"$MAILING_VERSION\"/g" {} +

# search core src and replace "process.env.MAILING_CORE_VERSION" with "\"${process.env.MAILING_CORE_VERSION}\""
find 'packages/core/src' -type f \( -name '*.ts' -o -name '*.tsx' \) -exec sed -i '' "s/MAILING_CORE_VERSION = process\.env\.MAILING_CORE_VERSION/MAILING_CORE_VERSION = \"$MAILING_CORE_VERSION\"/g" {} +

## build packages
yarn build
yarn changeset publish

##
# Undo search and replace in src directories from above

# search cli and core src and replace "process.env.POSTHOG_API_KEY" with "\"${process.env.POSTHOG_API_KEY}\""
find 'packages/cli/src' 'packages/core/src' -type f \( -name '*.ts' -o -name '*.tsx' \) -exec sed -i '' "s/\"$POSTHOG_API_KEY\"/process\.env\.POSTHOG_API_KEY/g" {} +

# search cli src and replace "process.env.MAILING_VERSION" with "\"${process.env.MAILING_VERSION}\""
find 'packages/cli/src' -type f \( -name '*.ts' -o -name '*.tsx' \) -exec sed -i '' "s/MAILING_VERSION = \"$MAILING_VERSION\"/MAILING_VERSION = process\.env\.MAILING_VERSION/g" {} +

# search core src and replace "process.env.MAILING_CORE_VERSION" with "\"${process.env.MAILING_CORE_VERSION}\""
find 'packages/core/src' -type f \( -name '*.ts' -o -name '*.tsx' \) -exec sed -i '' "s/MAILING_CORE_VERSION = \"$MAILING_CORE_VERSION\"/MAILING_CORE_VERSION = process\.env\.MAILING_CORE_VERSION/g" {} +

1 comment on commit 164940f

@vercel
Copy link

@vercel vercel bot commented on 164940f Dec 9, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.