diff --git a/frontend/public/services/make.png b/frontend/public/services/make.png new file mode 100644 index 00000000000..1849c242cfa Binary files /dev/null and b/frontend/public/services/make.png differ diff --git a/posthog/cdp/templates/__init__.py b/posthog/cdp/templates/__init__.py index 43917a62e75..34b6d79311f 100644 --- a/posthog/cdp/templates/__init__.py +++ b/posthog/cdp/templates/__init__.py @@ -7,6 +7,7 @@ from .intercom.template_intercom import template as intercom, TemplateIntercomMi from .sendgrid.template_sendgrid import template as sendgrid, TemplateSendGridMigrator from .clearbit.template_clearbit import template as clearbit from .june.template_june import template as june +from .make.template_make import template as make from .posthog.template_posthog import template as posthog, TemplatePostHogMigrator from .aws_kinesis.template_aws_kinesis import template as aws_kinesis from .discord.template_discord import template as discord @@ -73,6 +74,7 @@ HOG_FUNCTION_TEMPLATES = [ mailjet_create_contact, mailjet_update_contact_list, mailset_send_email, + make, meta_ads, microsoft_teams, posthog, diff --git a/posthog/cdp/templates/make/template_make.py b/posthog/cdp/templates/make/template_make.py new file mode 100644 index 00000000000..53f9b4d1e1e --- /dev/null +++ b/posthog/cdp/templates/make/template_make.py @@ -0,0 +1,58 @@ +from posthog.cdp.templates.hog_function_template import HogFunctionTemplate + + +template: HogFunctionTemplate = HogFunctionTemplate( + status="beta", + type="destination", + id="template-make", + name="Make", + description="Triggers a webhook based scenario", + icon_url="/static/services/make.png", + category=["Custom"], + hog=""" +if (not match(inputs.webhookUrl, '^https://hook.[^/]+.make.com/?.*')) { + throw Error('Invalid URL. The URL should match the format: https://hook..make.com/') +} + +let res := fetch(inputs.webhookUrl, { + 'body': inputs.body, + 'method': 'POST', + 'headers': { + 'Content-Type': 'application/json' + } +}); + +if (res.status >= 400) { + throw Error(f'Error from make.com (status {res.status}): {res.body}') +} +""".strip(), + inputs_schema=[ + { + "key": "webhookUrl", + "type": "string", + "label": "Webhook URL", + "description": "See this page on how to generate a Webhook URL: https://www.make.com/en/help/tools/webhooks", + "secret": False, + "required": True, + }, + { + "key": "body", + "type": "json", + "label": "JSON Body", + "default": { + "data": { + "eventUuid": "{event.uuid}", + "event": "{event.event}", + "teamId": "{project.id}", + "distinctId": "{event.distinct_id}", + "properties": "{event.properties}", + "elementsChain": "{event.elementsChain}", + "timestamp": "{event.timestamp}", + "person": {"uuid": "{person.id}", "properties": "{person.properties}"}, + } + }, + "secret": False, + "required": True, + }, + ], +) diff --git a/posthog/cdp/templates/make/test_template_make.py b/posthog/cdp/templates/make/test_template_make.py new file mode 100644 index 00000000000..df66979b488 --- /dev/null +++ b/posthog/cdp/templates/make/test_template_make.py @@ -0,0 +1,65 @@ +import pytest +from inline_snapshot import snapshot +from posthog.cdp.templates.helpers import BaseHogFunctionTemplateTest +from posthog.cdp.templates.make.template_make import template as template_make + + +class TestTemplateMake(BaseHogFunctionTemplateTest): + template = template_make + + def _inputs(self, **kwargs): + inputs = { + "webhookUrl": "https://hook.xxx.make.com/xxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "body": { + "data": { + "eventUuid": "uuid-xxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "event": "$pageview", + "teamId": "teamId-xxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "distinctId": "distinctId-xxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "properties": {"uuid": "person-uuid-xxxxxxxxxxxxxxxxxxxxxxxxxxxx"}, + } + }, + } + inputs.update(kwargs) + return inputs + + def test_function_works(self): + self.run_function(inputs=self._inputs()) + + assert self.get_mock_fetch_calls()[0] == snapshot( + ( + "https://hook.xxx.make.com/xxxxxxxxxxxxxxxxxxxxxxxxxxxx", + { + "method": "POST", + "headers": { + "Content-Type": "application/json", + }, + "body": { + "data": { + "eventUuid": "uuid-xxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "event": "$pageview", + "teamId": "teamId-xxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "distinctId": "distinctId-xxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "properties": {"uuid": "person-uuid-xxxxxxxxxxxxxxxxxxxxxxxxxxxx"}, + } + }, + }, + ) + ) + + def test_only_allow_teams_url(self): + for url, allowed in [ + ["https://hook.xxx.make.com/xxxxxxxxxxxxxxxxxxxxxxxxxxxx", True], + ["https://webhook.site/def", False], + ["https://webhook.site/def#https://hook.xxx.make.com/xxxxxxxxxxxxxxxxxxxxxxxxxxxx", False], + ]: + if allowed: + self.run_function(inputs=self._inputs(webhookUrl=url)) + assert len(self.get_mock_fetch_calls()) == 1 + else: + with pytest.raises(Exception) as e: + self.run_function(inputs=self._inputs(webhookUrl=url)) + assert ( + e.value.message # type: ignore[attr-defined] + == "Invalid URL. The URL should match the format: https://hook..make.com/" + )