def create_event( event_uuid: uuid.UUID, event: str, team: Team, distinct_id: str, timestamp: Optional[Union[timezone.datetime, str]] = None, properties: Optional[Dict] = {}, elements: Optional[List[Element]] = None, site_url: Optional[str] = None, ) -> str: if not timestamp: timestamp = timezone.now() assert timestamp is not None # clickhouse specific formatting if isinstance(timestamp, str): timestamp = isoparse(timestamp) else: timestamp = timestamp.astimezone(pytz.utc) elements_chain = "" if elements and len(elements) > 0: elements_chain = elements_to_string(elements=elements) pb_event = events_pb2.Event() pb_event.uuid = str(event_uuid) pb_event.event = event pb_event.properties = json.dumps(properties) pb_event.timestamp = timestamp.strftime("%Y-%m-%d %H:%M:%S.%f") pb_event.team_id = team.pk pb_event.distinct_id = str(distinct_id) pb_event.elements_chain = elements_chain pb_event.created_at = timestamp.strftime("%Y-%m-%d %H:%M:%S.%f") p = ClickhouseProducer() p.produce_proto(sql=INSERT_EVENT_SQL, topic=KAFKA_EVENTS, data=pb_event) if team.slack_incoming_webhook or team.organization.is_feature_available("zapier"): try: celery.current_app.send_task( "ee.tasks.webhooks_ee.post_event_to_webhook_ee", ( { "event": event, "properties": properties, "distinct_id": distinct_id, "timestamp": timestamp, "elements_chain": elements_chain, }, team.pk, site_url, ), ) except: capture_exception() return str(event_uuid)
def test_elements_to_string(self) -> None: self.maxDiff = None elements_string = elements_to_string(elements=[ Element( tag_name="a", href="/a-url", attr_class=["small"], text="bla bla", attributes={ "prop": "value", "number": 33, "data-attr": 'something " that; could mess up', "style": "min-height: 100vh;", }, nth_child=1, nth_of_type=0, ), Element(tag_name="button", attr_class=["btn", "btn-primary"], nth_child=0, nth_of_type=0), Element(tag_name="div", nth_child=0, nth_of_type=0), Element( tag_name="div", nth_child=0, nth_of_type=0, attr_id="nested", ), ], ) self.assertEqual( elements_string, ";".join([ r'a.small:data-attr="something \" that; could mess up"href="/a-url"nth-child="1"nth-of-type="0"number="33"prop="value"style="min-height: 100vh;"text="bla bla"', 'button.btn.btn-primary:nth-child="0"nth-of-type="0"', 'div:nth-child="0"nth-of-type="0"', 'div:attr_id="nested"nth-child="0"nth-of-type="0"', ]), ) elements = chain_to_elements(elements_string) self.assertEqual(elements[0].tag_name, "a") self.assertEqual(elements[0].href, "/a-url") self.assertEqual(elements[0].attr_class, ["small"]) self.assertDictEqual( elements[0].attributes, { "prop": "value", "number": "33", "data-attr": r"something \" that; could mess up", "style": "min-height: 100vh;", }, ) self.assertEqual(elements[0].nth_child, 1) self.assertEqual(elements[0].nth_of_type, 0) self.assertEqual(elements[1].attr_class, ["btn", "btn-primary"]) self.assertEqual(elements[3].attr_id, "nested")
def test_broken_class_names(self): elements = chain_to_elements("a........small") self.assertEqual(elements[0].tag_name, "a") self.assertEqual(elements[0].attr_class, ["small"]) elements_string = elements_to_string(elements=[ Element(tag_name="a", href="/a-url", attr_class=['small"', "xy:z"], attributes={"attr_class": 'xyz small"'}) ]) elements = chain_to_elements(elements_string) self.assertEqual(elements[0].tag_name, "a") self.assertEqual(elements[0].href, "/a-url") self.assertEqual(elements[0].attr_class, ["small", "xy:z"])
def create_event( event_uuid: uuid.UUID, event: str, team: Team, distinct_id: str, timestamp: Optional[Union[timezone.datetime, str]] = None, properties: Optional[Dict] = {}, elements: Optional[List[Element]] = None, site_url: Optional[str] = None, ) -> str: if not timestamp: timestamp = timezone.now() assert timestamp is not None # clickhouse specific formatting if isinstance(timestamp, str): timestamp = isoparse(timestamp) else: timestamp = timestamp.astimezone(pytz.utc) elements_chain = "" if elements and len(elements) > 0: elements_chain = elements_to_string(elements=elements) pb_event = events_pb2.Event() pb_event.uuid = str(event_uuid) pb_event.event = event pb_event.properties = json.dumps(properties) pb_event.timestamp = timestamp.strftime("%Y-%m-%d %H:%M:%S.%f") pb_event.team_id = team.pk pb_event.distinct_id = str(distinct_id) pb_event.elements_chain = elements_chain pb_event.created_at = timestamp.strftime("%Y-%m-%d %H:%M:%S.%f") p = ClickhouseProducer() p.produce_proto(sql=INSERT_EVENT_SQL, topic=KAFKA_EVENTS, data=pb_event) return str(event_uuid)
def create_event( event_uuid: uuid.UUID, event: str, team: Team, distinct_id: str, timestamp: Optional[Union[timezone.datetime, str]] = None, properties: Optional[Dict] = {}, elements: Optional[List[Element]] = None, ) -> str: if not timestamp: timestamp = timezone.now() assert timestamp is not None # clickhouse specific formatting if isinstance(timestamp, str): timestamp = isoparse(timestamp) else: timestamp = timestamp.astimezone(pytz.utc) elements_chain = "" if elements and len(elements) > 0: elements_chain = elements_to_string(elements=elements) data = { "uuid": str(event_uuid), "event": event, "properties": json.dumps(properties), "timestamp": timestamp.strftime("%Y-%m-%d %H:%M:%S.%f"), "team_id": team.pk, "distinct_id": distinct_id, "created_at": timestamp.strftime("%Y-%m-%d %H:%M:%S.%f"), "elements_chain": elements_chain, } p = ClickhouseProducer() p.produce(sql=INSERT_EVENT_SQL, topic=KAFKA_EVENTS, data=data) return str(event_uuid)