How to export the complete activities log of your Storyblok space

Contents
    Try Storyblok

    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 a node.js project

    Navigate into a folder you’re okay with creating a new Node project.

    mkdir pull-logs
    

    Start a new node project using the command below

    npm init
    

    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://app.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.