MindMeister is a market innovator for providing collaborative online mind mapping solutions. Launched in May 2007, our site has since attracted hundreds of thousands of businesses, academic institutions and creative consumers who have mapped over 100 million ideas online. We were one of a few web applications invited to take part in the Google Drive launch earlier this year.
The goal was to provide users with an intuitive integration between Google Drive and Mindmeister that would cover all the cases provided by the Google Drive guidelines at that time:
- Create mind maps directly from Google Drive
- Open mind map files from Google Drive using MindMeister
- Create a mind map file on Google Drive from MindMeister
Aside from these main integration points, we wanted to make use of the SDK and provide many useful Google Drive features, so we added a few more requirements to the list:
- Export all the user’s maps as a backup .zip file on Google Drive
- Import a file from Google Drive using the Google File Picker
- Attach a file from Google Drive directly to a node in a mind map
- Provide users with the possibility to share mind maps with their Google contacts
- Provide users with an application setting that would allow them to sync all their mind maps with Google Drive
- Allow Google users opening the same file from Google Drive to collaborate in real time on the mind map directly in MindMeister
- Enable users to login with their Google account without providing any extra information
Authentication and Authorization
Google Drive applications are required to use OAuth 2.0 as an authorization mechanism, and are recommended to use OpenID Connect for login. The authorization scope for Drive files is added by default for all registered drive apps. Additionally, the application can require extra scopes that would fit its needs. For our requirements, we needed the following scopes:
However, we didn’t want the user to turn away from our application by being asked for too many scopes from the outset. Instead, we defined sets of actions that required a subset of these scopes:
[‘drive’, ‘profile’, ‘email’]– any Google Drive action
[‘profile’, ‘email’]– login with a Google account
[‘contacts’, ‘profile’, ‘email’]– access the user’s Google contacts
Whenever the user wanted to execute an action that would require more scopes than they initially provided, we redirected them to a Google authorization dialog that requested the extra scope. Upon authorization, we stored the individual refresh tokens for each combination of scopes in a separate model (
[‘profile’, ‘email’]) it would fetch the refresh token from the database which corresponded to a superset of the required scopes (e.g.
[‘drive’, ‘profile’, ‘email’]would fit for the required
[‘profile’, ‘email’]). The access token would then be obtained from Google and stored in the session for future requests.
The main challenge we encountered during design and implementation was dealing with the special cases of multiple users (Google users or internal users) editing on the same map which is a Google Drive file, as well as dealing with the special cases of the map being edited in multiple editors. We also had to find a solution for mapping the Google Drive user’s permissions (
writer) to the MindMeister’s existing permission mechanism.
The MindMeister application is registered for opening four types of files: our own
.mind format, MindManager’s
.mmap format, Freemind’s
.mm format, as well as
.xmind. However, since these formats are not 100% compatible with each other, there is always a chance of losing more advanced features when opening a file in a format other than .mind. We wanted to provide the user with the possibility to chose whether the opened file would be saved in its original format, thus risking some features loss, or saving the file in MindMeister format. This option should be per user, per file and with the possibility to be remembered for future files.
After analyzing the requirements and the use cases, we designed the following architecture:
Out of Sync Maps and Files
Using the revision fields in both Map and DriveData, we always know if the map has been edited on MindMeister’s side without it being synced with the corresponding file on Google Drive. On the other hand, the token field from DriveData represents the file’s MD5 checksum at the moment of the last update and is supplied via the Google Drive SDK. So if the file is edited externally using an application other than MindMeister, we have a mechanism in place for detecting this issue and presenting the user with a few courses of action.
Handling 3rd Party Formats
Upon opening a file that has a different format than
.mind, the user is prompted with an option dialog where they can chose if they want the file to be saved back in the same format or in MindMeister’s own format. These options are then remembered in the current session and the per map settings are stored in the
extension (the original format) and
save_extension (the format to save back in) fields present in the
Handling User’s Permissions
A map on MindMeister can always be shared with other MindMeister users and the collaborators can have reading or writing access to the map. However, only some of these users will have a corresponding Google account with access to the MindMeister Google Drive application and furthermore, only some of them will have access to the same file on Google Drive with writing permission. This is why it is important for us to know which users can write back to the file and the solution for these access levels was achieved with the help of the permission field in the
Now more than two weeks on from the Google Drive launch and we can confidently say that our integration was successful, with more than 14,000 new users using Google login and with over 7,000 users that have enabled the Google Drive integration. All in all, the Google Drive SDK was very easy to use and well documented. The developer support, especially, was always there to help and our contacts were open to our suggestions.
Laura is the lead programmer at MindMeister, an online mind mapping tool built in HTML5 that features real-time collaboration.