diff --git a/integrations/messenger/integration.definition.ts b/integrations/messenger/integration.definition.ts index ff8316f67db..6795447305e 100644 --- a/integrations/messenger/integration.definition.ts +++ b/integrations/messenger/integration.definition.ts @@ -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 diff --git a/integrations/messenger/src/index.ts b/integrations/messenger/src/index.ts index 915fcdb24d3..9c6cf6bd4c8 100644 --- a/integrations/messenger/src/index.ts +++ b/integrations/messenger/src/index.ts @@ -19,6 +19,7 @@ export default posthogHelper.wrapIntegration( integrationName: INTEGRATION_NAME, key: bp.secrets.POSTHOG_KEY, integrationVersion: INTEGRATION_VERSION, + rateLimitByFunction: { handler: 1 / 1000 }, }, integrationConfig ) diff --git a/integrations/whatsapp/integration.definition.ts b/integrations/whatsapp/integration.definition.ts index 17469424c0c..edc4e1b525d 100644 --- a/integrations/whatsapp/integration.definition.ts +++ b/integrations/whatsapp/integration.definition.ts @@ -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, diff --git a/integrations/whatsapp/src/index.ts b/integrations/whatsapp/src/index.ts index 915fcdb24d3..9c6cf6bd4c8 100644 --- a/integrations/whatsapp/src/index.ts +++ b/integrations/whatsapp/src/index.ts @@ -19,6 +19,7 @@ export default posthogHelper.wrapIntegration( integrationName: INTEGRATION_NAME, key: bp.secrets.POSTHOG_KEY, integrationVersion: INTEGRATION_VERSION, + rateLimitByFunction: { handler: 1 / 1000 }, }, integrationConfig ) diff --git a/packages/common/src/posthog/boolean-generator.test.ts b/packages/common/src/posthog/boolean-generator.test.ts index b2f9f6535bb..6bf7dd094f8 100644 --- a/packages/common/src/posthog/boolean-generator.test.ts +++ b/packages/common/src/posthog/boolean-generator.test.ts @@ -2,18 +2,18 @@ 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()) { @@ -21,16 +21,16 @@ describe('Boolean Generator', () => { } } - 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()) { @@ -38,7 +38,7 @@ describe('Boolean Generator', () => { } } - const truthyPercentage = (trueCount / CYCLES) * 100 - expect(truthyPercentage).toBe(100) + const truthyRatio = trueCount / CYCLES + expect(truthyRatio).toBe(1) }) }) diff --git a/packages/common/src/posthog/boolean-generator.ts b/packages/common/src/posthog/boolean-generator.ts index 06bcd079f88..fcf5bde430d 100644 --- a/packages/common/src/posthog/boolean-generator.ts +++ b/packages/common/src/posthog/boolean-generator.ts @@ -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 } diff --git a/packages/common/src/posthog/helper.ts b/packages/common/src/posthog/helper.ts index 9be26604ee8..1e16bdba9d7 100644 --- a/packages/common/src/posthog/helper.ts +++ b/packages/common/src/posthog/helper.ts @@ -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 } type WrapFunctionProps = { @@ -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) => { @@ -36,9 +47,14 @@ const createPostHogClient = (key: string, rateLimitPercentage: number = 100): Po }) } -export const sendPosthogEvent = async (props: EventMessage, config: PostHogConfig): Promise => { - const { key, integrationName, integrationVersion, rateLimitPercentage } = config - const client = createPostHogClient(key, rateLimitPercentage) +export const sendPosthogEvent = async ( + props: EventMessage, + config: PostHogConfig, + functionName?: string +): Promise => { + const { key, integrationName, integrationVersion } = config + const rateLimitRatio = getRateLimitRatio(config, functionName) + const client = createPostHogClient(key, rateLimitRatio) try { const signedProps: EventMessage = { ...props, @@ -126,7 +142,8 @@ function wrapFunction(props: WrapFunctionProps) { integrationVersion: config.integrationVersion, }, }, - config + config, + functionName ) return await fn(...args) @@ -151,7 +168,8 @@ function wrapFunction(props: WrapFunctionProps) { ...additionalProps, }, }, - config + config, + functionName ) throw thrown } @@ -182,7 +200,8 @@ function wrapHandler(fn: Function, config: PostHogConfig) { ...additionalProps, }, }, - config + config, + 'handler' ) return resp } @@ -198,7 +217,8 @@ function wrapHandler(fn: Function, config: PostHogConfig) { ...additionalProps, }, }, - config + config, + 'handler' ) return resp }