monday.com Tutorial: Create and publish your first monday.com AI App with Stable Diffusion

Wednesday, July 26, 2023 by abdibrokhim
monday.com Tutorial: Create and publish your first monday.com AI App with Stable Diffusion

Introduction

Stable Diffusion, is a new generative model that can generate high-resolution images with a single forward pass. monday.com, is a work operating system (Work OS) where teams create workflow apps in minutes to run their processes, projects, and everyday work. Teams shape workflows and projects, code-free, with an adaptive platform that automates manual work and connects teams in a digital workspace.

Prerequisites

To use Stable Diffusion we need API Key. Go to Dream Studio, Sign up for an account to be taken to your API Key. Click me once you have created an account to be taken to your API Key. Copy the API key and save it somewhere safe. Some knowledge in React.

Let's get started

Create a new project

Let's start by creating new folder for our project. Open Visual Studio Code and create new folder named monday-tutorial:

mkdir monday-tutorial
cd monday-tutorial

First, make sure you have React and axios (a popular HTTP client library) installed in your project:

npx create-react-app my-app
cd my-app
npm install axios

Once your React project is set up, replace the content of the src/App.js file with the following code:

import React, { useState } from 'react';
import axios from 'axios';

function App() {
  const [image, setImage] = useState(null);
  const [inputText, setInputText] = useState('');

  const fetchImage = async () => {
    try {
      const response = await axios.post('http://localhost:3001/generate-image', {
        text: inputText,
      });

      if (response.data.success) {
        setImage('/v1_txt2img.png');
      }
    } catch (error) {
      console.error('Error fetching image:', error);
    }
  };

  return (
    <div style={{ textAlign: 'center' }}>
      <h1>AI Image Generator</h1>
      <input
        type="text"
        value={inputText}
        onChange={(e) => setInputText(e.target.value)}
        placeholder="Enter text"
      />
      <button onClick={fetchImage}>Generate Image</button>
      {image && <img src={image} alt="Generated Image" style={{ marginTop: '20px' }} />}
    </div>
  );
}

export default App;

Now, let's create a new file named server.js in the root of your project and add the following code:

const express = require('express');
const fetch = require('node-fetch');
const fs = require('fs');

const app = express();
const port = 3001;

app.use(express.json());

const engineId = 'stable-diffusion-v1-5';
const apiHost = process.env.API_HOST ?? 'https://api.stability.ai';
const apiKey = process.env.STABILITY_API_KEY;

if (!apiKey) throw new Error('Missing Stability API key.');

app.post('/generate-image', async (req, res) => {
  try {
    const response = await fetch(`${apiHost}/v1/generation/${engineId}/text-to-image`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        Accept: 'application/json',
        Authorization: `Bearer ${apiKey}`,
      },
      body: JSON.stringify({
        text_prompts: [
          {
            text: req.body.text,
          },
        ],
        cfg_scale: 7,
        clip_guidance_preset: 'FAST_BLUE',
        height: 512,
        width: 512,
        samples: 1,
        steps: 30,
      }),
    });

    if (!response.ok) {
      throw new Error(`Non-200 response: ${await response.text()}`);
    }

    const responseJSON = await response.json();
    const image = responseJSON.artifacts[0];

    fs.writeFileSync(`./out/v1_txt2img.png`, Buffer.from(image.base64, 'base64'));

    res.json({ success: true });
  } catch (error) {
    console.error('Error generating image:', error);
    res.status(500).json({ error: 'Image generation failed.' });
  }
});

app.listen(port, () => {
  console.log(`Server listening at http://localhost:${port}`);
});
    

Make sure you have the required dependencies installed. In the project root directory, run the following command:

npm install express node-fetch fs

Let's add some more functionality to our app. I highly recommend firstly try to use monday.com API playground to test queries and mutations. Or sign to your monday.com account and go to API playground for better experience.

Playground
Playground

You can get group_id by the following query:

const [groupId, setGroupId] = useState('');
    
    const getGroupId = () => {
        let query = `query {
                        boards (ids: 1175237853) {
                            groups {
                                title
                                id
                            }
                        }
                    }`;

        fetch("https://api.monday.com/v2", {
            method: 'post',
            headers: {
                'Content-Type': 'application/json',
                'Authorization': 'your_api_key' // replace with your actual API key
            },
            body: JSON.stringify({
                'query': query
            })
        })
        .then(res => res.json())
        .then(res => {
            const groupId = res.data.boards.groups[0].id;
            setGroupId(groupId);  // set group id 
        });
    };

Now, let's create a new task (a new item).

const [itemId, setItemId] = useState('');

    const createNewTask = () => {
        let query = `mutation { 
                        create_item ( 
                            board_id: 1175237853, 
                            group_id: ${groupId},}, 
                            item_name: "Enter your desired task details here", 
                            column_values: "{\"date\":\"2023-07-11\"}") { 
                                id 
                        } 
                    }`;  // GraphQL mutation to create a new task (a new item)

        fetch("https://api.monday.com/v2", {
            method: 'post',
            headers: {
                'Content-Type': 'application/json',
                'Authorization': 'your_api_key' // replace with your actual API key
            },
            body: JSON.stringify({
                'query': query
            })
        })
        .then(res => res.json())
        .then(res => {
            const itemId = res.data.create_item.id;
            setItemId(itemId);  // set item id (we need it to add files to the specific item)
            
            // you may call fetchImage() to automatilcally generate an image when new task is created
        });
    };

Now, let'a add a new column of type file to our board. We will use it to save the generated images.

const createColumnTypeFile = () => {
        let query = `mutation{
                        create_column(
                            board_id: 1175237853, 
                            title:"Images", 
                            description: "This is for images column", 
                            column_type:file) {
                                id
                                title
                                description
                        }
                    }`;  // GraphQL mutation to create new column of type file in our board (in our case to save here all the generated images)

        fetch("https://api.monday.com/v2", {
            method: 'post',
            headers: {
                'Content-Type': 'application/json',
                'Authorization': 'your_api_key' // replace with your actual API key
            },
            body: JSON.stringify({
                'query': query
            })
        })
        .then(res => res.json())
        .then(res => {
            // implement your logic here
            console.log(res);
        });
    };

Get column id to save generated images to the specific column. This is an example query to get column id. You can use it to get column id of any column in your board.

const [columnId, setColumnId] = useState('');

    const createColumnTypeFile = () => {
        let query = `query { 
                        boards(ids: 1175237853) { 
                            items (ids: 1226918259){
                                column_values { 
                                    id
                                } 
                            } 
                        } 
                    }`;  // GraphQL query to get column id, to save generated images to the specific column

        fetch("https://api.monday.com/v2", {
            method: 'post',
            headers: {
                'Content-Type': 'application/json',
                'Authorization': 'your_api_key' // replace with your actual API key
            },
            body: JSON.stringify({
                'query': query
            })
        })
        .then(res => res.json())
        .then(res => {
            const columnId = res.data.boards.items[0].column_values[0].id;
            setColumnId(columnId);  // set column id (we need it to add files to the specific column)
        });
    };

Next, we will add a new file to the column we just created. We will use the itemId, columnId and image we got from the previous steps. This is an example mutation to add a new files to the column.

const addImage = () => {
        let query = `mutation {
                        add_file_to_column (
                            item_id: ${itemId}, 
                            column_id: ${columnId}}, 
                            file: ${image}) {
                                id
                        }
                    }`;  // GraphQL mutation to add a new file to the column (in our case to save here generated images)

        fetch("https://api.monday.com/v2", {
            method: 'post',
            headers: {
                'Content-Type': 'application/json',
                'Authorization': 'your_api_key' // replace with your actual API key
            },
            body: JSON.stringify({
                'query': query
            })
        })
        .then(res => res.json())
        .then(res => {
            // implement your logic here
            console.log(res);
        });
    };

Cool! Now, go to your github account, create New repository and push your project:

git add .
git commit -m "init"
git push <link-to-repository>

Go to your Vercel dashboard and click Add new, from dropdown select Project and Import just created repository. Wait a couple of seconds while it's deploying, once it's done copy/save URL to your app, we will use it for our monday.com AI-powered app.

Create a monday.com account

Go to monday.com and create an account. You can use your Google account to sign up. Once you have created an account, you will be taken to your monday.com dashboard.

Create a new monday.com app

In the upper right corner click on your Profile picture > Developers.

Developers
Developers

You will be redirected to the Developers page. Click on Build app button. Now, you should see a page like this:

New App
New App

Name your app whatever you want and give a short description. For this tutorial, I named: Stable Diffusion AI App and description: monday.com AI-powered app using image generative AI (like Stable Diffusion). Then click on Save button.

Create a new feature

Click on Features tab and then click on Create feature button. Choose Board view > Next then select Start from scratch > Create.

Features
Features

Perfect! If you click on New Build button, you will see a page like this:

New App Build
New App Build

You have two options, Custom URL where you should input link to your app or Upload where you can upload your app zip file. For this tutorial, we will use Custom URL option. So, paste the link which we obtained from Vercel in the previous steps, then click on Create build button. Once it's done, switch to View Setup tab, and click on Go to preview button, after a few seconds you should see your app.

Cool! Now, let's publish our app. Go to App versions tab on the left sidebar. Click on the three dots on the right side > Publish > Promote. Once you done, you should notice that your app's status switched from Draft to Live.

App Versions
App Versions
App Live
App Live

Congratulations! You have successfully created and published your first monday.com AI-powered App with Stable Diffusion.

Install the app

Let's install our app. Select Install from sidebar, then click on Install app button. In addition, you can share your app with others by clicking on Share > Publish share.

App Publish
App Publish

Click Copy to copy the link to your app. Go and share it with your friends.

App Share
App Share

One, more thing before we finish. Let's add monday.com badge to our app. Click Copy button code and paste it inside your app.

Conclusion

Thank you for following along with this tutorial.