Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion integrations/messenger/integration.definition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { actions } from './definitions/actions'
import { messages } from './definitions/channels/channel/messages'

export const INTEGRATION_NAME = 'messenger'
export const INTEGRATION_VERSION = '5.1.4'
export const INTEGRATION_VERSION = '5.1.5'

const commonConfigSchema = z.object({
downloadMedia: z
Expand Down
1 change: 1 addition & 0 deletions integrations/messenger/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export default posthogHelper.wrapIntegration(
integrationName: INTEGRATION_NAME,
key: bp.secrets.POSTHOG_KEY,
integrationVersion: INTEGRATION_VERSION,
rateLimitByFunction: { handler: 1 / 1000 },
},
integrationConfig
)
2 changes: 1 addition & 1 deletion integrations/whatsapp/integration.definition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ const defaultBotPhoneNumberId = {
}

export const INTEGRATION_NAME = 'whatsapp'
export const INTEGRATION_VERSION = '4.8.1'
export const INTEGRATION_VERSION = '4.8.2'
export default new IntegrationDefinition({
name: INTEGRATION_NAME,
version: INTEGRATION_VERSION,
Expand Down
1 change: 1 addition & 0 deletions integrations/whatsapp/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export default posthogHelper.wrapIntegration(
integrationName: INTEGRATION_NAME,
key: bp.secrets.POSTHOG_KEY,
integrationVersion: INTEGRATION_VERSION,
rateLimitByFunction: { handler: 1 / 1000 },
},
integrationConfig
)
30 changes: 15 additions & 15 deletions packages/common/src/posthog/boolean-generator.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,43 +2,43 @@ import { describe, expect, test, beforeEach } from 'vitest'
import { useBooleanGenerator } from './boolean-generator'

describe('Boolean Generator', () => {
test.each([0, -10, 101, 50.5, NaN])('Should throw error for invalid percentage: %p', (percentage) => {
expect(() => useBooleanGenerator(percentage)).toThrow('Percentage must be an integer between 1 and 100')
test.each([0, -1, 1.1, NaN])('Should throw error for invalid ratio: %r', (ratio) => {
expect(() => useBooleanGenerator(ratio)).toThrow('Ratio must be a number between 0 and 1 (exclusive of 0)')
})

test.each([1, 10, 20, 30, 40, 50, 60, 70, 80, 90, 99].map((p) => ({ percentage: p })))(
'$percentage%% probability, should be true approximately $percentage%% the time',
({ percentage }) => {
test.each([0.01, 0.01, 0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09, 0.099].map((r) => ({ ratio: r })))(
'$ratio should be true approximately $ratio the time',
({ ratio }) => {
const CYCLES = 1000000
/** In percentage */
const TOLERANCE = 1
/** In Ratio */
const TOLERANCE = 0.01

let shouldAllow = useBooleanGenerator(percentage)
let shouldAllow = useBooleanGenerator(ratio)
let trueCount = 0
for (let i = 0; i < CYCLES; i++) {
if (shouldAllow()) {
trueCount++
}
}

const truthyPercentage = (trueCount / CYCLES) * 100
expect(truthyPercentage).toBeGreaterThan(percentage - TOLERANCE)
expect(truthyPercentage).toBeLessThan(percentage + TOLERANCE)
const truthyRatio = trueCount / CYCLES
expect(truthyRatio).toBeGreaterThan(ratio - TOLERANCE)
expect(truthyRatio).toBeLessThan(ratio + TOLERANCE)
}
)

test('100% probability, should be true all the time', () => {
test('Ratio of 1 should be true all the time', () => {
const CYCLES = 10000

let shouldAllow = useBooleanGenerator(100)
let shouldAllow = useBooleanGenerator(1)
let trueCount = 0
for (let i = 0; i < CYCLES; i++) {
if (shouldAllow()) {
trueCount++
}
}

const truthyPercentage = (trueCount / CYCLES) * 100
expect(truthyPercentage).toBe(100)
const truthyRatio = trueCount / CYCLES
expect(truthyRatio).toBe(1)
})
})
10 changes: 5 additions & 5 deletions packages/common/src/posthog/boolean-generator.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
export const useBooleanGenerator = (truthyPercentage: number): (() => boolean) => {
if (truthyPercentage <= 0 || truthyPercentage > 100 || !Number.isInteger(truthyPercentage)) {
throw new Error('Percentage must be an integer between 1 and 100')
export const useBooleanGenerator = (truthyRatio: number): (() => boolean) => {
if (truthyRatio <= 0 || truthyRatio > 1 || Number.isNaN(truthyRatio)) {
throw new Error('Ratio must be a number between 0 and 1 (exclusive of 0)')
}

if (truthyPercentage === 100) {
if (truthyRatio === 1) {
return () => true
}

const probability = truthyPercentage / 100
const probability = truthyRatio
return () => Math.random() <= probability
}
44 changes: 32 additions & 12 deletions packages/common/src/posthog/helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ export type PostHogConfig = {
key: string
integrationName: string
integrationVersion: string
/** An integer percentage between 1 and 100 which determines
* what percentage of events are allowed through. */
rateLimitPercentage?: number
/** A map of function names to their rate limit ratio (0-1 exclusive of 0).
* Use '*' as a wildcard key to set a default for all unlisted functions.
* Functions not listed (and no '*' key) default to 1 (no rate limiting). */
rateLimitByFunction?: Record<string, number>
}

type WrapFunctionProps = {
Expand All @@ -26,8 +27,18 @@ type WrapFunctionProps = {
functionArea: string
}

const createPostHogClient = (key: string, rateLimitPercentage: number = 100): PostHog => {
const shouldAllow = useBooleanGenerator(rateLimitPercentage)
const getRateLimitRatio = (config: PostHogConfig, functionName?: string): number => {
if (functionName && config.rateLimitByFunction?.[functionName] !== undefined) {
return config.rateLimitByFunction[functionName]
}
if (config.rateLimitByFunction?.['*'] !== undefined) {
return config.rateLimitByFunction['*']
}
return 1
}

const createPostHogClient = (key: string, rateLimitRatio: number = 1): PostHog => {
const shouldAllow = useBooleanGenerator(rateLimitRatio)
return new PostHog(key, {
host: 'https://us.i.posthog.com',
before_send: (event) => {
Expand All @@ -36,9 +47,14 @@ const createPostHogClient = (key: string, rateLimitPercentage: number = 100): Po
})
}

export const sendPosthogEvent = async (props: EventMessage, config: PostHogConfig): Promise<void> => {
const { key, integrationName, integrationVersion, rateLimitPercentage } = config
const client = createPostHogClient(key, rateLimitPercentage)
export const sendPosthogEvent = async (
props: EventMessage,
config: PostHogConfig,
functionName?: string
): Promise<void> => {
const { key, integrationName, integrationVersion } = config
const rateLimitRatio = getRateLimitRatio(config, functionName)
const client = createPostHogClient(key, rateLimitRatio)
try {
const signedProps: EventMessage = {
...props,
Expand Down Expand Up @@ -126,7 +142,8 @@ function wrapFunction(props: WrapFunctionProps) {
integrationVersion: config.integrationVersion,
},
},
config
config,
functionName
)

return await fn(...args)
Expand All @@ -151,7 +168,8 @@ function wrapFunction(props: WrapFunctionProps) {
...additionalProps,
},
},
config
config,
functionName
)
throw thrown
}
Expand Down Expand Up @@ -182,7 +200,8 @@ function wrapHandler(fn: Function, config: PostHogConfig) {
...additionalProps,
},
},
config
config,
'handler'
)
return resp
}
Expand All @@ -198,7 +217,8 @@ function wrapHandler(fn: Function, config: PostHogConfig) {
...additionalProps,
},
},
config
config,
'handler'
)
return resp
}
Expand Down
Loading