Grip.tools: building a tool that automates visual content production
Grip was launched in 2017 in the Netherlands, and its main customers are consumer product companies. Grip is a tool that is used to automate visual content production at scale, with the aim to generate beautiful images, always on brand. With its unique approach, it revolutionizes the world of physical goods marketing by democratizing the production of visual content.
So, how does it work? Let's say one of Grip’s clients wants to make a promotional poster that will show a bottled beverage on a specific background or with someone holding it in their hand. But to promote the product under different circumstances, you need to take into account a lot of peculiarities. For example, the label on a bottle in America should be in English, Portuguese in Brazil, and Arabic in Middle-East Countries.
It is very complex and sometimes even impossible to create photographs of the physical product(s) and its labels in a studio every single time. To make different pictures and models of different products, Grip develops a 3D model, called the Digital Twin, that is inserted into so-called templates, representing a virtual photo studio or a real-world lifestyle scene. Labels exist as a specific element of this model, which the Grip customer can change at their discretion. They can change the text of the label, change the color, etc., and by doing so, create images for completely different products, eg. in this case, for different countries and markets.
The Grip main platform was developed in C#, and the order queue and the render farm (which renders images) were also developed by their main team. We helped Grip expand the functionality of their tool & services by providing extension development services.
Developing extensions in Elixir
There is the main Grip platform, and then there are extensions to it, which have the same users, depending on the configuration and use-case. An extension in Grip is a kind of service that is not directly part of the Grip system but connects via an iframe and adds additional functionality through interaction with a special API.
We were involved in building several extensions through a small team, consisting of three backend Elixir developers, four frontend developers, one QA, and one project manager (who also performs the function of an analyst) working on these projects. So far, we have developed the following three extensions:
- Opera - It helps to export rendered images from Grip to the Opera DAM system of the Grip client. The client, having selected any rendered image or video, can start the process of exporting a file to Opera DAM and track the status of this process. This extension is in production and is used by Grip clients.
- Lineups - This extension helps the user create so-called “line-up images”. The background is used as a basis (for example, a table in a bar), and placeholders of products are placed on this background (points where you can insert products). This is all done by the admin, then the client, having selected a template (background + placeholders), has the ability to place their products in these placeholder positions (for example, beverage bottles), adjust the reflection and shadows, and move the products to the right place. Once the client has finished making changes to the web interface, they can generate an image render order. The order enters the order queue, then is rendered and appears in the client's interface as a final image. This extension is also in production.
- SABatch (Stand Alone Batch) - Its purpose is to generate a batch of render requests. With this extension, the user can manage and order Products, which get automatically defined and set up inside Grip, and final images are delivered back. In detail, a user can add several products to order, attach the necessary 3D models and labels to these products, and then send the order to the order queue with one button. This extension is still in development. The functionality of order formation on the SABatch side has been implemented, without sending it to the render farm queue. This extension has an admin panel for managing clients, a list of clients' products, and presets (settings for rendering).
On Grip, we use:
- Backend - project base is on C#, NodeJS. Supporting services are on Elixir, Phoenix framework (using Elixir to build HTTP APIs and web applications)
- Database - PostgreSQL
- Frontend - React
- DevOps - we configure servers using Ansible scripts. All applications are running on Docker. Circle CI and Azure Pipelines are used as CI/CD
- Opera extension - Elixir backend, storage of metadata, and export history in PostgreSQL. Since the user interface was not meant to be complicated, it was written in LiveView technology, allowing Elixir backend developers to write simple frontend applications easily.
- Lineups extension - backend on Elixir: admin panel on LiveView; REST-API on Phoenix for the frontend. Frontend on React, PostgreSQL is used for storing templates (background, placeholders, etc.). AWS S3 is used to store images.
- SABatch extension - backend on Elixir, frontend on React, PostgreSQL is used for data storage. AWS S3 for storing heavy data that the client uploads (pictures, archives, label excerpts).
We used AWS S3 to store data that is better not stored in a database. We also store database backups in S3. In addition, we worked with the Salsify service — this is the source of truth for the products of some Grip customers. We upload products from Salsify to SABatch.
We did a big refactoring of the existing Ansible script repository. We also liked working with Appsignal, an Elixir service monitoring tool. It is easy to set up and helps, not only developers but also QAs to identify problems and solve them quickly.
What is more, we are now in the process of working on the new version of the Grip platform. Our team works closely with the Grip team to maintain the project infrastructure (configuring applications, databases, networks), as well as diagnosing malfunctions that occur in services and keeping logs about these malfunctions so that everyone in the future can read and understand how they were fixed.
We work together with the Grip team and hold joint meetings, so we have transparency in our work and trusting relationships. Our manager makes every effort to make it clear to everyone what we are doing and exchange information with the teams from Grip’s side. On the project, we set up a workflow of tasks and started writing technical decisions, specifications, and working diagrams.
We help the client with various services and implementations of their vision for a visual content creation tool. Grip is not just a project in which we carry out assigned and pre-defined tasks; we are also contributing to research and development within these projects.
We really like that the client is flexible and trials a lot of new approaches and technologies. For example, we are revising data storage (from relational to graphs or to NoSql), and changing the attitude towards core-extension dependencies (microservices) and business logic in general. We are very pleased that the client trusts us to recognize and solve, not only technical issues but also some closely related issues of a product nature.
The client is satisfied with the results so far, but the most interesting tasks lie ahead. We are now working on the new version of Grip, and as part of the new platform, we are developing several services such as a web based editor, an interface for an external user to order/view images, a service for generating images based on created templates, etc. Stay tuned!
And, of course, reach out to us, via the form below, if you need an enterprise marketing tools development partner to help you update your project to the latest versions of the technology stack or develop a new one from scratch!
“They provide experienced and knowledgable talents that possess a strong work ethic. Their project management has been responsive, and the team has been on top of all the details. They became an extension of our team and never felt like a vendor.”
- Holger Schmidt, Head Of Engineering at INDG | Grip