Skip to content

Commit a472ab9

Browse files
committed
feat: Add support for meta through post requests
Fixes #24
1 parent 298ad7e commit a472ab9

File tree

3 files changed

+50
-14
lines changed

3 files changed

+50
-14
lines changed

packages/micro-analytics-cli/readme.md

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,28 @@ To track a view of `x`, simply send a request to `/x`. This is how you'd track p
4444
</script>
4545
```
4646

47-
If you send a `GET` request, the request will increment the views and return the total views for the id. (in this case "x") If you send a `POST` request, the views will increment but you don't get the total views back.
47+
If you send a `GET` or `POST` request, the request will increment the views and return the total views for the id (in this case "x").
4848

4949
#### `GET` the views without incrementing
5050

5151
If you just want to get the views for an id and don't want to increment the views during a `GET` request, set `inc` to `false` in your query parameter. (`/x?inc=false`)
5252

53+
#### `POST` to add metadata
54+
55+
You can add more metadata to the view by posting a JSON payload with the field `meta`. Everything in that meta field will be set on meta in the view object. You can read
56+
the data out with the `all` option, see below for more info. Example request that will post the browser useragent string:
57+
58+
```html
59+
<script>
60+
fetch('servicedomain.com' + window.location.pathname, {
61+
method: "POST",
62+
credentials: "include",
63+
headers: {"Content-Type": "application/json"},
64+
body: JSON.stringify({meta: { browser: navigator.userAgent }}),
65+
})
66+
</script>
67+
```
68+
5369
### Getting all views
5470

5571
If you want to get all views for all ids, set the `all` query parameter to `true` on a root request. (i.e. `/?all=true`) If you pass the `all` parameter to an id, all ids starting with that pathname will be included. E.g. `/x?all=true` will match views for `/x`, `/xyz` but not `/y`.

packages/micro-analytics-cli/src/handler.js

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
const url = require('url');
2-
const { send, createError, sendError } = require('micro');
2+
const { json, send, createError, sendError } = require('micro');
33

44
const db = require('./db');
55
const healthcheckHandler = require('./healthcheck');
@@ -24,6 +24,14 @@ function realtimeHandler(req, res) {
2424
}
2525
}
2626

27+
async function readMeta(req) {
28+
try {
29+
return (await json(req)).meta;
30+
} catch (error) {
31+
return null;
32+
}
33+
}
34+
2735
async function analyticsHandler(req, res) {
2836
const { pathname, query } = url.parse(req.url, /* parseQueryString */ true);
2937
res.setHeader('Access-Control-Allow-Origin', '*');
@@ -55,17 +63,18 @@ async function analyticsHandler(req, res) {
5563
const shouldIncrement = String(query.inc) !== 'false';
5664
try {
5765
const currentViews = (await db.has(pathname)) ? (await db.get(pathname)).views.length : 0;
58-
// Add a view and send the total views back to the client
59-
if (shouldIncrement) {
60-
await pushView(pathname, { time: Date.now() });
66+
const meta = await readMeta(req);
67+
68+
const data = { time: Date.now() };
69+
if (meta) {
70+
data.meta = meta;
6171
}
62-
if (req.method === 'GET') {
63-
send(res, 200, {
64-
views: shouldIncrement ? currentViews + 1 : currentViews,
65-
});
66-
} else {
67-
send(res, 200);
72+
73+
if (shouldIncrement) {
74+
await pushView(pathname, data);
6875
}
76+
77+
send(res, 200, { views: shouldIncrement ? currentViews + 1 : currentViews });
6978
} catch (err) {
7079
console.log(err);
7180
throw createError(500, 'Internal server error.');

packages/micro-analytics-cli/tests/items.test.js

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,20 @@ describe('single', () => {
4141
expect(body.views).toEqual(1);
4242
});
4343

44-
it('should not return anything for a POST request', async () => {
45-
const body = await request.post(`${server.url}/existant`);
46-
expect(body).toEqual('');
44+
describe('POST', () => {
45+
it('should increment the views of an existant path', async () => {
46+
await request.post(`${server.url}/existant`);
47+
const body = JSON.parse(await request(`${server.url}/existant`));
48+
expect(body.views).toEqual(2);
49+
});
50+
51+
it('should increment the views of an existant path and store metadata', async () => {
52+
await request.post(`${server.url}/existant`, {
53+
body: JSON.stringify({ meta: { browser: 'IE 6' } }),
54+
});
55+
const [data] = (await db.get('/existant')).views;
56+
expect(data).toMatchObject({ meta: { browser: 'IE 6' } });
57+
});
4758
});
4859
});
4960

0 commit comments

Comments
 (0)