title: How can I upload a folder to Google Drive with keeping its directory structure?
body: <p>I am trying to upload a folder to google drive with keeping its directory structure by using javascript drive api. I achieved to upload all files but not folders in a folder. Also I achieved to upload an empty folder to google drive by drive api. However I could not find a resource that explain uploading a folder with keeping its all directory structure. For example I have a folder like that:
  (I added a link to show my example folder. I could not add direct image because of my low reputation.)
  <a href="http://postimg.org/image/h52bvb71v/" rel="nofollow">http://postimg.org/image/h52bvb71v/</a></p>
  
  <p>But When I choose the folder, I can just upload the .txt files. At least google drive api Javascript Quickstart provides me that code. I dont want to ruin structure of folder and I want to upload it to drive with original structure. Do you have any idea how can I do this with google drive api and javascript. Thanks.</p>
  
  <p>Here is my code. It just uploads the files inside folders but not the folders.</p>
  
  <pre><code>&lt;html&gt;
  &lt;head&gt;
  &lt;meta http-equiv="Content-type" content="text/html;charset=UTF-8"&gt;
  &lt;script type="text/javascript"&gt;
      var CLIENT_ID = 'xxxxxxxxxxxxxxxxxxx';
      var SCOPES = 'https://www.googleapis.com/auth/drive';
  
      /**
       * Called when the client library is loaded to start the auth flow.
       */
      function handleClientLoad() {
          window.setTimeout(checkAuth, 1);
      }
  
      /**
       * Check if the current user has authorized the application.
       */
      function checkAuth() {
          gapi.auth.authorize(
              { 'client_id': CLIENT_ID, 'scope': SCOPES, 'immediate': true },
              handleAuthResult);
      }
  
      /**
       * Called when authorization server replies.
       *
       * @param {Object} authResult Authorization result.
       */
      function handleAuthResult(authResult) {
          var authButton = document.getElementById('authorizeButton');
          var filePicker = document.getElementById('filePicker');
          authButton.style.display = 'none';
          filePicker.style.display = 'none';
          if (authResult &amp;&amp; !authResult.error) {
              // Access token has been successfully retrieved, requests can be sent to the API.
              filePicker.style.display = 'block';
              filePicker.onchange = uploadFile;
          } else {
              // No access token could be retrieved, show the button to start the authorization flow.
              authButton.style.display = 'block';
              authButton.onclick = function () {
                  gapi.auth.authorize(
                      { 'client_id': CLIENT_ID, 'scope': SCOPES, 'immediate': false },
                      handleAuthResult);
              };
          }
      }
  
      /**
       * Start the file upload.
       *
       * @param {Object} evt Arguments from the file selector.
       */
      function uploadFile(evt) {
          gapi.client.load('drive', 'v2', function () {
              var output = document.getElementById('output');
  
  
              var files = evt.target.files; // FileList object
  
              var totalFiles = files.length; // important
  
              for (var i = 0; i &lt; totalFiles; i++) {
                  var file = evt.target.files[i];
                  insertFile(file);
            /*      if (file.isFile) {
                      document.write("OLDUUUUUUU");
                  } else if (file.isDirectory) {
                      document.write("haydaaaaa");
                  }*/
                  console.debug(file.webkitRelativePath);
                  output.innerText = output.innerText + file.webkitRelativePath + "\n";
              }
  
          //    var file = evt.target.files[0];
           //   insertFile(file);
          });
      }
  
      /**
       * Insert new file.
       *
       * @param {File} fileData File object to read data from.
       * @param {Function} callback Function to call when the request is complete.
       */
      function insertFile(fileData, callback) {
          const boundary = '-------314159265358979323846';
          const delimiter = "\r\n--" + boundary + "\r\n";
          const close_delim = "\r\n--" + boundary + "--";
  
          var reader = new FileReader();
          reader.readAsBinaryString(fileData);
          reader.onload = function (e) {
              var contentType = fileData.type || 'application/octet-stream';
              var metadata = {
                  'title': fileData.name,
                  'mimeType': contentType,
                  'parents': [{ "id": "0B-WlbPCzbAQpfmhpNXVRWmFlT2daWC1xNEUyQUJEbnViZThYUXVzMFpvdTNuYTc4aDJmb0E" }]
              };
  
              var base64Data = btoa(reader.result);
              var multipartRequestBody =
                  delimiter +
                  'Content-Type: application/json\r\n\r\n' +
                  JSON.stringify(metadata) +
                  delimiter +
                  'Content-Type: ' + contentType + '\r\n' +
                  'Content-Transfer-Encoding: base64\r\n' +
                  '\r\n' +
                  base64Data +
                  close_delim;
  
              var request = gapi.client.request({
                  'path': '/upload/drive/v2/files',
                  'method': 'POST',
                  'params': { 'uploadType': 'multipart' },
                  'headers': {
                      'Content-Type': 'multipart/mixed; boundary="' + boundary + '"'
                  },
                  'body': multipartRequestBody
              });
  
           /*   var request = gapi.client.request({
                  'path': '/drive/v2/files',
                  'method': 'POST',
                  'params': { 'uploadType': 'multipart' },
                  'body': {
                      "title": "cat",
                      "mimeType": "application/vnd.google-apps.folder",
                      "description": "Some"
                  }
              });*/
  
              if (!callback) {
                  callback = function (file) {
                      console.log(file)
                  };
              }
              request.execute(callback);
          }
      }
  
  &lt;/script&gt;
  &lt;script type="text/javascript" src="https://apis.google.com/js/client.js?onload=handleClientLoad"&gt;&lt;/script&gt;
  &lt;/head&gt;
  &lt;body&gt;
   &lt;!--Add a file picker for the user to start the upload process 
       &lt;input type="file" name="files[]" multiple directory webkitdirectory mozdirectory&gt;
      --&gt;
   &lt;div&gt;
      &lt;input type="file" id="filePicker" multiple directory webkitdirectory mozdirectory /&gt;
      &lt;input type="button" id="authorizeButton" style="display: none" value="Authorize" /&gt;
  &lt;/div&gt;      
  &lt;div id="output"&gt;&lt;/div&gt;
  </code></pre>
  
  <p>
    </p>