Working with the Snowtype CLI
Snowtype CLIโ
The Snowtype CLI is a tool which aims to speed up tracking implementations, provide type safety and inline documentation for developers and ultimately reduce the number of erroneous events. By integrating this tool in the development workflow we introduce a way to connect the additions and updates done in a Snowplow implementation with the corresponding tracking code of the project.
Authenticating with the Consoleโ
A Console API key is required for the Snowtype CLI to authenticate with your account. You can find your own or create one in the Console API key management.
From there, the ways for the CLI to recognize the key are either through the global -k, --apiKey
option or the SNOWPLOW_CONSOLE_API_KEY
environment variable. The Snowtype CLI does automatically read from a .env
file at the root of your project as well.
- .env file
- Shell variable
- CLI parameter
SNOWPLOW_CONSOLE_API_KEY=MY-API-KEY
# The required command will depend on your shell
export SNOWPLOW_CONSOLE_API_KEY=MY-API-KEY
npx snowtype generate --apiKey MY-API-KEY
Recommended: We recommend that you use the SNOWPLOW_CONSOLE_API_KEY
environment variable.
Initializing Snowtype for your projectโ
For the Snowtype CLI to work properly, it requires a configuration file to be initialized and present on your project's root folder. This file will be automatically generated using the snowtype init
command, after adding the required input.
# Start prompting for configuration inputs
npx snowtype init
The input required for the initialization to work, it the following:
- The organization ID from the BDP console.
- The tracker you wish to generate code for.
- If applicable, the language for that tracker.
- The output path you wish the CLI to generate the code to.
These will all be prompted to you by default, but if needed you can call the snowtype init
command with any or all the attributes passed as optional flags so prompting is not required.
Generate tracking codeโ
The CLI will generate tracking code using a valid Snowtype configuration file with the snowtype generate command
. The code that will be generated, depending on the language, will have all the required types used in schemas and Event Specifications together with methods/classes that allows for tracking these.
# Code will be generated to the outpath configuration
npx snowtype generate
The code generated by the CLI is not minified and contains inline documentation for methods, classes and types. If needed you can modify it in any way it suits your project.
Contentsโ
The contents of a generated file from the Snowtype CLI will be:
- Types/Interfaces/Classes for each schema that relates to the Data Structures, Iglu Central Schemas and Event Specifications selected.
- For each schema:
- A method/class to instantiate the structure as a Self Describing JSON. This is particularly useful to add entities as extra context on events.
- A method that sends a Self Describing Event with the schema as the main event entity.
- For each Event Specification, a method/class to track the specific event specification.
The Snowtype CLI does not automatically install the required Snowplow tracking libraries. For now it generates code that use the tracking libraries which are expected to be installed on the project.
Available Trackers/Languagesโ
Following is the set of available trackers and languages the Snowtype CLI currently can work with. This list is also the source of truth for valid keys in the tracker
and language
attributes of the Snowtype configuration file.
Tracker | Language/s |
---|---|
@snowplow/browser-tracker | javascript, typescript |
@snowplow/node-tracker | javascript, typescript |
@snowplow/react-native-tracker | typescript |
@snowplow/javascript-tracker | javascript |
snowplow-golang-tracker | go |
snowplow-ios-tracker | swift |
snowplow-android-tracker | kotlin |
Example Usageโ
Below we show example usage of the generated code. For demonstration, we assume the code was generated for the web_page and product schemas.
- @snowplow/browser-tracker TypeScript
- @snowplow/node-tracker TypeScript
- snowplow-android-tracker
- snowplow-ios-tracker
- snowplow-golang-tracker
- @snowplow/react-native-tracker TypeScript
import {
trackWebPage,
createProduct,
WebPage,
Product,
createWebPage,
} from "./{outpath}/snowplow";
/* Track a WebPage event */
trackWebPage({ id: "212a9b63-1af7-4e96-9f35-e2fca110ff43" });
/* Track a WebPage event with a Product context entity */
const product = createProduct({
id: "Product id",
name: "Snowplow product",
currency: "EUR",
price: 10,
category: "Snowplow/Shoes",
});
trackWebPage({
id: "212a9b63-1af7-4e96-9f35-e2fca110ff43",
context: [product],
});
/* You can enforce specific context entities on any `track` function using type arguments */
const webPage = createWebPage({ id: "212a9b63-1af7-4e96-9f35-e2fca110ff43" });
trackWebPage<Product | WebPage>({
id: "212a9b63-1af7-4e96-9f35-e2fca110ff43",
context: [product, webPage],
});
import {
trackWebPage,
createProduct,
WebPage,
Product,
createWebPage,
} from "./{outpath}/snowplow";
/* `t` is the tracker instance created by the `tracker` function of the @snowplow/node-tracker package. */
/* Track a WebPage event */
trackWebPage(t, { id: "212a9b63-1af7-4e96-9f35-e2fca110ff43" });
/* Track a WebPage event with a Product context entity */
const product = createProduct({
id: "Product id",
name: "Snowplow product",
currency: "EUR",
price: 10,
category: "Snowplow/Shoes",
});
trackWebPage(t, {
id: "212a9b63-1af7-4e96-9f35-e2fca110ff43",
context: [product],
});
/* You can enforce specific context entities on any `track` function using type arguments */
const webPage = createWebPage({ id: "212a9b63-1af7-4e96-9f35-e2fca110ff43" });
trackWebPage<Product | WebPage>(t, {
id: "212a9b63-1af7-4e96-9f35-e2fca110ff43",
context: [product, webPage],
});
import {{ specified package }}.Product
import {{ specified package }}.WebPage
/* Track a WebPage event */
tracker.track(WebPage(id = "212a9b63-1af7-4e96-9f35-e2fca110ff43").toEvent())
/* Track a WebPage event with a Product context entity */
val product = Product(
id = "Product id",
name = "Snowplow product",
currency = "EUR",
price = 10.0,
category = "Snowplow/Shoes",
)
val event = WebPage(id = "212a9b63-1af7-4e96-9f35-e2fca110ff43").toEvent()
event.entities.add(product.toEntity())
tracker.track(event)
import SnowplowTracker
/* Track a WebPage event */
_ = tracker.track(WebPage(id: "212a9b63-1af7-4e96-9f35-e2fca110ff43").toEvent())
/* Track a WebPage event with a Product context entity */
let product = Product(
category: "Snowplow/Shoes",
currency: "EUR",
id: "Product id",
name: "Snowplow product",
price: 10
)
let event = WebPage(id: "212a9b63-1af7-4e96-9f35-e2fca110ff43").toEvent()
event.entities.append(product.toEntity())
_ = tracker.track(event)
// Track a WebPage event
TrackWebPage(tracker, WebPage{ID: "212a9b63-1af7-4e96-9f35-e2fca110ff43"})
// Track a WebPage event with a Product context entity
productName := "Snowplow product"
product := Product{
ID: "Product_id",
Currency: "EUR",
Price: 10,
Category: "Snowplow/Shoes",
Name: &productName,
}
TrackWebPage(
tracker,
WebPage{ID: "212a9b63-1af7-4e96-9f35-e2fca110ff43"},
WithContexts(product),
)
import {
trackWebPage,
createProduct,
WebPage,
Product,
createWebPage,
} from "./{outpath}/snowplow";
/* `t` is the tracker instance created by the `createTracker` function of the @snowplow/react-native-tracker package. */
/* Track a WebPage event */
trackWebPage(t, { id: "212a9b63-1af7-4e96-9f35-e2fca110ff43" });
/* Track a WebPage event with a Product context entity */
const product = createProduct({
id: "Product id",
name: "Snowplow product",
currency: "EUR",
price: 10,
category: "Snowplow/Shoes",
});
trackWebPage(t, {
id: "212a9b63-1af7-4e96-9f35-e2fca110ff43",
context: [product],
});
/* You can enforce specific context entities on any `track` function using type arguments */
const webPage = createWebPage({ id: "212a9b63-1af7-4e96-9f35-e2fca110ff43" });
trackWebPage<Product | WebPage>(t, {
id: "212a9b63-1af7-4e96-9f35-e2fca110ff43",
context: [product, webPage],
});
Event Specificationsโ
To add an Event Specification to the code generation, either manually or through the snowtype patch
command, you would need the ID of the event specification. You can find the Event Specification ID in the main page of the event specification as shown below:
Then you should add this ID to your snowtype.config.json
eventSpecificationIds
array.
Data Structuresโ
To add a Data Structure to the code generation, either manually or through the snowtype patch
command, you would need the Data Structure Schema tracking URL
. You can find the Data Structure tracking URL on the Data Structure page in the Console, under the Overview tab as shown below:
Then you should add this Data Structure tracking URL to your snowtype.config.json
dataStructures
array.
Iglu Central Schemasโ
To add a Data Structure to the code generation, either manually or through the snowtype patch
command, you would need the Schema tracking URL
. You can find the Schema tracking URL on Iglu Central by searching for the schema and under the General Information tab you can find the URL as shown below:
Then you should add this Schema tracking URL to your snowtype.config.json
igluCentralSchemas
array.
Generating event specification instructionsโ
When generating code for Event Specifications, you have the option of delivering the implementation instructions and triggers for each scenario right on the developer's environment.
By using the --instructions
option on the snowtype generate
command, you can generate a markdown file with all the required information about tracking an event specification.
This includes:
- Trigger description.
- Images uploaded on your Event Specification triggers.
- App identifiers and URLs this event should be triggered on.
- Direct links to the code for this Event Specification.
Keeping up with latest updatesโ
It is important that the tracking code is up-to-date with latest versions of Data Structures and Event Specifications we are tracking on a project. The Snowtype CLI gives the engineers the ability to check if there are available updates for Data Structures and Event Specifications that are used in the project.
This works with the snowtype update
command.
npx snowtype update
The above command will output a diff showing the available version updates, similar to what you can see below:
In that case, you can select to update to latest versions and regenerate the tracking code. To automatically update and regenerate the tracking code reflecting the latest updates, you can use the --yes
flag.