How to gather data from Miro

In this blog post you will learn about ways to automatically gather, modify and analyse Miro boards.

Miro is an online collaborative whiteboard platform which we are using heavily in our consulting workshops to collaborate, explore and document. In this blog post I will show you options to automatically gather, modify and analyse Miro boards.

Why we wanted to gather data from miro

In one of our Innovation Incubator rounds, the idea was born to find ways to analyse Big Picture Event storms and their evolution over time in the course of the workshop’s post processing. Wouldn’t it be helpful if you could create a replay cockpit where you can replay the whole workshop and see how this event storm evolved over time.

Additionally we needed to export board data into our statistical analyzers written in python. Basic data such as stickers and their history needed to generate word clouds, lingual analysis and activity analysis of workshop participants.

So the idea was born to check out the Miro Options to gather data and create ideas how this data can be analysed.

Options to access Miro Data

MIRO provides two ways of accessing data. You can either use the Miro REST API or the Miro Web Plugin SDK. The REST API provides easy access to basic board data but it is not yet comprehensive whereas the Miro SDK provides more capabilities.

Retrieving Data

The REST API is the simplest way to retrieve data from Miro. The following preparatory steps need to be executed to access the API (detailed description can be found here)

1. Create a developer team

2. Create an APP within your organization. Go to your User->Profile Settings->Your Apps

3. Create a developer team

4. Create an APP within your organization: Go to your User->Profile Settings —> Your Apps

Once you have gathered you personal access (bearer) token, the first request can be sent to Miro on behalf of your Miro user. You can access any resource your Miro user has access to, limited by the app permission scope (intersection of both permissions). It is also possible to send requests on behalf other users, however this requires that you set up an OAUTH 2.0 flow. In this Python sample request we retrieve all widgets from a board.

 url = "https://api.miro.com/v1/boards/" + board_id + "/widgets"

    headers = {
        "Accept": "application/json",
        "Content-Type": "application/json",
        "Authorization": bearer
    }

    response = requests.request("GET", url, headers=headers)

This sample response contains JSON describing all the widgets on a board. As you can see there is a lot of styling and positioning information delivered. Everything within a frame is embedded as sub collection within this frame.

Limits and Observations

  • You can retrieve max 1000 widgets. Pagination is not supported. If you have more elements on your board, you could filter by widget type and send a separate request for each type. If you use a huge board to collect the outcome of several workshops this limit could be a hurdle.

  • You can retrieve the created by and modified by metadata however the modified by describes the last modification. There is no way to retrieve the full history of a widget.

  • Updating the App Scopes had no effect. I needed to delete and then recreate the App defining new scopes.

Modify Data

The REST API provides methods to create and modify boards. For our replay cockpit we need first to retrieve all elements and then replay them in the correct order. My assumption that everything I retrieve can be posted again to another board was refuted. The following limitations have been observed

  • Deleting boards is not possible. This lacks the ability during the development phase to create boards and automatically delete them after each iteration. My workaround was to delete all widgets on the cleanup step, with the side effect that the board crashed after several iterations (probably too many elements in history)

  • Styles: Not each style property can be set in a POST request even if was delivered by the GET request.

  • Once you retrieve colors they are in a 8 digits format (RGB including opacity). Write requests accept only 6 digit formats (RGB)

  • 12 colors are support for stickers however on the board you could assign custom colors to stickers. I wrote therefore a color distance calculator to map a custom color to the nearest one of these 12

Actually I do not understand some of these limitations and it took several runs and hacks to copy the content from one board to another board.

Replay Architecture

I have set up a vue.js application with a python backend. The backend is due to convenience reasons and to prevent CORS issues. The user then can select a board. All board content is loaded chronological into a slider and the user can navigate through the single steps. Once the autoplay feature is enabled, you can go to the replay Miro board and enjoy the replay show. For each replay step either a create widget REST request is sent or a delete widget request (if you navigate backwards)

SDK

As we could solve our replay cockpit using the API we searched for a small use case to evaluate the Miro SDK. Wouldn’t it be nice to implement a word counter which shows you within a widget the most used words and once you click on the word all occurrences on the board will be highlighted.

Your Code

Miro plugins are loaded from a public accessible source (your code) and embedded into the miro site via an IFrame. Therefore you need to setup an HTML site and publish it to some publicly available location, in my case github pages. In the simplest form you provide a html page which loads some javascript code.

let icon =
    ''
miro.onReady(() => {
    miro.initialize({
        extensionPoints: {
            bottomBar: {
                title: 'Word count',
                svgIcon: icon,
                positionPriority: 1,
                onClick: () => {
                    miro.board.ui.openLeftSidebar('/my-first-miro-plugin/wordCount.html')
                },
            },
        },
    })
})

This simple javascript file defines an action tray icon and assigns the content of wordCount.html to the sidebar on the left.

 

Once you click on the icon the content of wordCount.html will be loaded to the left sidebar.


var tokens = new Object();

function addToWordCounts(element) {
    var text = normalizeTitle(element['text'])
    if (text == '')
        return;

    let parts = text.split(' ');
    for (const part of parts) {
        if (part in tokens) {
            tokens[part].elements.push(element)
            tokens[part].count++;
        } else {
            let newElement = new Object();
            newElement.elements = [element];
            newElement.count = 1;
            newElement.text = part;
            tokens[part] = newElement;
        }
    }
}

async function calculateWordCounts() {
    let widgets = await miro.board.widgets.stickers.get()
    tokens = new Object();
    for (const widget of widgets) {
        addToWordCounts(widget)
    }
}

miro.onReady(() => {
    // subscribe on user selected widgets
    //miro.addListener(miro.enums.event.SELECTION_UPDATED, getWidget)
    calculateWordCounts()
})

Miro provides the miro instance where you can hook to miro events and call miro functions to access and modify board content.

Finally you need to setup the application in the miro settings. Same as for REST API access you need to create an app, define the scope and permissions and additionally specify the public available source code URL.

SDK - Limits and first impressions

There was not the coding experience I am used to, especially if you are not familiar with the SDK functions and you need to try out things. Anytime you update your code you need to reload the miro board, click on your icon and then in worst case click through some workflows to reach the point which you want to test. As there is no local Miro dev environment provided the whole dev cycle gets bumpy. I worked a lot with the dev tools to find out possible functions on the current miro state and also to call them to test the outcome before I deploy the new code fragment to my public location.

Unfortunately the full history of a sticker cannot be gathered. As a workaround we had the idea to record changes and write them to local storage or an external destination. However, Miro’s change events are triggered once you create a sticker but not once a text is changed.

Summary

Miro REST API is a straightforward way to retrieve and modify basic Miro data. Unfortunately it is still under development and important data such as history cannot be gathered yet. If you need more control over data or even need a widget on your board, Miro SDK should be you choice. Coding within the SDK feels bumpy and there is still no way to retrieve the full history of stickers. I’m looking forward getting these features in future releases of Miro.

Blog 10/6/21

Designing and Running a Workshop series: An outline

Learn how to design and execute impactful workshops. Discover tips, strategies, and a step-by-step outline for a successful workshop series.

Headerbild Data Insights
Service

Data Insights

With Data Insights, we help you step by step with the appropriate architecture to use new technologies and develop a data-driven corporate culture

Service 4/13/23

Training courses on how to deploy target software

Do you want to maintain the software for your idea and innovation management yourself? We will be happy to provide you with the necessary know-how in our training courses.

Blog 11/24/23

Part 3: How to Analyze a Database File with GPT-3.5

In this blog, we'll explore the proper usage of data analysis with ChatGPT and how you can analyze and visualize data from a SQLite database to help you make the most of your data.

Blog 7/16/21

Building A Shell Application for Micro Frontends | Part 4

We already have a design system, several micro frontends consuming this design system, and now we need a shell application that imports micro frontends and displays them.

Blog

Responsible AI: A Guide to Ethical AI Development

Responsible AI is a key requirement in the development and use of AI technologies. You can find everything you need to know here!

Blog 7/14/21

Building and Publishing Design Systems | Part 2

Learn how to build and publish design systems effectively. Discover best practices for creating reusable components and enhancing UI consistency.

Blog 4/17/23

Running Hybrid Workshops

When modernizing or building systems, one major challenge is finding out what to build. In Pre-Covid times on-site workshops were a main source to get an idea about ‘the right thing’. But during Covid everybody got used to working remotely, so now the question can be raised: Is it still worth having on-site, physical workshops?

Headerbild zur automatischen Handschrifterkennung bei Versicherern
Branche

Automatic handwriting recognition for insurers

The recognition of handwriting works "out of the box". In addition, we support our customers in further document classification and extraction of specialized data so that it can be processed automatically.

Header zu Fullstack Development
Service

Fullstack Development

The trend in Software Development is towards Full-Stack Development. Full-stack developers are programmers who work in both frontend and backend development and thus have competencies in the areas of databases, servers, systems and clients.

Blog 3/17/22

Using NLP libraries for post-processing

Learn how to analyse sticky notes in miro from event stormings and how this analysis can be carried out with the help of the spaCy library.

Blog 10/7/21

Designing and Running a Workshop series: The board

In this part, we discuss the basic design of the Miro board, which will aid in conducting the workshops.

Server farm
Leistung 2/14/22

From Unix to Linux with Adabas/Natural

Mit Adabas/Natural von Unix nach Linux

Teaserbild zu Data Integration Service und Consulting
Service

Data Integration, ETL and Data Virtualization

While the term "ETL" (Extract - Transform - Load / or ELT) usually described the classic batch-driven process, today the term "Data Integration" extends to all methods of integration: whether batch, real-time, inside or outside a database, or between any systems.

Headerbild zu Cloud bei Versicherungen
Branche

Paths to the cloud for insurers

Cloud ist die Blaupause für eine moderne Nutzung von IT-Ressourcen. Doch traditionell scheuen viele Versicherer den Weg in die Cloud. Befürchtet werden Kontrollverlust oder fehlende Sicherheit für vertrauliche Daten. Doch all dies sind Themen, die technisch und organisatorisch gelöst sind. Es überwiegen die Vorzüge einer flexiblen und kostengünstigen Architektur.

Blog 2/21/22

The Power of Event Sourcing

This is how we used Event Sourcing to maintain flexibility, handle changes, and ensure efficient error resolution in application development.

Blog 11/15/22

5 lessons from running a (remote) design systems book club

Last year I gifted a design systems book I had been reading to a friend and she suggested starting a mini book club so that she’d have some accountability to finish reading the book. I took her up on the offer and so in late spring, our design systems book club was born. But how can you make the meetings fun and engaging even though you're physically separated? Here are a couple of things I learned from running my very first remote book club with my friend!

Blog 5/25/21

From the idea to the product: The genesis of Skwill

We strongly believe in the benefits of continuous learning at work; this has led us to developing products that we also enjoy using ourselves. Meet Skwill.

Wissen 5/2/24

Unlock the Potential of Data Culture in Your Organization

Are you ready to revolutionize your organization's potential by unleashing the power of data culture? Imagine a workplace where every decision is backed by insights, every strategy informed by data, and every employee equipped to navigate the digital landscape with confidence. This is the transformative impact of cultivating a robust data culture within your enterprise.

Unternehmen

Directions to TIMETOACT GROUP in Cologne

Whether you travel by car, train or plane, we will show you the best way to get to the Mediaparkt in Cologne.

Bleiben Sie mit dem TIMETOACT GROUP Newsletter auf dem Laufenden!