From ccbdc8cf090eabcda451c81ff850acfe8632805f Mon Sep 17 00:00:00 2001 From: Marius Andra Date: Sat, 26 Oct 2024 00:31:31 +0200 Subject: [PATCH] Revert "remove broadcast code" This reverts commit 56bc99988e758e278b70a4a7b6ae0d066977a16c. --- frontend/src/lib/api.ts | 3 ++ .../hogfunctions/HogFunctionConfiguration.tsx | 33 +++++++++++++++++++ .../hogFunctionConfigurationLogic.tsx | 17 ++++++++++ posthog/api/hog_function.py | 31 +++++++++++++++++ 4 files changed, 84 insertions(+) diff --git a/frontend/src/lib/api.ts b/frontend/src/lib/api.ts index d6760ce8d2abe..3cc573f88a14e 100644 --- a/frontend/src/lib/api.ts +++ b/frontend/src/lib/api.ts @@ -1760,6 +1760,9 @@ const api = { async update(id: HogFunctionType['id'], data: Partial): Promise { return await new ApiRequest().hogFunction(id).update({ data }) }, + async sendBroadcast(id: HogFunctionType['id']): Promise { + return await new ApiRequest().hogFunction(id).withAction('broadcast').create() + }, async logs( id: HogFunctionType['id'], params: LogEntryRequestParams = {} diff --git a/frontend/src/scenes/pipeline/hogfunctions/HogFunctionConfiguration.tsx b/frontend/src/scenes/pipeline/hogfunctions/HogFunctionConfiguration.tsx index a27181b3e77c7..94c10958d397c 100644 --- a/frontend/src/scenes/pipeline/hogfunctions/HogFunctionConfiguration.tsx +++ b/frontend/src/scenes/pipeline/hogfunctions/HogFunctionConfiguration.tsx @@ -69,6 +69,7 @@ export function HogFunctionConfiguration({ templateId, id }: HogFunctionConfigur templateHasChanged, forcedSubTemplateId, type, + broadcastLoading, } = useValues(logic) const { submitConfiguration, @@ -80,6 +81,7 @@ export function HogFunctionConfiguration({ templateId, id }: HogFunctionConfigur setConfigurationValue, deleteHogFunction, setSubTemplateId, + sendBroadcast, } = useActions(logic) if (loading && !loaded) { @@ -493,6 +495,37 @@ export function HogFunctionConfiguration({ templateId, id }: HogFunctionConfigur )} {!id || id === 'new' ? : } + + {type === 'broadcast' ? ( + id && id !== 'new' ? ( + + + Send to {personsCount} emails + +
+ Please note: Clicking the button above will + synchronously send to all the e-mails. While this is fine for + testing with small lists, please don't use this for production + usecases yet. +
+ + } + /> + ) : ( + + ) + ) : null} +
{saveButtons}
diff --git a/frontend/src/scenes/pipeline/hogfunctions/hogFunctionConfigurationLogic.tsx b/frontend/src/scenes/pipeline/hogfunctions/hogFunctionConfigurationLogic.tsx index 93d6359d349ca..6599b4d45bdec 100644 --- a/frontend/src/scenes/pipeline/hogfunctions/hogFunctionConfigurationLogic.tsx +++ b/frontend/src/scenes/pipeline/hogfunctions/hogFunctionConfigurationLogic.tsx @@ -188,6 +188,7 @@ export const hogFunctionConfigurationLogic = kea ({ configuration }), persistForUnload: true, setSampleGlobalsError: (error) => ({ error }), + sendBroadcast: true, }), reducers({ showSource: [ @@ -402,6 +403,22 @@ export const hogFunctionConfigurationLogic = kea { + const id = values.hogFunction?.id + if (!id) { + lemonToast.error('No broadcast to send') + return false + } + await api.hogFunctions.sendBroadcast(id) + lemonToast.success('Broadcast sent!') + return true + }, + }, + ], })), forms(({ values, props, asyncActions }) => ({ configuration: { diff --git a/posthog/api/hog_function.py b/posthog/api/hog_function.py index 83f81ca2e63df..fe23a65d6f687 100644 --- a/posthog/api/hog_function.py +++ b/posthog/api/hog_function.py @@ -23,6 +23,7 @@ from posthog.cdp.templates import HOG_FUNCTION_TEMPLATES_BY_ID from posthog.cdp.validation import compile_hog, generate_template_bytecode, validate_inputs, validate_inputs_schema from posthog.constants import AvailableFeature +from posthog.hogql_queries.actors_query_runner import ActorsQueryRunner from posthog.models.activity_logging.activity_log import log_activity, changes_between, Detail from posthog.models.hog_functions.hog_function import HogFunction, HogFunctionState from posthog.plugins.plugin_server_api import create_hog_invocation_test @@ -305,6 +306,36 @@ def invocations(self, request: Request, *args, **kwargs): return Response(res.json()) + @action(detail=True, methods=["POST"]) + def broadcast(self, request: Request, *args, **kwargs): + hog_function = self.get_object() + actors_query = { + "kind": "ActorsQuery", + "properties": hog_function.filters.get("properties", None), + "select": ["id", "any(pdi.distinct_id)", "properties", "created_at"], + } + + response = ActorsQueryRunner(query=actors_query, team=self.team).calculate() + + for result in response.results: + globals = { + "person": { + "id": str(result[0]), + "distinct_id": str(result[1]), + "properties": json.loads(result[2]), + "created_at": result[3].isoformat(), + } + } + create_hog_invocation_test( + team_id=hog_function.team_id, + hog_function_id=hog_function.id, + globals=globals, + configuration=HogFunctionSerializer(hog_function).data, + mock_async_functions=False, + ) + + return Response({"success": True}) + def perform_create(self, serializer): serializer.save() log_activity(