How to export the complete activities log of your Storyblok space
Storyblok is the first headless CMS that works for developers & marketers alike.
In this article you will learn how to use the Mangement API of Storyblok to download your Activities log as .csv
utilizing node.js.
Set-up & install dependencies
Next you can exchange the content of the package.json
with the following one:
{
"name": "pull-logs",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"axios": "^0.21.1",
"axios-concurrency": "^1.0.4",
"flat": "^5.0.2",
"json2csv": "^5.0.6"
}
}
This will add the dependencies axios
, axios-concurrency
, flat
, and json2csv
which allows us to easily access the Management API, flatten the JSON we receive from the activities endpoint and convert JSON to csv so we can than write it as a file.
Install the dependencies so we can start creating the actual script itself.
npm install
Creating the Node Script
Create a index.js
with the following content. The comments will guide you through the whole implementation. You will need your personal access token to exchange the STORYBLOK_MANAGEMENT_TOKEN
placeholder and your space id to replace STORYBLOK_SPACE_ID
.
const axios = require('axios')
const { ConcurrencyManager } = require("axios-concurrency")
const flatten = require('flat')
const fs = require('fs')
const { parse } = require('json2csv')
// Initialize axios with the Management API endpoint and your Space ID
// In the same step we will also add the Personal Access Token so we authenticated with the current user.
// CAUTION: DO NOT COMMIT YOUR PERSONAL ACCESS TOKEN - THIS ALLOWS CRUD OPERATIONS
let api = axios.create({
baseURL: `https://mapi.storyblok.com/v1/spaces/STORYBLOK_SPACE_ID`,
headers: { 'authorization': 'STORYBLOK_MANAGEMENT_TOKEN' }
})
// Set-up MAX_CONCURRENT_REQUESTS to apply to the rate limits
const manager = ConcurrencyManager(api, MAX_CONCURRENT_REQUESTS = 2)
// How many activities should be requested at once (no need to increase it)
const per_page = 100
// Perform a HEAD request to get the total number of activities from the Response Headers
api.head(`/activities/?created_at_gte=&created_at_lte=&per_page=${per_page}&page=1`).then((res) => {
// Total number of activities from response header
const total = res.headers.total
// calculate the maximum amount of pages
const maxPage = Math.ceil(total / per_page)
// prepare all requests that needs to be sent in total to request all activities
let contentRequests = []
for (let page = 1; page <= maxPage; page++) {
contentRequests.push(api.get(`/activities/?created_at_gte=&created_at_lte=&per_page=${per_page}&page=${page}`))
}
// Execute all requests that we've prepared before using axios.all and axios.spread
// Thanks to axios-concurrency it will send maximum of 3 requests per second!
axios.all(contentRequests).then(axios.spread((...responses) => {
// To output the JSON as CSV we will have to flatten the JSON structure
// for this we will loop through all responses and use `flat` and their flatten method
let flatData = []
responses.forEach((response) => {
let data = response.data
// flatten JSON response and add to array.
data.activities.forEach(activity => {
flatData.push(flatten(activity))
})
})
// Get all fields of one object so we can define the header of the CSV
const fields = Object.keys(flatData[0])
const opts = { fields }
// parse the whole flatData into a CSV format
const csv = parse(flatData, opts)
// and finally let's write it out into a file
fs.writeFileSync('log-' + Date.now() + '.csv', csv)
})).catch(e => { console.log(e) })
})
After adding the above content you can execute it using node index.js
which will write out a log-timestamp.csv
in your current directory.
Summary
With just a few lines of code you can not only access the whole activities log and easily run custom filters on it using Excel, archive it, export it for an audit or any other case you might want to access your logs of your Storyblok space.