Skip to content

Commit 4840bf8

Browse files
authored
Add Fullstory integration (#957)
* Add Fullstory integration * Add changeset for Fullstory integration * Fix lockfile
1 parent 93475b2 commit 4840bf8

File tree

10 files changed

+292
-2
lines changed

10 files changed

+292
-2
lines changed

.changeset/tender-shrimps-raise.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@gitbook/integration-fullstory": patch
3+
---
4+
5+
Add Fullstory integration

bun.lock

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,18 @@
122122
"@gitbook/tsconfig": "workspace:*",
123123
},
124124
},
125+
"integrations/fullstory": {
126+
"name": "@gitbook/integration-fullstory",
127+
"version": "0.1.0",
128+
"dependencies": {
129+
"@gitbook/api": "*",
130+
"@gitbook/runtime": "*",
131+
},
132+
"devDependencies": {
133+
"@gitbook/cli": "workspace:*",
134+
"@gitbook/tsconfig": "workspace:*",
135+
},
136+
},
125137
"integrations/github": {
126138
"name": "@gitbook/integration-github",
127139
"version": "0.6.3",
@@ -531,7 +543,7 @@
531543
},
532544
"integrations/slack": {
533545
"name": "@gitbook/integration-slack",
534-
"version": "2.4.0",
546+
"version": "2.5.0",
535547
"dependencies": {
536548
"@gitbook/api": "*",
537549
"@gitbook/runtime": "*",
@@ -652,7 +664,7 @@
652664
},
653665
"packages/api": {
654666
"name": "@gitbook/api",
655-
"version": "0.137.0",
667+
"version": "0.138.0",
656668
"dependencies": {
657669
"event-iterator": "^2.0.0",
658670
"eventsource-parser": "^3.0.0",
@@ -997,6 +1009,8 @@
9971009

9981010
"@gitbook/integration-formspree": ["@gitbook/integration-formspree@workspace:integrations/formspree"],
9991011

1012+
"@gitbook/integration-fullstory": ["@gitbook/integration-fullstory@workspace:integrations/fullstory"],
1013+
10001014
"@gitbook/integration-github": ["@gitbook/integration-github@workspace:integrations/github"],
10011015

10021016
"@gitbook/integration-github-copilot": ["@gitbook/integration-github-copilot@workspace:integrations/github-copilot"],

integrations/fullstory/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# @gitbook/integration-fullstory
478 KB
Loading
5.8 KB
Loading
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
name: fullstory
2+
title: Fullstory
3+
icon: ./assets/icon.png
4+
organization: gitbook
5+
description: Capture user sessions in GitBook with Fullstory to understand reader behavior and improve UX.
6+
previewImages:
7+
- ./assets/fullstory-preview.png
8+
externalLinks:
9+
- label: Documentation
10+
url: https://www.gitbook.com/integrations/fullstory
11+
visibility: public
12+
script: ./src/index.ts
13+
# The following scope(s) are available only to GitBook Staff
14+
# See https://developer.gitbook.com/integrations/configurations#scopes
15+
scopes:
16+
- site:script:inject
17+
- site:script:cookies
18+
contentSecurityPolicy:
19+
script-src: |
20+
https://fullstory.com
21+
https://edge.fullstory.com;
22+
img-src: |
23+
data:
24+
blob:
25+
fullstory.com
26+
edge.fullstory.com;
27+
font-src: |
28+
data:;
29+
connect-src: |
30+
fullstory.com
31+
edge.fullstory.com
32+
about:;
33+
summary: |
34+
# Overview
35+
36+
Fullstory is a digital experience analytics platform that helps companies understand how users interact with their websites and apps. The Fullstory integration for GitBook allows you to gather analytics in Fullstory from visitors to your docs site.
37+
38+
# How it works
39+
40+
AI-powered insights from your documentation: Each of your connected GitBook sites will fetch the Fullstory tracking script and inject it into your public content.
41+
42+
# Configure
43+
44+
GitBook admins can enable the Fullstory integration by navigating to organization settings. The integration can be enabled on a per-site basis or for all sites in the organization.
45+
categories:
46+
- analytics
47+
configurations:
48+
site:
49+
properties:
50+
organization_id:
51+
type: string
52+
title: Organization ID
53+
description: Look for this in your Fullstory account.
54+
required:
55+
- organization_id
56+
target: site

integrations/fullstory/package.json

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"name": "@gitbook/integration-fullstory",
3+
"version": "0.1.0",
4+
"private": true,
5+
"dependencies": {
6+
"@gitbook/api": "*",
7+
"@gitbook/runtime": "*"
8+
},
9+
"devDependencies": {
10+
"@gitbook/cli": "workspace:*",
11+
"@gitbook/tsconfig": "workspace:*"
12+
},
13+
"scripts": {
14+
"typecheck": "tsc --noEmit",
15+
"publish-integrations-staging": "gitbook publish .",
16+
"check": "gitbook check",
17+
"publish-integrations": "gitbook publish ."
18+
}
19+
}

integrations/fullstory/src/index.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import {
2+
createIntegration,
3+
FetchPublishScriptEventCallback,
4+
RuntimeContext,
5+
RuntimeEnvironment,
6+
} from '@gitbook/runtime';
7+
8+
import script from './script.raw.js';
9+
10+
type FullStoryRuntimeContext = RuntimeContext<
11+
RuntimeEnvironment<
12+
{},
13+
{
14+
organization_id?: string;
15+
}
16+
>
17+
>;
18+
19+
export const handleFetchEvent: FetchPublishScriptEventCallback = async (
20+
event,
21+
{ environment }: FullStoryRuntimeContext,
22+
) => {
23+
const organizationId = environment.siteInstallation?.configuration?.organization_id;
24+
if (!organizationId) {
25+
return;
26+
}
27+
28+
return new Response((script as string).replace('<TO_REPLACE>', organizationId), {
29+
headers: {
30+
'Content-Type': 'application/javascript',
31+
'Cache-Control': 'max-age=604800',
32+
},
33+
});
34+
};
35+
36+
export default createIntegration<FullStoryRuntimeContext>({
37+
fetch_published_script: handleFetchEvent,
38+
});
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
window['_fs_host'] = 'fullstory.com';
2+
window['_fs_script'] = 'edge.fullstory.com/s/fs.js';
3+
window['_fs_org'] = '<TO_REPLACE>';
4+
window['_fs_namespace'] = 'FS';
5+
!(function (m, n, e, t, l, o, g, y) {
6+
var s,
7+
f,
8+
a = (function (h) {
9+
return (
10+
!(h in m) ||
11+
(m.console &&
12+
m.console.log &&
13+
m.console.log(
14+
'FullStory namespace conflict. Please set window["_fs_namespace"].',
15+
),
16+
!1)
17+
);
18+
})(e);
19+
function p(b) {
20+
var h,
21+
d = [];
22+
function j() {
23+
h &&
24+
(d.forEach(function (b) {
25+
var d;
26+
try {
27+
d = b[h[0]] && b[h[0]](h[1]);
28+
} catch (h) {
29+
return void (b[3] && b[3](h));
30+
}
31+
d && d.then ? d.then(b[2], b[3]) : b[2] && b[2](d);
32+
}),
33+
(d.length = 0));
34+
}
35+
function r(b) {
36+
return function (d) {
37+
h || ((h = [b, d]), j());
38+
};
39+
}
40+
return (
41+
b(r(0), r(1)),
42+
{
43+
then: function (b, h) {
44+
return p(function (r, i) {
45+
d.push([b, h, r, i]), j();
46+
});
47+
},
48+
}
49+
);
50+
}
51+
a &&
52+
((g = m[e] =
53+
(function () {
54+
var b = function (b, d, j, r) {
55+
function i(i, c) {
56+
h(b, d, j, i, c, r);
57+
}
58+
r = r || 2;
59+
var c,
60+
u = /Async$/;
61+
return u.test(b)
62+
? ((b = b.replace(u, '')),
63+
'function' == typeof Promise ? new Promise(i) : p(i))
64+
: h(b, d, j, c, c, r);
65+
};
66+
function h(h, d, j, r, i, c) {
67+
return b._api
68+
? b._api(h, d, j, r, i, c)
69+
: (b.q && b.q.push([h, d, j, r, i, c]), null);
70+
}
71+
return (b.q = []), b;
72+
})()),
73+
(y = function (b) {
74+
function h(h) {
75+
'function' == typeof h[4] && h[4](new Error(b));
76+
}
77+
var d = g.q;
78+
if (d) {
79+
for (var j = 0; j < d.length; j++) h(d[j]);
80+
(d.length = 0), (d.push = h);
81+
}
82+
}),
83+
(function () {
84+
((o = n.createElement(t)).async = !0),
85+
(o.crossOrigin = 'anonymous'),
86+
(o.src = 'https://' + l),
87+
(o.onerror = function () {
88+
y('Error loading ' + l);
89+
});
90+
var b = n.getElementsByTagName(t)[0];
91+
b && b.parentNode ? b.parentNode.insertBefore(o, b) : n.head.appendChild(o);
92+
})(),
93+
(function () {
94+
function b() {}
95+
function h(b, h, d) {
96+
g(b, h, d, 1);
97+
}
98+
function d(b, d, j) {
99+
h('setProperties', { type: b, properties: d }, j);
100+
}
101+
function j(b, h) {
102+
d('user', b, h);
103+
}
104+
function r(b, h, d) {
105+
j(
106+
{
107+
uid: b,
108+
},
109+
d,
110+
),
111+
h && j(h, d);
112+
}
113+
(g.identify = r),
114+
(g.setUserVars = j),
115+
(g.identifyAccount = b),
116+
(g.clearUserCookie = b),
117+
(g.setVars = d),
118+
(g.event = function (b, d, j) {
119+
h(
120+
'trackEvent',
121+
{
122+
name: b,
123+
properties: d,
124+
},
125+
j,
126+
);
127+
}),
128+
(g.anonymize = function () {
129+
r(!1);
130+
}),
131+
(g.shutdown = function () {
132+
h('shutdown');
133+
}),
134+
(g.restart = function () {
135+
h('restart');
136+
}),
137+
(g.log = function (b, d) {
138+
h('log', { level: b, msg: d });
139+
}),
140+
(g.consent = function (b) {
141+
h('setIdentity', { consent: !arguments.length || b });
142+
});
143+
})(),
144+
(s = 'fetch'),
145+
(f = 'XMLHttpRequest'),
146+
(g._w = {}),
147+
(g._w[f] = m[f]),
148+
(g._w[s] = m[s]),
149+
m[s] &&
150+
(m[s] = function () {
151+
return g._w[s].apply(this, arguments);
152+
}),
153+
(g._v = '2.0.0'));
154+
})(window, document, window._fs_namespace, 'script', window._fs_script);

integrations/fullstory/tsconfig.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"extends": "@gitbook/tsconfig/integration.json"
3+
}

0 commit comments

Comments
 (0)