This project is in early days, and is a work in progress.
Blockstack Stats is a client/server framework for convient, privacy-preserving analytics.
At Blockstack, we often struggle with figuring out the best way to gather analytics in our web properties. We aim to be data-driven, so collecting no information at all is problematic. At the same time, we have a strong sense of privacy, and we don't want to be sending user's data arbitrarily to third parties. We definitely don't want to let third parties inject their javascript on our pages, which may contain sensitive information.
We also want the convienient user interfaces provided by popular analytics services. We don't want to have to re-invent the wheel, or limit ourselves to open source projects that aren't as feature complete.
As a result of these problems, we've built a framework for easily collecting analytics, while proxying it through to a configurable list of destinations. We strip out all sensitive data, like IP Address, before proxying. We don't set any cookies, and we don't collect identifiable information.
Our architecture is setup just like Segment, except that you don't need to embed a third-party script, or send unproxied data through to external services.
This framework consists of two components:
The server component provides a simple API for collecting analytics. It follows the adapter pattern for passing data along to external services, so you can make a single API call, and pass through that data to whatever service you use.
Our client-side library is what you'll use in your web applications. It has a simple API, and works with modern Javascript, so you can use Typescript and import the library from NPM.
First, you'll need to get the server running.
The simplest way to do this in development is by running:
npx @blockstack/stats-server blockstack-stats-server
This will get the server running on port 5555.
In your web application, install the package @blockstack/stats
with npm
or yarn
.
yarn add @blockstack/stats
# or
npm install --save @blockstack/stats
Then, in your application, call the setConfig
method.
import { setConfig } from '@blockstack/stats';
setConfig({
host: 'https://myserver.com', // where the server can be found. Defaults to http://localhost:5555
providers: [
{
name: 'segment',
writeKey: 'your-segment-write-key'
}
]
});
The event
method is used for event tracking.
import { event } from '@blockstack/stats';
const eventName = 'clicked_login';
event({
name: eventName,
})
// You can also pass any properties with events:
event({
name: 'purchased',
product: 'Fuzzy Hat',
price: '$10.00',
});
The page
method is used to track page visits.
Call this method for every page load. Or, in a single-page-app, call this method whenever your app's screen changes.
@blockstack/stats
will automatically attach basic page data, like the origin
and path
. Other aspects of the URL that are not tracked include the search
, hash
, and document.title
, which often contain sensitive information.
page({
name: 'Home Page'
})
"Providers" are external services that consume your (privacy-enhanced) analytics. You can configure as many as you'd like. Each provider has a specific name
and configuration variables.
Segment is a service that allows you to pass your data through to one service, and it'll forward that information along to hundreds of external providers. It's what this project is modeled after!
To use the "Segment" provider, you must include a writeKey
.
import { setConfig } from '@blockstack/stats';
setConfig({
providers: [
{
name: 'segment',
writeKey: 'your-segment-write-key'
}
]
})
First, clone this repository, then run in the command line:
yarn lerna run bootstrap
We've included a simple app for testing out the package. This is very handy for when you're developing, because it requires building the client and the server at the same time.
To run everything at once (the test app, the server, while compiling the client), run in the command line:
yarn dev:watch
Note: If you've never built the client package before, you'll probably run into some errors with the above command. First, run yarn build:client
. Then, try running yarn dev:watch
.
This will open the test app at http://localhost:3333.
To add a new provider, it only takes a few steps:
In types.ts, add a new key to the Providers
enum:
export enum Providers {
// ...existing providers...
MyProvider = 'my-provider',
}
Then add whatever configuration is required, like API keys:
export interface MyProviderConfig {
name: typeof Providers.MyProvider;
apiKey: string;
}
Update the Provider
type to use your new one:
export type Provider = SegmentConfig | MyProviderConfig;
To follow along, it's best to look at existing implementations, like SegmentProvider.
The server needs to know how to pass this data to the provider. Create a new file in packages/server/src/providers for your implementation.
You'll need to extend the BaseProvider
class, then implement the static event
and page
methods. You must follow the same method signature as BaseProvider
. The event
method accepts a eventData
parameter, whose type can be found here.
Most analytics services provide a package for passing events in node.js, and it's best to use that, if available.
Finally, update nameToProvider
in utils.ts.
const nameToProvider = {
// existing providers...
[Providers.MyProvider]: MyProviderProvider,
};