Search code examples
javascriptgoogle-apps-scriptgoogle-drive-apifetch-apigoogle-apps-script-api

How to send localhost Blob(Clipboard Image Data) send to other server (Google Apps Script)


I want to send Blob(Clipboard Image Data, Client Javascript) to other server (Google Apps Script) for storing in Google Drive.

client and server is not same domain.

I try below code but It's not working.

google apps script side, e.postData parameter is always return undefined.

What should I do? I don't even know whether it's a javascript fetch problem or a server problem.

Must JavaScript blob data be converted as raw texts(String) before sending?

My English is bad,.

please show me answer code.

in javascript, html // localhost environment because this html, javascript for chrome extension.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <script>
      window.addEventListener("DOMContentLoaded", function () {
        document.querySelector("#test").addEventListener("click", async () => {
          try {
            const permission = await navigator.permissions.query({
              name: "clipboard-read",
            });

            // permission allowed
            if (permission.state === "granted") {
              const dataTransfer = await navigator.clipboard.read();

              // get item from clipboard
              for (const item of dataTransfer) {
                const isImage = item.types.some((type) => type === "image/png");

                if (!isImage) {
                  continue;
                }

                // get Blob from clipboardItem
                const blob = await item.getType("image/png");

                var formData = new FormData();
                formData.append("blobData", blob);

                fetch("my_google_apps_script_url", {
                  method: "POST",
                  body: formData,
                })
                  .then((response) => response.json())
                  .then((data) => {
                    console.log("Response from Google Apps Script:", data);
                  })
                  .catch((error) => {
                    console.error("Error calling Google Apps Script:", error);
                  });
                break;
              }
            } else {
              console.log("not allowed permission.");
            }
          } catch (error) {
            console.error("clipboard read error:", error);
          }
        });
      });
    </script>
  </head>
  <body>
    <button id="test">test button</button>
  </body>
</html>

in google Apps Script

 function doPost(e) {
   try {
       e.postData is null

//     I will get blob from e.postData and store in my google drive.

     return ContentService.createTextOutput(JSON.stringify({ success: true }))
       .setMimeType(ContentService.MimeType.JSON);
   } catch (error) {
     console.error('Error processing Blob data:', error);


     return ContentService.createTextOutput(JSON.stringify({ success: false, error: error.message }))
       .setMimeType(ContentService.MimeType.JSON);
   }
 }

Solution

  • I Success below Way

    front Side

    const blob = await item.getType("image/png");
    
              let reader = new FileReader();
    
              reader.onload = function (event) {
                let base64EndcodedArr = event.target.result.split(",");
                let metaDataStr = base64EndcodedArr[0];
                let encodedData = base64EndcodedArr[1];
    
                console.log(event.target.result);
    
                fetch(
                  "my_google_apps_script_url",
                  {
                    method: "POST",
                    body: JSON.stringify({
                      metaData: metaDataStr,
                      data: encodedData,
                    }),
                  }
                )
                  .then((response) => response.json())
                  .then((data) => {
                    console.log("Response from Google Apps Script:", data);
                  })
                  .catch((error) => {
                    console.error("Error calling Google Apps Script:", error);
                  });
              };
    
              reader.readAsDataURL(blob);
    

    Server Side

    function doPost(e) {
      try {
        let json = JSON.parse(e.postData.contents);
        var data = Utilities.base64Decode(json.data);
        var fileName = Utilities.getUuid() + ".png";
        var blob = Utilities.newBlob(data, 'image/png', fileName);
        var linkUrl = saveBlobImageToDrive(blob);
        // 성공 응답 반환
        return ContentService.createTextOutput(JSON.stringify({ success: true, link : linkUrl }))
          .setMimeType(ContentService.MimeType.JSON);
      } catch (error) {
        console.error('Error processing Blob data:', error);
    
        // 오류 응답 반환
        return ContentService.createTextOutput(JSON.stringify({ success: false, error: error.message }))
          .setMimeType(ContentService.MimeType.JSON);
      }
    }
    
    // 클라이언트에서 전송된 Blob 이미지 데이터를 Google 드라이브에 저장하고 파일로 로깅하는 함수
    function saveBlobImageToDrive(blobImageData) {
        // Blob 데이터를 Google 드라이브에 저장할 폴더 ID
        var folderId = 'my_folderId'; // 실제 폴더 ID로 변경해야 합니다.
    
        // Google 드라이브에 저장
        var file = DriveApp.getFolderById(folderId).createFile(blobImageData);
    
        file.setSharing(DriveApp.Access.ANYONE_WITH_LINK, DriveApp.Permission.VIEW);
        var shareableLink = file.getUrl() + '/view?usp=sharing';
    
        return shareableLink;
    }