Skip to content

Commit

Permalink
Upgrade to Ackee v3 with Events tracking
Browse files Browse the repository at this point in the history
  • Loading branch information
oakify committed Jan 24, 2021
1 parent eccef40 commit bd48ab3
Show file tree
Hide file tree
Showing 12 changed files with 354 additions and 103 deletions.
138 changes: 114 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,64 +1,78 @@
# Angular Ackee Wrapper

This is an Angular wrapper library for [Ackee](https://ackee.electerious.com/).
Please make sure you have a working Ackee server (self-hosted) before you use this lib.
Also, please read Ackee's [docs](https://docs.ackee.electerious.com/).
This is an Angular wrapper library for [ackee-tracker](https://github.com/electerious/ackee-tracker), the client-side piece of [Ackee](https://ackee.electerious.com/) analytics.

## I. Install in your Angular App
_This version is now (ONLY) compatible with Ackee v3, including event tracking! See [Release Notes for v3](https://github.com/electerious/Ackee/releases/tag/v3.0.0)_

### I.a) With NPM
> 🚨 BREAKING CHANGES: the `.create()` method was renamed to `.visit()` for better naming consistency with `.event()` - one tracks a **_visit_** and the other an **_event_**. Both **_create_** the instance if it does not exist. Also, the interface `AckeeOptions` has been renamed `AckeeConfig`.
Please make sure you read Ackee's [docs](https://docs.ackee.electerious.com/) before you use this lib.

For more insights on how this wrapper works, you can clone its [repository](https://github.com/oakify/ngx-ackee-wrapper) which contains a test app.

> ⚠️ _There are 2 ways to get ackee-tracker: from your Ackee instance (i.e: https://yourackeeinstance.com/**tracker.js**) or from npm. This library only supports getting it from your instance, which is the way that is reccomended by the Ackee devs._
## 1. Installing the library ⚙️

### 1.1. Download & add to your project

```shell
$ npm install ngx-ackee-wrapper
```

### I.b) Or Yarn
Or

```shell
$ yarn add ngx-ackee-wrapper
```

## II. Update your AppModule
### 1.2. Update your AppModule

```typescript
import { BrowserModule } from "@angular/platform-browser";
import { NgModule } from "@angular/core";

import { AppComponent } from "./app.component";

import { AckeeModule, AckeeOptions } from "ngx-ackee-wrapper"; // <-- HERE
import { AckeeModule, AckeeOptions } from "ngx-ackee-wrapper"; // <-- 1. ADD THIS

// configure your ackee client with (see chapter III. for more info)
// 2. Configure to your Ackee instance:
const ACKEE_CONFIG: AckeeOptions = {
tracker: "https://example.com/tracker.js",
server: "https://example.com",
tracker: "https://yourackeeinstance.com/tracker.js",
server: "https://yourackeeinstance.com",
domainId: "12312311-1234-1234-1234-123412341234",
options: {
// ignoreLocalhost: false,
// detailed: true,
// ignoreOwnVisits: true,
},
dev: true, // Will add to log - useful in dev if you chose ignoreLocalhost: false
dev: true,
};

@NgModule({
declarations: [AppComponent],
imports: [BrowserModule, AckeeModule.forRoot(ACKEE_CONFIG)], // <-- add AckeeModule & config
imports: [BrowserModule, AckeeModule.forRoot(ACKEE_CONFIG)], // <-- 3. Add AckeeModule & config to imports
providers: [],
bootstrap: [AppComponent],
})
export class AppModule {}
```

## III. Options
Configuration:

- **tracker:** The full url to your instance's tracker (you can configure a custom name other than tracker.js). See [here](https://github.com/electerious/ackee-tracker#-installation).

- **tracker:** The url to your instance's tracker (you could have a custom name) - it is recommended by Ackee's developer to use the tracker from your instance instead of the package ackee-tracker. See [here](https://github.com/electerious/ackee-tracker#-installation).
- **server, domainId & options:** same as in ackee-tracker, see the [docs](https://github.com/electerious/ackee-tracker#createserver-opts).

- **server, domainId & options:** same as ackee-tracker, see their [docs](https://github.com/electerious/ackee-tracker#createserver-opts).
- **dev:** optional, will add a message to console log - just a check to see if it runs

- **dev:** optional, useful if you want to see check tracking from your console when using `ignoreLocalhost: false`
> Note: You can also use environment variables as demonstrated in the demo app.
## IV. TRACK
## 2. Using the Library 🚀

### 2.1. Track visits

In your Component:

```typescript
import { Component } from "@angular/core";
Expand All @@ -73,16 +87,92 @@ import { filter } from "rxjs/operators";
})
export class AppComponent {
constructor(private ackeeServ: AckeeService, private router: Router) {
// Don't track route changes (not sure why you wouldn't want to, but you have the option)
// this.ackeeServ.create();
// Don't track route changes:
// this.ackeeServ.visit();

// Track route changes (recommended)
this.ackeeServ.create(
// Track route changes:
this.ackeeServ.visit(
this.router.events.pipe(filter((evt) => evt instanceof NavigationEnd))
);
}
}
```

To track route changes, we get the router's events (an `Observable<Event>`) and we filter them to get only NavigationEnd types of events. If you want you can use NavigationStart instead.
I personally prefer NavigationEnd so that we track only pages that have effectively loaded.
To track route changes, we get the router's events (an `Observable<Event>`) and we filter them to get only the events of type NavigationEnd. If you want, you can use NavigationStart instead. In fact you can pass any Observable you want to get fancy with the tracking. I personally prefer NavigationEnd so that I only track the pages that have effectively loaded.

If you don't want to track route changes, just don't pass anything in `.visit()`:

```typescript
this.ackeeServ.visit();
```

_This will result in only one page or visit recorded for your entire Angular app, no mater how many routes were opened (unless the user reloads the page). The upside of this option however, is that the recorded "duration" of the visit will be for the entire session of the use of the app._

### 2.2. Track events: `.event()`

You can track any event you want. Please read the docs to understand how that translates to the Ackee reporting.

For example, to track a click on a button, in your HTML Template:

```HTML
<button (click)="triggerAction()">Click for Event</button>
```

In your Component:

```typescript
triggerAction() {
this.ackeeServ.event(
'evnt-id-from-ackee-instance-settings-page',
{
key: 'your-event-key',
value: 1,
},
(actionId: string) => (this.actionId = actionId)
);
}
```

Parameters:

- `eventId` `(string)`: get it from you Ackee's instance settings page;
- `attributes` `({key:string; value:number})`: record whatever you want;
- `callback` (optional): will receive the `actionId (string)` that lets you update your event later, if required.

### 2.2. Update events `.eventUpdate()`

You can change the attibutes of any past event as long as you have its `actionId` that you get from the callback in `.event()`.

In your Component:

```typescript
this.ackeeServ.eventUpdate("the-action-id-from-event-method", {
key: "your-key",
value: 42,
});
```

Parameters:

- `actionId` `(string)`: get it from the callback in `.event()` - see above;
- `attributes` `({key:string; value:number})`: update the record with whatever you want;

## 3. Miscellaneous 🦦

### 3.1 License

MIT - Software is provided as is, no liability to the developer.

### 3.2 Donate to the Ackee developer (not me)

Please consider donating to the developer of Ackee to keep this amazing project going. They are working hard, continuously developing and maintaining Ackee as a free, self hosted, privacy-first analytics solution.

- [Become a GitHub sponsor of the Ackee dev](https://github.com/sponsors/electerious)
- [Donate via PayPal to the Ackee dev](https://paypal.me/electerious)
- [Buy the Ackee dev a coffee](https://www.buymeacoffee.com/electerious)

### 3.3 Links

- [Ackee Official](https://ackee.electerious.com/)
- [Follow Ackee on Twitter](https://twitter.com/getackee)
- [Vote for Ackee on ProductHunt](https://www.producthunt.com/posts/ackee)
7 changes: 6 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "ngx-ackee-wrapper",
"description": "Angular wrapper library for Ackee",
"version": "0.0.1",
"version": "1.0.0",
"license": "MIT",
"author": "Oakify",
"scripts": {
Expand All @@ -14,6 +14,11 @@
"e2e": "ng e2e"
},
"private": true,
"homepage": "https://github.com/oakify/ngx-ackee-wrapper",
"repository": {
"type": "git",
"url": "https://github.com/oakify/ngx-ackee-wrapper.git"
},
"dependencies": {
"@angular/animations": "~10.1.4",
"@angular/common": "~10.1.4",
Expand Down
2 changes: 2 additions & 0 deletions projects/app/src/app/app.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ <h2>Test App for ngx-ackee-wrapper</h2>
<a routerLink="/a" routerLinkActive="active">Child A</a>
<a routerLink="/b" routerLinkActive="active">Child B</a>
</nav>
<button (click)="triggerAction()">Click for Event</button>
<button (click)="triggerActionUpdate()">Click for Event Update</button>
</div>

<router-outlet></router-outlet>
22 changes: 19 additions & 3 deletions projects/app/src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,29 @@ import { filter } from 'rxjs/operators';
styleUrls: ['./app.component.scss'],
})
export class AppComponent {
actionId: string;
constructor(private ackeeServ: AckeeService, private router: Router) {
// Don't track route changes:
// this.ackeeServ.create();

// this.ackeeServ.visit();
// Track route changes:
this.ackeeServ.create(
this.ackeeServ.visit(
this.router.events.pipe(filter((evt) => evt instanceof NavigationEnd))
);
}
triggerAction() {
this.ackeeServ.event(
'evnt-id-from-ackee-instance-settings-page',
{
key: 'your-event-key',
value: 1,
},
(actionId: string) => (this.actionId = actionId)
);
}
triggerActionUpdate() {
this.ackeeServ.eventUpdate(this.actionId, {
key: 'your-key',
value: 42,
});
}
}
13 changes: 7 additions & 6 deletions projects/app/src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,17 @@ import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { CompaComponent } from './compa/compa.component';
import { CompbComponent } from './compb/compb.component';
import { environment } from '../environments/environment';

import { AckeeModule, AckeeOptions } from 'projects/lib/src/public-api';
import { AckeeModule, AckeeConfig } from 'projects/lib/src/public-api';
// import { AckeeModule, AckeeOptions } from 'ngx-ackee-wrapper';

const ACKEE_CONFIG: AckeeOptions = {
tracker: 'https://example.com/tracker.js',
server: 'https://example.com',
domainId: '12312311-1234-1234-1234-123412341234',
const ACKEE_CONFIG: AckeeConfig = {
tracker: environment.ackeeUrl + '/tracker.js',
server: environment.ackeeUrl,
domainId: environment.ackeeDomainId,
options: {
// ignoreLocalhost: true,
ignoreLocalhost: false,
detailed: true,
// ignoreOwnVisits: true,
},
Expand Down
4 changes: 3 additions & 1 deletion projects/app/src/environments/environment.prod.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
export const environment = {
production: true
production: true,
ackeeUrl: 'https://example.com',
ackeeDomainId: '12312311-1234-1234-1234-123412341234',
};
4 changes: 3 additions & 1 deletion projects/app/src/environments/environment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
// The list of file replacements can be found in `angular.json`.

export const environment = {
production: false
production: false,
ackeeUrl: 'https://example.com',
ackeeDomainId: '12312311-1234-1234-1234-123412341234',
};

/*
Expand Down
22 changes: 11 additions & 11 deletions projects/app/src/index.html
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
<!doctype html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>App</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
<app-root></app-root>
</body>
<head>
<meta charset="utf-8" />
<title>App</title>
<base href="/" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" type="image/x-icon" href="favicon.ico" />
</head>
<body>
<app-root></app-root>
</body>
</html>
Loading

0 comments on commit bd48ab3

Please sign in to comment.