Marketing Ops
Python
Webhook Trigger

Associate Company to Marketing Event (Python)

Associate an attendee contact's company to a marketing event for account-level event reporting in Python.

Why this automation is needed

Native HubSpot workflows often struggle with complex multi-object traversals, conditional lookback attribution windows, custom phone format standardizations, and custom scoring calculations.

With Workflood, this recipe runs in a secure gVisor container sandbox with pre-authenticated HubSpot SDK injection, avoiding HubSpot Data Hub execution limits, memory bottlenecks, and per-seat fees.

Action Source Code (Python)

associate-company-marketing-event-python.py
Python
def main(input_data, hs_client, http_client, secret, console):
    raw = input_data[0] if isinstance(input_data, list) and input_data else (input_data or {})
    marketing_event_id = raw.get('marketingEventId') or raw.get('marketing_event_id') or raw.get('eventId')
    contact_id = raw.get('contactId') or raw.get('contact_id') or raw.get('objectId') or raw.get('hs_object_id')
    email = raw.get('email')
    attendance_state = raw.get('attendanceState') or raw.get('attendance_state')

    # Only link company if the contact actually attended
    if attendance_state and attendance_state != 'ATTENDED':
        return {
            "associated": False,
            "marketingEventId": marketing_event_id,
            "message": f"Skipped: contact attendanceState is '{attendance_state}' (not ATTENDED)"
        }

    # Trigger-agnostic fallback if no inputs given
    if not contact_id and not email and not marketing_event_id:
        recent = hs_client.crm.contacts.basic_api.get_page(limit=25, properties=['email'])
        linked = 0
        for c in (recent.results or []):
            c_assoc = hs_client.crm.associations.v4.basic_api.get_page('contacts', c.id, 'companies', limit=1)
            comp_id = c_assoc.results[0].to_object_id if c_assoc.results else None
            if not comp_id:
                continue
            e_assoc = hs_client.crm.associations.v4.basic_api.get_page('contacts', c.id, 'marketing_events', limit=5)
            for e in (e_assoc.results or []):
                hs_client.crm.associations.v4.basic_api.create(
                    'companies', comp_id, 'marketing_events', e.to_object_id,
                    [{"associationCategory": "HUBSPOT_DEFINED", "associationTypeId": 14}]
                )
                linked += 1
        return {"associated": linked > 0, "processedCount": len(recent.results or []), "message": f"Trigger-agnostic scan: linked {linked} company-to-event associations"}

    # Resolve contact ID if email was provided
    if not contact_id and email:
        contacts = hs_client.crm.contacts.basic_api.get_page(
            limit=1,
            properties=['email'],
            filters=[{ "value": email, "propertyName": "email", "operator": "EQ" }]
        )
        if contacts.results:
            contact_id = contacts.results[0].id

    if not contact_id:
        raise ValueError("Could not determine contactId (provide contactId or valid email)")

    # Fetch associated companies for contact
    assocs = hs_client.crm.associations.v4.basic_api.get_page(
        from_object_type='contacts',
        object_id=contact_id,
        to_object_type='companies',
        limit=5
    )

    if not assocs.results:
        return {
            "associated": False,
            "contactId": contact_id,
            "marketingEventId": marketing_event_id,
            "message": f"No associated company found for contact ID {contact_id}"
        }

    company_id = assocs.results[0].to_object_id

    if not marketing_event_id:
        e_assocs = hs_client.crm.associations.v4.basic_api.get_page('contacts', contact_id, 'marketing_events', limit=5)
        if not e_assocs.results:
            return {"associated": False, "companyId": company_id, "contactId": contact_id, "message": f"No events on contact {contact_id}"}
        marketing_event_id = e_assocs.results[0].to_object_id

    # Create association between Company and Marketing Event
    hs_client.crm.associations.v4.basic_api.create(
        from_object_type='companies',
        object_id=company_id,
        to_object_type='marketing_events',
        to_object_id=marketing_event_id,
        types=[{"associationCategory": "HUBSPOT_DEFINED", "associationTypeId": 14}]
    )

    return {
        "associated": True,
        "companyId": company_id,
        "contactId": contact_id,
        "marketingEventId": marketing_event_id,
        "message": f"Successfully associated Company {company_id} to Marketing Event {marketing_event_id}"
    }

How to deploy in Workflood

1

Connect your HubSpot Portal

Add your HubSpot Private App token once. Workflood securely encrypts it via libsodium XChaCha20 and injects pre-authenticated SDK clients.

2

Create Action from Template

Select this recipe in Workflood. Edit variables, customize logic in Monaco editor, or execute dry runs with sample JSON payloads.

3

Trigger via Webhook or Cron

Trigger from standard HubSpot workflows via Webhook action, or schedule recurring batch syncs with cron expressions and timezone handling.