ghost 5.116.0 → 5.116.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/{tryghost-api-framework-5.116.0.tgz → tryghost-api-framework-5.116.2.tgz} +0 -0
- package/components/tryghost-constants-5.116.2.tgz +0 -0
- package/components/tryghost-custom-fonts-5.116.2.tgz +0 -0
- package/components/{tryghost-custom-theme-settings-service-5.116.0.tgz → tryghost-custom-theme-settings-service-5.116.2.tgz} +0 -0
- package/components/tryghost-domain-events-5.116.2.tgz +0 -0
- package/components/tryghost-donations-5.116.2.tgz +0 -0
- package/components/{tryghost-email-addresses-5.116.0.tgz → tryghost-email-addresses-5.116.2.tgz} +0 -0
- package/components/{tryghost-email-service-5.116.0.tgz → tryghost-email-service-5.116.2.tgz} +0 -0
- package/components/tryghost-email-suppression-list-5.116.2.tgz +0 -0
- package/components/{tryghost-html-to-plaintext-5.116.0.tgz → tryghost-html-to-plaintext-5.116.2.tgz} +0 -0
- package/components/tryghost-i18n-5.116.2.tgz +0 -0
- package/components/{tryghost-job-manager-5.116.0.tgz → tryghost-job-manager-5.116.2.tgz} +0 -0
- package/components/tryghost-link-replacer-5.116.2.tgz +0 -0
- package/components/{tryghost-magic-link-5.116.0.tgz → tryghost-magic-link-5.116.2.tgz} +0 -0
- package/components/{tryghost-member-attribution-5.116.0.tgz → tryghost-member-attribution-5.116.2.tgz} +0 -0
- package/components/{tryghost-member-events-5.116.0.tgz → tryghost-member-events-5.116.2.tgz} +0 -0
- package/components/{tryghost-members-api-5.116.0.tgz → tryghost-members-api-5.116.2.tgz} +0 -0
- package/components/{tryghost-members-csv-5.116.0.tgz → tryghost-members-csv-5.116.2.tgz} +0 -0
- package/components/{tryghost-members-offers-5.116.0.tgz → tryghost-members-offers-5.116.2.tgz} +0 -0
- package/components/tryghost-milestones-5.116.2.tgz +0 -0
- package/components/{tryghost-mw-error-handler-5.116.0.tgz → tryghost-mw-error-handler-5.116.2.tgz} +0 -0
- package/components/{tryghost-mw-vhost-5.116.0.tgz → tryghost-mw-vhost-5.116.2.tgz} +0 -0
- package/components/tryghost-post-events-5.116.2.tgz +0 -0
- package/components/tryghost-post-revisions-5.116.2.tgz +0 -0
- package/components/tryghost-posts-service-5.116.2.tgz +0 -0
- package/components/{tryghost-prometheus-metrics-5.116.0.tgz → tryghost-prometheus-metrics-5.116.2.tgz} +0 -0
- package/components/tryghost-security-5.116.2.tgz +0 -0
- package/components/{tryghost-tiers-5.116.0.tgz → tryghost-tiers-5.116.2.tgz} +0 -0
- package/components/tryghost-webmentions-5.116.2.tgz +0 -0
- package/core/built/admin/assets/admin-x-activitypub/admin-x-activitypub.js +9776 -11013
- package/core/built/admin/assets/admin-x-demo/admin-x-demo.js +2 -2
- package/core/built/admin/assets/admin-x-demo/{index-a9601514.mjs → index-09325f38.mjs} +4 -4
- package/core/built/admin/assets/admin-x-demo/{modals-c1789d04.mjs → modals-1a9ae8b7.mjs} +2 -2
- package/core/built/admin/assets/admin-x-settings/{CodeEditorView-e9c9deb8.mjs → CodeEditorView-550846e0.mjs} +2 -2
- package/core/built/admin/assets/admin-x-settings/admin-x-settings.js +2 -2
- package/core/built/admin/assets/admin-x-settings/{index-f744cab7.mjs → index-4ce2fcd1.mjs} +78 -77
- package/core/built/admin/assets/admin-x-settings/{index-84580c3a.mjs → index-f3cb3f4d.mjs} +2 -2
- package/core/built/admin/assets/admin-x-settings/{modals-d9ca60c5.mjs → modals-6bc20529.mjs} +8 -8
- package/core/built/admin/assets/{chunk.524.8371443ef8f60db429d0.js → chunk.524.578de86e5014b911b05a.js} +8 -8
- package/core/built/admin/assets/{chunk.582.f90151775f2e53dd21d9.js → chunk.582.21bf3e37b5d84ac4b58a.js} +9 -9
- package/core/built/admin/assets/{chunk.713.e9027c0cc3c56110f5da.js → chunk.713.761d11035fe0bf3e557c.js} +2 -2
- package/core/built/admin/assets/{ghost-03b64c086f3c60cabc85fe7a7e2b640a.js → ghost-868c537d5c02ca65323d0122596a67ec.js} +57 -55
- package/core/built/admin/assets/posts/posts.js +5185 -5096
- package/core/built/admin/assets/stats/stats.js +6630 -6541
- package/core/built/admin/assets/{vendor-72026232b36d97babc6320917c16c321.js → vendor-8e3ee8261528bb429cfe78ce79a4a82a.js} +5 -5
- package/core/built/admin/index.html +5 -5
- package/core/frontend/helpers/ghost_head.js +9 -5
- package/core/frontend/public/ghost-stats.js +41 -74
- package/core/server/data/tinybird/datasources/_mv_hits.datasource +23 -0
- package/core/server/data/tinybird/datasources/analytics_events.datasource +14 -0
- package/core/server/data/tinybird/endpoints/api_kpis.pipe +161 -0
- package/core/server/data/tinybird/endpoints/api_top_browsers.pipe +52 -0
- package/core/server/data/tinybird/endpoints/api_top_devices.pipe +51 -0
- package/core/server/data/tinybird/endpoints/api_top_locations.pipe +51 -0
- package/core/server/data/tinybird/endpoints/api_top_os.pipe +51 -0
- package/core/server/data/tinybird/endpoints/api_top_pages.pipe +52 -0
- package/core/server/data/tinybird/endpoints/api_top_sources.pipe +24 -0
- package/core/server/data/tinybird/fixtures/analytics_events.ndjson +31 -0
- package/core/server/data/tinybird/pipes/filtered_sessions.pipe +42 -0
- package/core/server/data/tinybird/pipes/mv_hits.pipe +89 -0
- package/core/server/data/tinybird/pipes/mv_session_data.pipe +28 -0
- package/core/server/data/tinybird/readme.md +47 -0
- package/core/server/data/tinybird/tests/api_kpis.yaml +207 -0
- package/core/server/data/tinybird/tests/api_top_browsers.yaml +89 -0
- package/core/server/data/tinybird/tests/api_top_devices.yaml +69 -0
- package/core/server/data/tinybird/tests/api_top_locations.yaml +95 -0
- package/core/server/data/tinybird/tests/api_top_os.yaml +73 -0
- package/core/server/data/tinybird/tests/api_top_pages.yaml +86 -0
- package/core/server/data/tinybird/tests/api_top_sources.yaml +118 -0
- package/package.json +59 -59
- package/yarn.lock +37 -56
- package/components/tryghost-constants-5.116.0.tgz +0 -0
- package/components/tryghost-custom-fonts-5.116.0.tgz +0 -0
- package/components/tryghost-domain-events-5.116.0.tgz +0 -0
- package/components/tryghost-donations-5.116.0.tgz +0 -0
- package/components/tryghost-email-suppression-list-5.116.0.tgz +0 -0
- package/components/tryghost-i18n-5.116.0.tgz +0 -0
- package/components/tryghost-link-replacer-5.116.0.tgz +0 -0
- package/components/tryghost-milestones-5.116.0.tgz +0 -0
- package/components/tryghost-post-events-5.116.0.tgz +0 -0
- package/components/tryghost-post-revisions-5.116.0.tgz +0 -0
- package/components/tryghost-posts-service-5.116.0.tgz +0 -0
- package/components/tryghost-security-5.116.0.tgz +0 -0
- package/components/tryghost-webmentions-5.116.0.tgz +0 -0
- /package/core/built/admin/assets/{chunk.713.e9027c0cc3c56110f5da.js.LICENSE.txt → chunk.713.761d11035fe0bf3e557c.js.LICENSE.txt} +0 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
TOKEN "stats_page" READ
|
|
2
|
+
|
|
3
|
+
NODE _top_os_0
|
|
4
|
+
SQL >
|
|
5
|
+
|
|
6
|
+
%
|
|
7
|
+
select
|
|
8
|
+
os,
|
|
9
|
+
uniqExact(session_id) as visits
|
|
10
|
+
from _mv_hits h
|
|
11
|
+
inner join filtered_sessions fs
|
|
12
|
+
on fs.session_id = h.session_id
|
|
13
|
+
where
|
|
14
|
+
site_uuid = {{String(site_uuid, 'mock_site_uuid', description="Tenant ID", required=True)}}
|
|
15
|
+
{% if defined(date_from) %}
|
|
16
|
+
and toDate(toTimezone(timestamp, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}}))
|
|
17
|
+
>=
|
|
18
|
+
{{ Date(date_from, description="Starting day for filtering a date range", required=False) }}
|
|
19
|
+
{% else %}
|
|
20
|
+
and toDate(toTimezone(timestamp, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}}))
|
|
21
|
+
>=
|
|
22
|
+
timestampAdd(today(), interval -1 year)
|
|
23
|
+
{% end %}
|
|
24
|
+
{% if defined(date_to) %}
|
|
25
|
+
and toDate(toTimezone(timestamp, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}}))
|
|
26
|
+
<=
|
|
27
|
+
{{ Date(date_to, description="Finishing day for filtering a date range", required=False) }}
|
|
28
|
+
{% else %}
|
|
29
|
+
and toDate(toTimezone(timestamp, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}}))
|
|
30
|
+
<=
|
|
31
|
+
today()
|
|
32
|
+
{% end %}
|
|
33
|
+
{% if defined(member_status) %}
|
|
34
|
+
and member_status IN (
|
|
35
|
+
select arrayJoin(
|
|
36
|
+
{{ Array(member_status, "'undefined', 'free', 'paid'", description="Member status to filter on", required=False) }}
|
|
37
|
+
|| if('paid' IN {{ Array(member_status) }}, ['comped'], [])
|
|
38
|
+
)
|
|
39
|
+
)
|
|
40
|
+
{% end %}
|
|
41
|
+
{% if defined(device) %} and device = {{ String(device, description="Device to filter on", required=False) }} {% end %}
|
|
42
|
+
{% if defined(browser) %} and browser = {{ String(browser, description="Browser to filter on", required=False) }} {% end %}
|
|
43
|
+
{% if defined(os) %} and os = {{ String(os, description="Operating system to filter on", required=False) }} {% end %}
|
|
44
|
+
{% if defined(source) %} and source = {{ String(source, description="Source to filter on", required=False) }} {% end %}
|
|
45
|
+
{% if defined(location) %} and location = {{ String(location, description="Location to filter on", required=False) }} {% end %}
|
|
46
|
+
{% if defined(pathname) %} and pathname = {{ String(pathname, description="Pathname to filter on", required=False) }} {% end %}
|
|
47
|
+
group by os
|
|
48
|
+
order by visits desc
|
|
49
|
+
limit {{ Int32(skip, 0) }},{{ Int32(limit, 50) }}
|
|
50
|
+
|
|
51
|
+
TYPE ENDPOINT
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
TOKEN "stats_page" READ
|
|
2
|
+
|
|
3
|
+
NODE _top_pages_0
|
|
4
|
+
SQL >
|
|
5
|
+
|
|
6
|
+
%
|
|
7
|
+
select
|
|
8
|
+
pathname,
|
|
9
|
+
uniqExact(session_id) as visits
|
|
10
|
+
from _mv_hits h
|
|
11
|
+
inner join filtered_sessions fs
|
|
12
|
+
on fs.session_id = h.session_id
|
|
13
|
+
where
|
|
14
|
+
site_uuid = {{String(site_uuid, 'mock_site_uuid', description="Tenant ID", required=True)}}
|
|
15
|
+
{% if defined(date_from) %}
|
|
16
|
+
and toDate(toTimezone(timestamp, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}}))
|
|
17
|
+
>=
|
|
18
|
+
{{ Date(date_from, description="Starting day for filtering a date range", required=False) }}
|
|
19
|
+
{% else %}
|
|
20
|
+
and toDate(toTimezone(timestamp, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}}))
|
|
21
|
+
>=
|
|
22
|
+
timestampAdd(today(), interval -7 day)
|
|
23
|
+
{% end %}
|
|
24
|
+
{% if defined(date_to) %}
|
|
25
|
+
and toDate(toTimezone(timestamp, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}}))
|
|
26
|
+
<=
|
|
27
|
+
{{ Date(date_to, description="Finishing day for filtering a date range", required=False) }}
|
|
28
|
+
{% else %}
|
|
29
|
+
and toDate(toTimezone(timestamp, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}}))
|
|
30
|
+
<=
|
|
31
|
+
today()
|
|
32
|
+
{% end %}
|
|
33
|
+
{% if defined(member_status) %}
|
|
34
|
+
and member_status IN (
|
|
35
|
+
select arrayJoin(
|
|
36
|
+
{{ Array(member_status, "'undefined', 'free', 'paid'", description="Member status to filter on", required=False) }}
|
|
37
|
+
|| if('paid' IN {{ Array(member_status) }}, ['comped'], [])
|
|
38
|
+
)
|
|
39
|
+
)
|
|
40
|
+
{% end %}
|
|
41
|
+
{% if defined(device) %} and device = {{ String(device, description="Device to filter on", required=False) }} {% end %}
|
|
42
|
+
{% if defined(browser) %} and browser = {{ String(browser, description="Browser to filter on", required=False) }} {% end %}
|
|
43
|
+
{% if defined(os) %} and os = {{ String(os, description="Operating system to filter on", required=False) }} {% end %}
|
|
44
|
+
-- we do filtering on source in the filtered_sessions pipe
|
|
45
|
+
# --{% if defined(source) %} and source = {{ String(source, description="Source to filter on", required=False) }} {% end %}
|
|
46
|
+
{% if defined(location) %} and location = {{ String(location, description="Location to filter on", required=False) }} {% end %}
|
|
47
|
+
{% if defined(pathname) %} and pathname = {{ String(pathname, description="Pathname to filter on", required=False) }} {% end %}
|
|
48
|
+
group by pathname
|
|
49
|
+
order by visits desc
|
|
50
|
+
limit {{ Int32(skip, 0) }},{{ Int32(limit, 50) }}
|
|
51
|
+
|
|
52
|
+
TYPE ENDPOINT
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
TOKEN "stats_page" READ
|
|
2
|
+
|
|
3
|
+
NODE top_sources
|
|
4
|
+
SQL >
|
|
5
|
+
%
|
|
6
|
+
select
|
|
7
|
+
source,
|
|
8
|
+
count() as visits
|
|
9
|
+
from mv_session_data sd
|
|
10
|
+
inner join filtered_sessions fs
|
|
11
|
+
on fs.session_id = sd.session_id
|
|
12
|
+
where
|
|
13
|
+
site_uuid = {{ String(site_uuid, 'mock_site_uuid', description="Tenant ID", required=True) }}
|
|
14
|
+
{% if defined(date_from) and day_diff(date_from, date_to) == 0 %}
|
|
15
|
+
and toDate(toTimezone(first_pageview, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}})) = {{ Date(date_from) }}
|
|
16
|
+
{% else %}
|
|
17
|
+
{% if defined(date_from) %} and toDate(toTimezone(first_pageview, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}})) >= {{ Date(date_from) }} {% else %} and toDate(toTimezone(first_pageview, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}})) >= timestampAdd(today(), interval -7 day) {% end %}
|
|
18
|
+
{% if defined(date_to) %} and toDate(toTimezone(first_pageview, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}})) <= {{ Date(date_to) }} {% else %} and toDate(toTimezone(first_pageview, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}})) <= today() {% end %}
|
|
19
|
+
{% end %}
|
|
20
|
+
group by source
|
|
21
|
+
order by visits desc
|
|
22
|
+
limit {{ Int32(skip, 0) }},{{ Int32(limit, 50) }}
|
|
23
|
+
|
|
24
|
+
TYPE ENDPOINT
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{"timestamp":"2100-01-01 00:06:15","session_id":"e5c37e25-ed9e-4940-a2be-bc49149d991a","action":"page_hit","version":"1","payload":{"site_uuid":"mock_site_uuid","member_uuid":"undefined","member_status":"undefined","post_uuid":"6b8635fb-292f-4422-9fe4-d76cfab2ba31","user-agent":"AhrefsBot/7.0; +http://ahrefs.com/robot/","locale":"en-GB","location":"GB","referrer":"https://petty-queen.com","pathname":"/blog/hello-world/","href":"https://my-ghost-site.com/blog/hello-world/"}}
|
|
2
|
+
{"timestamp":"2100-01-01 01:21:17","session_id":"1267b782-e5a1-4334-8cf6-771d72bbc28e","action":"page_hit","version":"1","payload":{"site_uuid":"mock_site_uuid","member_uuid":"d4678fdf-824c-4d5f-a5fe-c713d409faac","member_status":"free","post_uuid":"undefined","user-agent":"Mozilla/5.0 (Windows; U; Windows NT 5.2) AppleWebKit/533.2.1 (KHTML, like Gecko) Chrome/13.0.868.0 Safari/533.2.1","locale":"es-ES","location":"ES","referrer":"","pathname":"/","href":"https://my-ghost-site.com/"}}
|
|
3
|
+
{"timestamp":"2100-01-01 01:39:48","session_id":"1267b782-e5a1-4334-8cf6-771d72bbc28e","action":"page_hit","version":"1","payload":{"site_uuid":"mock_site_uuid","member_uuid":"d4678fdf-824c-4d5f-a5fe-c713d409faac","member_status":"free","post_uuid":"undefined","user-agent":"Mozilla/5.0 (Windows; U; Windows NT 5.2) AppleWebKit/533.2.1 (KHTML, like Gecko) Chrome/13.0.868.0 Safari/533.2.1","locale":"es-ES","location":"ES","referrer":"https://my-ghost-site.com","pathname":"/","href":"https://my-ghost-site.com/"}}
|
|
4
|
+
{"timestamp":"2100-01-01 02:21:13","session_id":"2a31286e-53b4-41da-a7fd-89d966072af5","action":"page_hit","version":"1","payload":{"site_uuid":"mock_site_uuid","member_uuid":"df8343d2-e89d-45b7-ba12-988734efcc56","member_status":"free","post_uuid":"06b1b0c9-fb53-4a15-a060-3db3fde7b1fc","user-agent":"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.0; Trident/4.0)","locale":"en-GB","location":"GB","referrer":"https://www.bing.com/","pathname":"/about/","href":"https://my-ghost-site.com/about/"}}
|
|
5
|
+
{"timestamp":"2100-01-01 02:31:43","session_id":"2a31286e-53b4-41da-a7fd-89d966072af5","action":"page_hit","version":"1","payload":{"site_uuid":"mock_site_uuid","member_uuid":"df8343d2-e89d-45b7-ba12-988734efcc56","member_status":"free","post_uuid":"undefined","user-agent":"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.0; Trident/4.0)","locale":"en-GB","location":"GB","referrer":"https://my-ghost-site.com","pathname":"/","href":"https://my-ghost-site.com/"}}
|
|
6
|
+
{"timestamp":"2100-01-02 00:59:45","session_id":"f253b9b7-0a1a-4168-8fcf-b20a1668ce4d","action":"page_hit","version":"1","payload":{"site_uuid":"mock_site_uuid","member_uuid":"65bacac2-8122-4ed0-a11f-ac52aa82beb0","member_status":"paid","post_uuid":"06b1b0c9-fb53-4a15-a060-3db3fde7b1fc","user-agent":"Mozilla/5.0 (Windows NT 5.3; Win64; x64; rv:11.6) Gecko/20100101 Firefox/11.6.2","locale":"en-GB","location":"GB","referrer":"https://www.google.com/","pathname":"/about/","href":"https://my-ghost-site.com/about/"}}
|
|
7
|
+
{"timestamp":"2100-01-02 01:12:56","session_id":"f253b9b7-0a1a-4168-8fcf-b20a1668ce4d","action":"page_hit","version":"1","payload":{"site_uuid":"mock_site_uuid","member_uuid":"65bacac2-8122-4ed0-a11f-ac52aa82beb0","member_status":"paid","post_uuid":"undefined","user-agent":"Mozilla/5.0 (Windows NT 5.3; Win64; x64; rv:11.6) Gecko/20100101 Firefox/11.6.2","locale":"en-GB","location":"GB","referrer":"https://my-ghost-site.com","pathname":"/","href":"https://my-ghost-site.com/"}}
|
|
8
|
+
{"timestamp":"2100-01-02 01:16:52","session_id":"f253b9b7-0a1a-4168-8fcf-b20a1668ce4d","action":"page_hit","version":"1","payload":{"site_uuid":"mock_site_uuid","member_uuid":"65bacac2-8122-4ed0-a11f-ac52aa82beb0","member_status":"paid","post_uuid":"undefined","user-agent":"Mozilla/5.0 (Windows NT 5.3; Win64; x64; rv:11.6) Gecko/20100101 Firefox/11.6.2","locale":"en-GB","location":"GB","referrer":"https://my-ghost-site.com","pathname":"/","href":"https://my-ghost-site.com/"}}
|
|
9
|
+
{"timestamp":"2100-01-03 00:01:24","session_id":"9c15f99e-c8b1-4145-a073-e7f8649d2fa4","action":"page_hit","version":"1","payload":{"site_uuid":"mock_site_uuid","member_uuid":"4c14393f-d792-403e-bbdc-aa5af3abbdd9","member_status":"free","post_uuid":"undefined","user-agent":"Mozilla/5.0 (Windows NT 5.0; rv:10.7) Gecko/20100101 Firefox/10.7.1","locale":"en-US","location":"US","referrer":"https://duckduckgo.com/","pathname":"/","href":"https://my-ghost-site.com/"}}
|
|
10
|
+
{"timestamp":"2100-01-03 01:28:09","session_id":"9c15f99e-c8b1-4145-a073-e7f8649d2fa4","action":"page_hit","version":"1","payload":{"site_uuid":"mock_site_uuid","member_uuid":"4c14393f-d792-403e-bbdc-aa5af3abbdd9","member_status":"free","post_uuid":"6b8635fb-292f-4422-9fe4-d76cfab2ba31","user-agent":"Mozilla/5.0 (Windows NT 5.0; rv:10.7) Gecko/20100101 Firefox/10.7.1","locale":"en-US","location":"US","referrer":"https://my-ghost-site.com","pathname":"/blog/hello-world/","href":"https://my-ghost-site.com/blog/hello-world/"}}
|
|
11
|
+
{"timestamp":"2100-01-03 01:41:44","session_id":"8a2461a8-91cd-4f01-b066-3de6dc946995","action":"page_hit","version":"1","payload":{"site_uuid":"mock_site_uuid","member_uuid":"f4c738bc-7327-440c-8007-6a0b306c05e3","member_status":"comped","post_uuid":"06b1b0c9-fb53-4a15-a060-3db3fde7b1fc","user-agent":"Mozilla/5.0 (Windows; U; Windows NT 5.0) AppleWebKit/533.2.0 (KHTML, like Gecko) Chrome/39.0.887.0 Safari/533.2.0","locale":"de-DE","location":"DE","referrer":"https://www.bing.com/","pathname":"/about/","href":"https://my-ghost-site.com/about/"}}
|
|
12
|
+
{"timestamp":"2100-01-03 01:53:31","session_id":"8a2461a8-91cd-4f01-b066-3de6dc946995","action":"page_hit","version":"1","payload":{"site_uuid":"mock_site_uuid","member_uuid":"f4c738bc-7327-440c-8007-6a0b306c05e3","member_status":"comped","post_uuid":"6b8635fb-292f-4422-9fe4-d76cfab2ba31","user-agent":"Mozilla/5.0 (Windows; U; Windows NT 5.0) AppleWebKit/533.2.0 (KHTML, like Gecko) Chrome/39.0.887.0 Safari/533.2.0","locale":"de-DE","location":"DE","referrer":"https://my-ghost-site.com","pathname":"/blog/hello-world/","href":"https://my-ghost-site.com/blog/hello-world/"}}
|
|
13
|
+
{"timestamp":"2100-01-03 02:00:19","session_id":"8a2461a8-91cd-4f01-b066-3de6dc946995","action":"page_hit","version":"1","payload":{"site_uuid":"mock_site_uuid","member_uuid":"f4c738bc-7327-440c-8007-6a0b306c05e3","member_status":"comped","post_uuid":"06b1b0c9-fb53-4a15-a060-3db3fde7b1fc","user-agent":"Mozilla/5.0 (Windows; U; Windows NT 5.0) AppleWebKit/533.2.0 (KHTML, like Gecko) Chrome/39.0.887.0 Safari/533.2.0","locale":"de-DE","location":"DE","referrer":"https://my-ghost-site.com","pathname":"/about/","href":"https://my-ghost-site.com/about/"}}
|
|
14
|
+
{"timestamp":"2100-01-03 02:51:20","session_id":"50785df1-3232-4ff7-8495-d93e06d63f5c","action":"page_hit","version":"1","payload":{"site_uuid":"mock_site_uuid","member_uuid":"3675e750-09bf-44c9-bc3f-b9aebac37c5d","member_status":"paid","post_uuid":"undefined","user-agent":"Mozilla/5.0 (Windows NT 6.3; rv:14.7) Gecko/20100101 Firefox/14.7.1","locale":"fr-FR","location":"FR","referrer":"https://search.yahoo.com/","pathname":"/","href":"https://my-ghost-site.com/"}}
|
|
15
|
+
{"timestamp":"2100-01-03 03:52:39","session_id":"50785df1-3232-4ff7-8495-d93e06d63f5c","action":"page_hit","version":"1","payload":{"site_uuid":"mock_site_uuid","member_uuid":"3675e750-09bf-44c9-bc3f-b9aebac37c5d","member_status":"paid","post_uuid":"undefined","user-agent":"Mozilla/5.0 (Windows NT 6.3; rv:14.7) Gecko/20100101 Firefox/14.7.1","locale":"fr-FR","location":"FR","referrer":"https://my-ghost-site.com","pathname":"/","href":"https://my-ghost-site.com/"}}
|
|
16
|
+
{"timestamp":"2100-01-04 00:25:39","session_id":"59478d87-ce95-40fd-a081-65d1e497bcfc","action":"page_hit","version":"1","payload":{"site_uuid":"mock_site_uuid","member_uuid":"97c79891-2ae9-4eb2-ada8-89d2a998747d","member_status":"paid","post_uuid":"6b8635fb-292f-4422-9fe4-d76cfab2ba31","user-agent":"Mozilla/5.0 (Windows; U; Windows NT 6.3) AppleWebKit/531.2.2 (KHTML, like Gecko) Chrome/31.0.808.0 Safari/531.2.2","locale":"en-GB","location":"GB","referrer":"","pathname":"/blog/hello-world/","href":"https://my-ghost-site.com/blog/hello-world/"}}
|
|
17
|
+
{"timestamp":"2100-01-04 01:10:48","session_id":"a6b6c4e6-19e3-47a9-afc6-d9870592652e","action":"page_hit","version":"1","payload":{"site_uuid":"mock_site_uuid","member_uuid":"undefined","member_status":"undefined","post_uuid":"6b8635fb-292f-4422-9fe4-d76cfab2ba31","user-agent":"Mozilla/5.0 (Windows; U; Windows NT 5.2) AppleWebKit/533.0.1 (KHTML, like Gecko) Chrome/32.0.856.0 Safari/533.0.1","locale":"en-GB","location":"GB","referrer":"","pathname":"/blog/hello-world/","href":"https://my-ghost-site.com/blog/hello-world/"}}
|
|
18
|
+
{"timestamp":"2100-01-04 01:16:10","session_id":"a6b6c4e6-19e3-47a9-afc6-d9870592652e","action":"page_hit","version":"1","payload":{"site_uuid":"mock_site_uuid","member_uuid":"undefined","member_status":"undefined","post_uuid":"06b1b0c9-fb53-4a15-a060-3db3fde7b1fc","user-agent":"Mozilla/5.0 (Windows; U; Windows NT 5.2) AppleWebKit/533.0.1 (KHTML, like Gecko) Chrome/32.0.856.0 Safari/533.0.1","locale":"en-GB","location":"GB","referrer":"https://my-ghost-site.com","pathname":"/about/","href":"https://my-ghost-site.com/about/"}}
|
|
19
|
+
{"timestamp":"2100-01-04 01:20:15","session_id":"a6b6c4e6-19e3-47a9-afc6-d9870592652e","action":"page_hit","version":"1","payload":{"site_uuid":"mock_site_uuid","member_uuid":"undefined","member_status":"undefined","post_uuid":"06b1b0c9-fb53-4a15-a060-3db3fde7b1fc","user-agent":"Mozilla/5.0 (Windows; U; Windows NT 5.2) AppleWebKit/533.0.1 (KHTML, like Gecko) Chrome/32.0.856.0 Safari/533.0.1","locale":"en-GB","location":"GB","referrer":"https://my-ghost-site.com","pathname":"/about/","href":"https://my-ghost-site.com/about/"}}
|
|
20
|
+
{"timestamp":"2100-01-04 01:35:41","session_id":"e22a7f6f-28da-4715-a199-6f0338b593d4","action":"page_hit","version":"1","payload":{"site_uuid":"mock_site_uuid","member_uuid":"5369031a-a5cd-4176-83d8-d6ffcb3bcfb8","member_status":"free","post_uuid":"6b8635fb-292f-4422-9fe4-d76cfab2ba31","user-agent":"Mozilla/5.0 (Windows; U; Windows NT 6.1) AppleWebKit/538.0.1 (KHTML, like Gecko) Chrome/16.0.814.0 Safari/538.0.1","locale":"en-GB","location":"GB","referrer":"","pathname":"/blog/hello-world/","href":"https://my-ghost-site.com/blog/hello-world/"}}
|
|
21
|
+
{"timestamp":"2100-01-04 01:36:33","session_id":"e22a7f6f-28da-4715-a199-6f0338b593d4","action":"page_hit","version":"1","payload":{"site_uuid":"mock_site_uuid","member_uuid":"5369031a-a5cd-4176-83d8-d6ffcb3bcfb8","member_status":"free","post_uuid":"undefined","user-agent":"Mozilla/5.0 (Windows; U; Windows NT 6.1) AppleWebKit/538.0.1 (KHTML, like Gecko) Chrome/16.0.814.0 Safari/538.0.1","locale":"en-GB","location":"GB","referrer":"https://my-ghost-site.com","pathname":"/","href":"https://my-ghost-site.com/"}}
|
|
22
|
+
{"timestamp":"2100-01-04 01:54:50","session_id":"e22a7f6f-28da-4715-a199-6f0338b593d4","action":"page_hit","version":"1","payload":{"site_uuid":"mock_site_uuid","member_uuid":"5369031a-a5cd-4176-83d8-d6ffcb3bcfb8","member_status":"free","post_uuid":"06b1b0c9-fb53-4a15-a060-3db3fde7b1fc","user-agent":"Mozilla/5.0 (Windows; U; Windows NT 6.1) AppleWebKit/538.0.1 (KHTML, like Gecko) Chrome/16.0.814.0 Safari/538.0.1","locale":"en-GB","location":"GB","referrer":"https://my-ghost-site.com","pathname":"/about/","href":"https://my-ghost-site.com/about/"}}
|
|
23
|
+
{"timestamp":"2100-01-05 01:51:00","session_id":"d8e4622f-95cc-4fba-b31b-f38ff72e0975","action":"page_hit","version":"1","payload":{"site_uuid":"mock_site_uuid","member_uuid":"75a190eb-62da-46d2-972d-a9763c954f42","member_status":"paid","post_uuid":"06b1b0c9-fb53-4a15-a060-3db3fde7b1fc","user-agent":"Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/3.0)","locale":"es-ES","location":"ES","referrer":"","pathname":"/about/","href":"https://my-ghost-site.com/about/"}}
|
|
24
|
+
{"timestamp":"2100-01-05 01:53:03","session_id":"d8e4622f-95cc-4fba-b31b-f38ff72e0975","action":"page_hit","version":"1","payload":{"site_uuid":"mock_site_uuid","member_uuid":"75a190eb-62da-46d2-972d-a9763c954f42","member_status":"paid","post_uuid":"6b8635fb-292f-4422-9fe4-d76cfab2ba31","user-agent":"Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/3.0)","locale":"es-ES","location":"ES","referrer":"https://my-ghost-site.com","pathname":"/blog/hello-world/","href":"https://my-ghost-site.com/blog/hello-world/"}}
|
|
25
|
+
{"timestamp":"2100-01-05 00:29:59","session_id":"490475f1-1fb7-4672-9edd-daa1b411b5f9","action":"page_hit","version":"1","payload":{"site_uuid":"mock_site_uuid","member_uuid":"undefined","member_status":"undefined","post_uuid":"6b8635fb-292f-4422-9fe4-d76cfab2ba31","user-agent":"Mozilla/5.0 (Windows; U; Windows NT 5.1) AppleWebKit/532.2.0 (KHTML, like Gecko) Chrome/20.0.898.0 Safari/532.2.0","locale":"en-GB","location":"GB","referrer":"https://www.baidu.com/","pathname":"/blog/hello-world/","href":"https://my-ghost-site.com/blog/hello-world/"}}
|
|
26
|
+
{"timestamp":"2100-01-05 00:37:42","session_id":"490475f1-1fb7-4672-9edd-daa1b411b5f9","action":"page_hit","version":"1","payload":{"site_uuid":"mock_site_uuid","member_uuid":"undefined","member_status":"undefined","post_uuid":"undefined","user-agent":"Mozilla/5.0 (Windows; U; Windows NT 5.1) AppleWebKit/532.2.0 (KHTML, like Gecko) Chrome/20.0.898.0 Safari/532.2.0","locale":"en-GB","location":"GB","referrer":"https://my-ghost-site.com","pathname":"/","href":"https://my-ghost-site.com/"}}
|
|
27
|
+
{"timestamp":"2100-01-05 00:38:12","session_id":"490475f1-1fb7-4672-9edd-daa1b411b5f9","action":"page_hit","version":"1","payload":{"site_uuid":"mock_site_uuid","member_uuid":"undefined","member_status":"undefined","post_uuid":"6b8635fb-292f-4422-9fe4-d76cfab2ba31","user-agent":"Mozilla/5.0 (Windows; U; Windows NT 5.1) AppleWebKit/532.2.0 (KHTML, like Gecko) Chrome/20.0.898.0 Safari/532.2.0","locale":"en-GB","location":"GB","referrer":"https://my-ghost-site.com","pathname":"/blog/hello-world/","href":"https://my-ghost-site.com/blog/hello-world/"}}
|
|
28
|
+
{"timestamp":"2100-01-06 00:51:26","session_id":"8d975128-2027-40c6-834a-972cc0293d21","action":"page_hit","version":"1","payload":{"site_uuid":"mock_site_uuid","member_uuid":"b7e0fca6-27ce-46c0-af57-c591f20dcd51","member_status":"free","post_uuid":"06b1b0c9-fb53-4a15-a060-3db3fde7b1fc","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_7 rv:2.0; KW) AppleWebKit/537.0.1 (KHTML, like Gecko) Version/5.0.10 Safari/537.0.1","locale":"fr-FR","location":"FR","referrer":"","pathname":"/about/","href":"https://my-ghost-site.com/about/"}}
|
|
29
|
+
{"timestamp":"2100-01-06 01:28:38","session_id":"61a2896b-7cf8-4853-86a6-a0e4f87c1e21","action":"page_hit","version":"1","payload":{"site_uuid":"mock_site_uuid","member_uuid":"undefined","member_status":"undefined","post_uuid":"6b8635fb-292f-4422-9fe4-d76cfab2ba31","user-agent":"Mozilla/5.0 (Windows; U; Windows NT 5.1) AppleWebKit/533.1.0 (KHTML, like Gecko) Chrome/18.0.852.0 Safari/533.1.0","locale":"en-GB","location":"GB","referrer":"https://search.yahoo.com/","pathname":"/blog/hello-world/","href":"https://my-ghost-site.com/blog/hello-world/"}}
|
|
30
|
+
{"timestamp":"2100-01-07 01:44:10","session_id":"7f1e88e1-da8e-46df-bc69-d04fb29d603d","action":"page_hit","version":"1","payload":{"site_uuid":"mock_site_uuid","member_uuid":"undefined","member_status":"undefined","post_uuid":"06b1b0c9-fb53-4a15-a060-3db3fde7b1fc","user-agent":"Mozilla/5.0 (Windows NT 5.0; WOW64; rv:13.9) Gecko/20100101 Firefox/13.9.7","locale":"en-US","location":"US","referrer":"http://wilted-tick.com","pathname":"/about/","href":"https://my-ghost-site.com/about/"}}
|
|
31
|
+
{"timestamp":"2100-01-07 02:23:19","session_id":"98159299-8111-4dc8-9156-bb339fe9508c","action":"page_hit","version":"1","payload":{"site_uuid":"mock_site_uuid","member_uuid":"undefined","member_status":"undefined","post_uuid":"06b1b0c9-fb53-4a15-a060-3db3fde7b1dd","user-agent":"Mozilla/5.0 (Windows NT 5.0; WOW64; rv:13.9) Gecko/20100101 Firefox/13.9.7","locale":"en-US","location":"US","referrer":"https://my-ghost-site.com","pathname":"/blog/hello-world/","href":"https://my-ghost-site.com/blog/hello-world/"}}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
NODE query_filters
|
|
2
|
+
DESCRIPTION >
|
|
3
|
+
Get sessions that match the filter criteria
|
|
4
|
+
|
|
5
|
+
SQL >
|
|
6
|
+
%
|
|
7
|
+
select distinct session_id
|
|
8
|
+
from _mv_hits
|
|
9
|
+
where
|
|
10
|
+
site_uuid = {{ String(site_uuid, 'mock_site_uuid', description="Tenant ID", required=True) }}
|
|
11
|
+
{% if defined(date_from) %} and toDate(toTimezone(timestamp, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}})) >= {{ Date(date_from) }} {% else %} and toDate(toTimezone(timestamp, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}})) >= timestampAdd(today(), interval -7 day) {% end %}
|
|
12
|
+
{% if defined(date_to) %} and toDate(toTimezone(timestamp, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}})) <= {{ Date(date_to) }} {% else %} and toDate(toTimezone(timestamp, {{String(timezone, 'Etc/UTC', description="Site timezone", required=True)}})) <= today() {% end %}
|
|
13
|
+
{% if defined(member_status) %}
|
|
14
|
+
and member_status IN (
|
|
15
|
+
select arrayJoin(
|
|
16
|
+
{{ Array(member_status, "'undefined', 'free', 'paid'", description="Member status to filter on", required=False) }}
|
|
17
|
+
|| if('paid' IN {{ Array(member_status) }}, ['comped'], [])
|
|
18
|
+
)
|
|
19
|
+
)
|
|
20
|
+
{% end %}
|
|
21
|
+
{% if defined(device) %} and device = {{ String(device, description="Device to filter on", required=False) }} {% end %}
|
|
22
|
+
{% if defined(browser) %} and browser = {{ String(browser, description="Browser to filter on", required=False) }} {% end %}
|
|
23
|
+
{% if defined(os) %} and os = {{ String(os, description="Operating system to filter on", required=False) }} {% end %}
|
|
24
|
+
{% if defined(source) %} and source = {{ String(source, description="Source to filter on", required=False) }} {% end %}
|
|
25
|
+
{% if defined(location) %} and location = {{ String(location, description="Location to filter on", required=False) }} {% end %}
|
|
26
|
+
{% if defined(pathname) %} and pathname = {{ String(pathname, description="Pathname to filter on", required=False) }} {% end %}
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
NODE sessions_filtered_by_source
|
|
30
|
+
DESCRIPTION >
|
|
31
|
+
Further filter by source when using the source filter. This is necessary because the source is specific to the first hit in a session,
|
|
32
|
+
whereas other filters are on hits.
|
|
33
|
+
|
|
34
|
+
SQL >
|
|
35
|
+
%
|
|
36
|
+
select session_id
|
|
37
|
+
from mv_session_data sd
|
|
38
|
+
inner join query_filters qf
|
|
39
|
+
on qf.session_id = sd.session_id
|
|
40
|
+
where
|
|
41
|
+
site_uuid = {{ String(site_uuid, 'mock_site_uuid', description="Tenant ID", required=True) }}
|
|
42
|
+
{% if defined(source) %} and source = {{ String(source, description="Source to filter on", required=False) }} {% end %}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
NODE mv_hits_0
|
|
2
|
+
SQL >
|
|
3
|
+
|
|
4
|
+
SELECT timestamp,
|
|
5
|
+
action,
|
|
6
|
+
version,
|
|
7
|
+
coalesce(session_id, '0') as session_id,
|
|
8
|
+
toString(payload.locale) as locale,
|
|
9
|
+
toString(payload.location) as location,
|
|
10
|
+
case -- this avoids really crappy null handling by the JSON type and downstream fns
|
|
11
|
+
when isNull(payload.referrer) then ''
|
|
12
|
+
else toString(payload.referrer)
|
|
13
|
+
end as referrer,
|
|
14
|
+
toString(payload.pathname) as pathname,
|
|
15
|
+
toString(payload.href) as href,
|
|
16
|
+
site_uuid,
|
|
17
|
+
toString(payload.member_uuid) as member_uuid,
|
|
18
|
+
toString(payload.member_status) as member_status,
|
|
19
|
+
toString(payload.post_uuid) as post_uuid,
|
|
20
|
+
toString(payload.post_type) as post_type,
|
|
21
|
+
lower(toString(getSubcolumn(payload,'user-agent'))) as user_agent
|
|
22
|
+
FROM analytics_events
|
|
23
|
+
where action = 'page_hit'
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
NODE mv_hits_1
|
|
28
|
+
SQL >
|
|
29
|
+
|
|
30
|
+
SELECT
|
|
31
|
+
site_uuid,
|
|
32
|
+
timestamp,
|
|
33
|
+
action,
|
|
34
|
+
version,
|
|
35
|
+
session_id,
|
|
36
|
+
member_uuid,
|
|
37
|
+
member_status,
|
|
38
|
+
post_uuid,
|
|
39
|
+
post_type,
|
|
40
|
+
location,
|
|
41
|
+
case
|
|
42
|
+
-- domainWithoutWWW returns '' if the referrer is not a valid domain
|
|
43
|
+
-- we want to maintain refs like 'ghost-newsletter'
|
|
44
|
+
when domainWithoutWWW(referrer) = '' then coalesce(referrer, '')
|
|
45
|
+
else domainWithoutWWW(referrer)
|
|
46
|
+
end as source,
|
|
47
|
+
pathname,
|
|
48
|
+
href,
|
|
49
|
+
case
|
|
50
|
+
when match(user_agent, 'wget|ahrefsbot|curl|urllib|bitdiscovery|\+https://|googlebot')
|
|
51
|
+
then 'bot'
|
|
52
|
+
when match(user_agent, 'android')
|
|
53
|
+
then 'mobile-android'
|
|
54
|
+
when match(user_agent, 'ipad|iphone|ipod')
|
|
55
|
+
then 'mobile-ios'
|
|
56
|
+
else 'desktop'
|
|
57
|
+
END as device,
|
|
58
|
+
case
|
|
59
|
+
when match(user_agent, 'windows')
|
|
60
|
+
then 'windows'
|
|
61
|
+
when match(user_agent, 'mac')
|
|
62
|
+
then 'macos'
|
|
63
|
+
when match(user_agent, 'linux')
|
|
64
|
+
then 'linux'
|
|
65
|
+
when match(user_agent, 'android')
|
|
66
|
+
then 'android'
|
|
67
|
+
when match(user_agent, 'iphone|ipad|ipod')
|
|
68
|
+
then 'ios'
|
|
69
|
+
else 'Unknown'
|
|
70
|
+
END as os,
|
|
71
|
+
case
|
|
72
|
+
when match(user_agent, 'firefox')
|
|
73
|
+
then 'firefox'
|
|
74
|
+
when match(user_agent, 'chrome|crios')
|
|
75
|
+
then 'chrome'
|
|
76
|
+
when match(user_agent, 'opera')
|
|
77
|
+
then 'opera'
|
|
78
|
+
when match(user_agent, 'msie|trident')
|
|
79
|
+
then 'ie'
|
|
80
|
+
when match(user_agent, 'iphone|ipad|safari')
|
|
81
|
+
then 'safari'
|
|
82
|
+
else 'Unknown'
|
|
83
|
+
END as browser
|
|
84
|
+
FROM mv_hits_0
|
|
85
|
+
|
|
86
|
+
TYPE materialized
|
|
87
|
+
DATASOURCE _mv_hits
|
|
88
|
+
|
|
89
|
+
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
NODE mv_hits_0
|
|
2
|
+
SQL >
|
|
3
|
+
|
|
4
|
+
SELECT
|
|
5
|
+
site_uuid,
|
|
6
|
+
session_id,
|
|
7
|
+
finalizeAggregation(countState()) as pageviews,
|
|
8
|
+
finalizeAggregation(minState(timestamp)) as first_pageview,
|
|
9
|
+
finalizeAggregation(maxState(timestamp)) as last_pageview,
|
|
10
|
+
argMin(source, timestamp) as source
|
|
11
|
+
FROM _mv_hits
|
|
12
|
+
GROUP BY site_uuid, session_id
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
NODE data
|
|
17
|
+
SQL >
|
|
18
|
+
|
|
19
|
+
SELECT
|
|
20
|
+
site_uuid,
|
|
21
|
+
session_id,
|
|
22
|
+
pageviews,
|
|
23
|
+
first_pageview,
|
|
24
|
+
last_pageview,
|
|
25
|
+
last_pageview - first_pageview AS duration,
|
|
26
|
+
pageviews = 1 AS is_bounce,
|
|
27
|
+
source
|
|
28
|
+
FROM mv_hits_0
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
## Tinybird Analytics
|
|
2
|
+
This is the web analytics implementation using [Tinybird Forward](https://www.tinybird.co/docs/forward).
|
|
3
|
+
|
|
4
|
+
### Usage
|
|
5
|
+
*Only for the first time: run `yarn tbf:install` from `/ghost/`*.
|
|
6
|
+
|
|
7
|
+
Run `yarn tbf` from `/ghost/`. This will start/install the TB Local Docker container, change the path, and start `tb dev`.
|
|
8
|
+
|
|
9
|
+
### Local
|
|
10
|
+
Run `yarn tb:local` from `/ghost/` to spin up a Docker container running Tinybird local.
|
|
11
|
+
|
|
12
|
+
In order to use `tb local` with Ghost, the config local blocks should be updated with your tokens: `tb token ls`.
|
|
13
|
+
|
|
14
|
+
Simply disable local to use the cloud version by switching `local: false` - this is switchable both via tracker script (ideally not used with the cloud data except with a unique id) and stats page.
|
|
15
|
+
|
|
16
|
+
### Config
|
|
17
|
+
Sample config:
|
|
18
|
+
```
|
|
19
|
+
"tinybird": {
|
|
20
|
+
"tracker": {
|
|
21
|
+
"endpoint": "https://e.ghost.org/tb/web_analytics",
|
|
22
|
+
"token": "xxxxx",
|
|
23
|
+
"id": "local-ghost",
|
|
24
|
+
"datasource": "analytics_events",
|
|
25
|
+
"local": {
|
|
26
|
+
"enabled": true,
|
|
27
|
+
"token": "xxxxx",
|
|
28
|
+
"endpoint": "http://localhost:7181/v0/events",
|
|
29
|
+
"datasource": "analytics_events"
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"stats": {
|
|
33
|
+
"endpoint": "https://api.tinybird.co",
|
|
34
|
+
"token": "xxxxx",
|
|
35
|
+
"id": "local-ghost",
|
|
36
|
+
"local": {
|
|
37
|
+
"enabled": true,
|
|
38
|
+
"token": "xxxxx",
|
|
39
|
+
"endpoint": "http://localhost:7181",
|
|
40
|
+
"datasource": "analytics_events"
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Testing
|
|
47
|
+
Tests are executed using `tb test run`.
|