{"id":22793393,"url":"https://github.com/fivetran/dbt_customer360","last_synced_at":"2026-02-06T23:01:23.911Z","repository":{"id":246288160,"uuid":"816978353","full_name":"fivetran/dbt_customer360","owner":"fivetran","description":null,"archived":false,"fork":false,"pushed_at":"2024-08-06T20:58:13.000Z","size":112,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-07-19T05:31:20.254Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"PLpgSQL","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fivetran.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-06-18T19:06:57.000Z","updated_at":"2024-08-06T20:58:17.000Z","dependencies_parsed_at":"2024-06-27T02:33:25.966Z","dependency_job_id":"e1a44b88-691b-4151-8cd2-d9c32f08bf79","html_url":"https://github.com/fivetran/dbt_customer360","commit_stats":null,"previous_names":["fivetran/dbt_customer360"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/fivetran/dbt_customer360","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fivetran%2Fdbt_customer360","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fivetran%2Fdbt_customer360/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fivetran%2Fdbt_customer360/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fivetran%2Fdbt_customer360/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fivetran","download_url":"https://codeload.github.com/fivetran/dbt_customer360/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fivetran%2Fdbt_customer360/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29179564,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-06T22:12:24.066Z","status":"ssl_error","status_checked_at":"2026-02-06T22:12:09.859Z","response_time":59,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-12-12T03:19:42.279Z","updated_at":"2026-02-06T23:01:23.895Z","avatar_url":"https://github.com/fivetran.png","language":"PLpgSQL","funding_links":[],"categories":[],"sub_categories":[],"readme":"# (WIP -- currently developing on BigQuery only) Customer360 Data Model\n\n## Prerequisites\nTo use this dbt package, you must have at least **TWO** of the following Fivetran Connectors:\n- Marketo\n- Stripe\n- Zendesk\n\nIf you are not using one of the above sources, set the respective `customer360__using_\u003csoure\u003e` variable to `False`:\n```yml\n# dbt_project.yml\nvars:\n  # Not using Stripe?\n  customer360__using_stripe: false # default = True\n\n  # Not using Marketo? \n  customer360__using_marketo: false # default = True\n\n  # Not using Zendesk?\n  customer360__using_zendesk: false # default = True\n```\n\n\u003e No need to set these variables to `True` if you are using the respective source. The package will assume the value to be true.\n\n## Output\nUnified \"customer\" view.\n\nWhat is a customer? The lowest grain of individuality (ie individual vs company) of your data from the 3 sources we use:\n- Marketo\n- Stripe\n- Zendesk\n\nEach record where `is_organization_header=False` will represent an Individual (otherwise the most granular level of data present). The package will also insert an organization-level header row for easier aggregations across grains (`is_organization_header=true`) for proper aggregations and flexibility. These will all share the same `customer360_organization_id` but each have a unique `customer360_id`.\n\n\u003e Note: If you are a b2c organization, your source Stripe customer data (and potentially Marketo) may only exist at the organizational level, while other sources (Zendesk and likely Marketo) typically provide customer data at the individual level. See the \"Grain of Source Data\" section below.\n\n### The exact tables:\n- `customer360__mapping`: Complete mapping of customer IDs from Marketo, Zendesk, and Stripe onto each other.\n- Child informational tables with all values found for a customer across all 3 sources:\n  - `customer360__address`\n  - `customer360__email`\n  - `customer360__phone`\n  - `customer360__name`\n  - `customer360__organization`\n  - `customer360__ip_address`\n  - `customer360_status`\n  - `customer360__updates`\n- A summary table surfacing the most \"confident\" values (chosen from recency and frequency) from above: `customer360__summary`.\n- A customer table aggregating all metrics from Stripe, Marketo, and Zendesk.\n\n## How to Run\n### Step 1: Install Package\n1. Go to your project's `packages.yml` and comment out any individual references to the Fivetran Stripe, Marketo, and Zendesk packages.\n2. Add the following instead (ths will install Stripe, Marketo, and Zendesk as dependencies).\n```yml\npackages:\n  - git: https://github.com/fivetran/dbt_customer360.git # this will install Stripe, Marketo, and Zendesk as dependencies\n    revision: main\n    warn-unpinned: false\n```\n\n### Step 2: Configure Package Variables\n\n#### A. Grain of Source Data\nBy default, this package assumes each of your data sources presents information at the Individual's level. However, if you are a b2c company, some of your data may exist at the Organization level only. This is especially likely of Stripe as opposed to Zendesk and Marketo, in which typically individuals operate.\n\nTell the package the grain of your source data to better perform identity resolution.\n```yml\nvars:\n  customer360_grain_stripe: organization # default = individual\n  customer360_grain_marketo: organization # default = individual\n  customer360_grain_zendesk: organization # default = individual\n```\n\n#### B. Leveraging Custom/Internal IDs\nBy default, the package will perform identity matching based on:\n- email\n- phone number\n- physical address\n- individual name (fuzzy matching)\n  - organization name is used instead if the `customer360_grain_\u003csource\u003e` variable is set to `organization`.\n\nThis heuristic on its own, however, may not offer a high match rate. You may have an interanl ID, such as a product app ID or a third-party tool's ID (ie Salesforce Account ID), that can be leveraged for resolving identities.\n\n```yml\nvars:\n    customer360_internal_match_ids:\n        - name: sf_account_id # to serve as a generalized alias\n          customer_grain: individual | organization # should this be applied at the individual or organizational level? affects joins/filters in our identity resolution logic\n          marketo: \n            match_key: sfdc_account_id\n          stripe:\n            match_key: salesforce_account_id\n          zendesk:\n              map_table: db-name.intermediate_tables.salesforce_to_fivetran_account\n              source: user | organization # should we use zendesk.USER or zendesk.ORGANIZATION\n              join_with_map_on: custom_fivetran_account_id\n              map_table_join_on: fivetran_account_id_c\n              match_key: account_c\n\n        - name: fivetran_user_id # to serve as a generalized alias\n          customer_grain: individual | organization # should this be applied at the individual or organizational level? affects joins/filters in our identity resolution logic\n          marketo: \n            match_key: fivetran_user_id\n          stripe:\n            match_key: fivetran_user_id\n          zendesk:\n              source: user | organization # should we use zendesk.USER or zendesk.ORGANIZATION\n              match_key: fivetran_user_id\n```\n\nYou can provide multiple \"match sets\" such as the above. The arguments are as follows:\n- `name` (required): General name to serve as an alias for the match field, as its name in each individual source will likely be different.\n- `customer_grain` (required): Grain at which to merge customers along this key. Does it apply to entire organizations, or individual consumers? Specify this by providing `individual` or `organization`.\n- `source` (required only for Zendesk): What source table the field is coming from. In Zendesk's case, we pull data from both `user` and `organization`, and the `source` should reflect one of these tables.\n- `match_key` (required for 2+ sources): What field from each source that the `match_key` is scoped under should be used in identity resolution joins. If you are using a mapping table (see below), this should be the target field from the mapping to use for identity resolution.\n- We also allow for the use of an internal intermediate mapping table, in case this is is necessary to grab the necessary `match_key` for all 3 sources. If leveraging a mapping table, add the following arguments:\n  - `map_table` (required only if using mapping): The full `\u003cdatabase\u003e.\u003cschema\u003e.\u003ctable\u003e` identifier for the mapping table. Do not include quotes. This cannot be a `ref()` :disappointed:\n  - `join_with_map_on` (required only if using mapping): Which source field from either `marketo__leads`, `stripe__customer_overview`, `stg_zendesk__user`, or `stg_zendesk__organization` to use for joining with the mapping table.\n  - `map_table_join_on`: Which field from the mapping table to use for joining with either `marketo__leads`, `stripe__customer_overview`, `stg_zendesk__user`, or `stg_zendesk__organization`.\n\n#### C. Stripe Individual-Name Configs\nStripe doesn't have distinct name fields for individuals vs organizations. If you store both the indvidual and the company name, and in a consistent enforced format, use the below variables to tell the package how to parse them out from the Stripe `CUSTOMER.customer_name` and `CUSTOMER.shipping_name` fields.\n\n```yml\nvars:\n    stripe_customer_full_name_extract_sql: \"replace( {{ dbt.split_part('customer_name', \\\"' ('\\\", 2) }}, ')', '')\" # How to extract the individual name from `customer_name`. Default = customer_name\n    stripe_customer_organization_name_extract_sql: \"coalesce({{ dbt.split_part('customer_name', \\\"' ('\\\", 1) }}, customer_name)\" # How to extract the company name from `customer_name`. Default = customer_name\n    stripe_shipping_full_name_extract_sql: \"replace( {{ dbt.split_part('shipping_name', \\\"' ('\\\", 2) }}, ')', '')\" # How to extract the individual name from `shipping_name`. Default = shipping_name\n    stripe_shipping_organization_name_extract_sql: \"coalesce({{ dbt.split_part('shipping_name', \\\"' ('\\\", 1) }}, shipping_name)\" # How to extract the company name from `shipping_name`. Default = shipping_name\n```\n\nThe above example code is intended for environments in which Stripe names are stored as `Company Name (Individual Name)`.\n\n### Step 3: Run Models! \n1. Execute `dbt seed -m customer360 --full-refresh`. This will seed in some utilities files that map Countries and Territories onto their abbreviations and individual's nicknames onto their longform names.\n2. Execute `dbt run -m +customer360`. This will run everything (that's enabled) upstream of and within the Customer360 package.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffivetran%2Fdbt_customer360","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffivetran%2Fdbt_customer360","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffivetran%2Fdbt_customer360/lists"}