Allow users to upload images and other files
# 👀feature-requests
h
I know this is a veryyyy popular request that gets plenty of upvotes but I think it is so needed so here I am! Botpress team, if it is already a work in progress please let me know and I’ll delete this as I know repetition of a feature being worked on currently will just clog this channel 🙂 Cheers!
w
I think Botpress team is aware and thinking about this feature👀
But yes, it would increase the bots value by 10x for sure!
h
🤞
q
@hallowed-lizard-35251 🦸‍♂️🛠️ 🫡 Maybe you have already seen this, I practiced with this and uploading .txt files to Botpress KB table https://discord.com/channels/1108396290624213082/1189632494241321180 I used this to accept only .txt files just to see that it works, and I haven't tried with other formats in this project
Copy code
html
<input type="file" id="textInput" accept=".txt">
but other file formats could be for example
Copy code
html
<input type="file" id="textInput" accept=".txt, .doc, .docx, .odt, application/msword, application/vnd.openxmlformats-officedocument.wordprocessingml.document, application/vnd.oasis.opendocument.text">
I've uploaded images and audio to Botpress before, but for that I used an external server. Our best option is to wait for the official Botpress feature for all these. Meanwhile, we can practice with home-made alternatives so that we're prepared when the feature arrives 🚀
...external server in my previous solution, since audio and image files require a URL link (at least at the moment)...
h
Thanks @quick-musician-29561 ! Yeah my use case would be accepting image files so my clients can then provide quotes for services based on images the user uploads 🙂 Which I understand isn't straight forward but hopefully it can be implemented!
q
I'm going to try that with images and if it's successful, we can connect it to your chatbots until Botpress feature is ready! 🫡 You can use it for testing and building as much as needed 🤝
h
You are a champion 🙌 I did see one solution in another thread but it was extremely codey and I'm a no-code guy so it was way above my ability level 😂
q
If your users have image files hosted somewhere, then it's already working. It users want to upload the images from their computer, then it needs some workarounds.
Something to start with. Now the image user uploaded is in Botpress chatbot, and also stored in variable called workflow.imageUrl, which can be stored in KB table so that clients can check all the images their users have uploaded Code Playground https://jsfiddle.net/devmik/qy5sfruo/14/ Chatbot file and website are far from ready, but instead a good starting place.
h
Sorry Devmik, how does the upload image URL get shown in the bot? And how does the user get the URL, rather than just uploading a file? It looks like great work but I'm not on a level to understand it haha 😂
q
I created a variable called workflow.imageURL, then I used that variable in Image card to show it to the chatbot user
this is the version where users have image, audio or video files as URLs.
Then users can just paste the URL to the website where chatbot is located, and click UPLOAD For example the image that I used in this example: [URL](https://plus.unsplash.com/premium_photo-1682724602925-f0264b85953f?q=80&w=2071&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D)
If users need to upload the images (or audio, video) from their computer, then it must first be converted to a URL (because Botpress requires URLs to display the images, audio and video, at least for now).
@hallowed-lizard-35251 let me know if you test it 🛠️ If you download the bot file here
and then publish the bot
and then in your chatbot Integragions page, copy these
and paste those inside that jsfiddle link, HTML section
then it works with your test chatbot (now it has my chatbot config scripts)
or we can build your version together and test everything 🛠️ 💯
(and now I realized that we are still on the feature-requests section 💡)
Here I managed to download images (under 20kB or so) from local computer to Botpress chatbot, without external server, using just Botpress and webpage.
code playground (removed the JSFiddle link, I uploaded HTML in this thread instead ⤵️
this is just a test version, it already works, but there's still so much to do (bigger image files, store image details to KB table etc.). And also should we move this from feature-requests to Help-section or share-your-bots section?
Copy code
html
<html>

  <body>
    <h1>
      Upload Files
    </h1>
    <p>Upload image file</p>
    <script src="https://cdn.botpress.cloud/webchat/v1/inject.js"></script>
    <script>
    // ADD YOUR CHATBOT CONFIG SCRIPT HERE
    </script>

    <input type="file" id="imageInput" accept="image/*">
    <br><br>
    <label for="imageInput">Username:</label>
    <br>
    <input type="text" id="name" name="nameInput" required>
    <br><br>

    <button id="submit">Submit</button>

    <script>
      const imageInput = document.getElementById('imageInput');
      const submitButton = document.getElementById('submit');
      let dataURL = null;
      let imageName = null;

      imageInput.addEventListener('change', function(event) {
        var file = event.target.files[0];
        var reader = new FileReader();

        reader.onloadend = function() {
          dataURL = reader.result;
          imageName = file.name;
        };

        reader.readAsDataURL(file);
      });

      submitButton.addEventListener('click', function() {
        const nameValue = document.getElementById('name').value;

        if (dataURL) {
          console.log('Image Name:', imageName);
          window.botpressWebChat.sendPayload({
            type: 'text',
            text: "Here is my image",
            payload: {
              name: nameValue,
              image: dataURL,
              imageName: imageName
            }
          })
        }
      });

    </script>
  </body>

</html>
If you're using an external server, then there's no problem with bigger image file sizes. But I wanted to try this with Botpress+Webpage only
Let's continue towards this goal 🚀 I uploaded an image file with size 366.5kB, which is 18x bigger than yesterday.
Here we're using client-side compression libraries to reduce the file size, so users can send large files to Botpress chatbot without issues. Also we need to adjust the canvas size, I don't know which numbers are correct for chatbot, but we'll find that out through trial and error.
@hallowed-lizard-35251 and others who might want to test this, download the chatbot file and that HTML file. Publish the chatbot, then add your chatbot config script to the HTML file, save it and open it in a web browser (normally it opens in a browser just by double-clinking the file). Inside the HTML file:
First we add the 'pica' library to compress the image files on client-side.
Copy code
html
<html>
<head>
  <title>Upload Images</title>
  <script src="https://cdn.jsdelivr.net/npm/pica/dist/pica.min.js"></script>
  <style>
    body {
      background-color: #a7bcb9;
    }
  </style>
</head>
Add your chatbot confiq script here (after you have published the chatbot)
Copy code
html
<body>
  <h1>
    Upload Files
  </h1>
  <p>Upload image file</p>


  <script src="https://cdn.botpress.cloud/webchat/v1/inject.js"></script>
  <script>
  // ADD YOUR CHATBOT CONFIG SCRIPT HERE

  </script>
These let your users to select the image from their local computer, and then they can click a Submit button.
Copy code
html
  <input type="file" id="imageInput" accept="image/*">
  <br><br>
  <label for="imageInput">Username:</label>
  <br>
  <input type="text" id="name" name="nameInput" required>
  <br><br>

  <button id="submit">Submit</button>
Here we create variables for the selected file (imageInput), submitButton, dataURL, and imageName
Copy code
html
<script>
    const imageInput = document.getElementById('imageInput');
    const submitButton = document.getElementById('submit');
    let dataURL = null;
    let imageName = null;
this event listener reads the selected file, sets the canvas (image) smaller and reduces the file size
Copy code
html
    imageInput.addEventListener('change', function (event) {
      var file = event.target.files[0];
      var reader = new FileReader();
      var img = new Image();

      reader.onloadend = function () {
        img.src = reader.result;
        img.onload = function () {
          var canvas = document.createElement('canvas');
          var ctx = canvas.getContext('2d');

          canvas.width = img.width / 2;
          canvas.height = img.height / 2;

          pica().resize(img, canvas, {
            quality: 3,
            alpha: true,
            unsharpAmount: 80,
            unsharpRadius: 0.6,
            unsharpThreshold: 2
          }).then(function (result) {
            return pica().toBlob(result, 'image/jpeg', 0.90);
          }).then(function (blob) {
            var resizedReader = new FileReader();
            resizedReader.onloadend = function () {
              dataURL = resizedReader.result;
              imageName = file.name;
              console.log(dataURL)
            };
            resizedReader.readAsDataURL(blob);
          });
        };
      };

      reader.readAsDataURL(file);
    });
When we have created the Data URL (which Botpress chatbot can read because it's technically just URL) from image file (which Botpress chatbot can't read at the moment), we send it to the chatbot as a payload, sending also users name (nameValue) and imageName along with the actual image.
Copy code
html
    submitButton.addEventListener('click', function () {
      const nameValue = document.getElementById('name').value;

      if (dataURL) {
        console.log('Image Name:', imageName);
        window.botpressWebChat.sendPayload({
          type: 'text',
          text: "Here is my image",
          payload: {
            name: nameValue,
            image: dataURL,
            imageName: imageName
          }
        })
      }
    });

  </script>
</body>

</html>
So website sends the image: dataURL as a payload to the chatbot, then chatbot stores the image (dataURL) to a variable called workflow.image. In your chatbot Execute code card
Copy code
js
let { name, image, imageName, blob } = event.payload.payload
workflow.name = name
workflow.image = image
workflow.imageName = imageName
workflow.blob = blob
We can then display the image (uploaded by the user from their local computer) using Image card, because now it's in the correct URL format.
Latest chatbot file
There are still some unnecessary variables, etc., which is quite normal during the development and testing phase. I'm building this because I enjoy challenging myself with these kinds of tasks and seeing if I can make this work. I'm trying and testing everything, keeping what works and after a while removing what doesn't work. And, as usual, nothing else works in my chatbots but just the feature I try to implement. For example, there's an "Ask questions" button, but that's not even connected to anything 🤡
h
Oh my! Devmik you are incredible 😂 I feel terrible having taken so long to reply after you spent so much time and effort doing this so my apologies, but also thank you so much! I will try and implement this once I solve this very annoying problem I am having haha https://discord.com/channels/1108396290624213082/1197876786856468520
q
I really like this kind of practice 🤝 And that was the easier part, to let users to upload images from URL (already works in Botpress) and also from users local computer as seen here.
The challenging part is figuring out how to enable chatbot owners to effectively USE the images their users have uploaded. The uploaded images can already be used in other parts of the chatbot. However, if the chatbot owners want to browse the images later, they need to be stored. This would be fairly easy with Google Sheets, but we would not go out from Botpress this time. If the image is in Data URL format, it tends to be too large to fit within a Botpress KB table row (which has a maximum limit of 4kB), and it's also too large to be stored in a variable. So we need to find a way to split the data into smaller chunks when it exceeds the size limit and store that information in arrays of chunks. In the KB table, we can then reference these chunk arrays for each image. When the image is used in other parts of the chatbot, we can reconstruct the Data URL (i.e., the image) from these smaller chunks to display the correct image. Sounds more complex process than it actually is, and perhaps it can be done! 🤷‍♂️ If we can make this work, then it's not complex at all for chatbot builders. You just need to add the required code to a website and also add these few Nodes into your chatbot.
I don't know if Admins can move this 'Upload files' topic from feature-requests to help section ❔ Now it seems we're attracting others from help section to also post in feature-requests 😂 and that's my mistake🤦‍♂️
Otherwise I can open a new thread in the Help section and continue this discussion there.
h
Maybe this is the best idea @quick-musician-29561, it might be easier for others to follow it that way as it will be distilled down the nuggets of gold you have found along the way 🙂 a tutorial is another option but maybe not if it will just be temporary until the botpress team can release this feature 🤞
q
2 Views