skip to Main Content

I’m trying to upload a CSV file to google drive and I’m getting the error described in the subject of this post.

this is my code:

I think my error is in the content generation. I’ve seen some other posts but I can’t resolve it yet.

this is the code

public function uploadFileToDrive($token, $fileContent){
        echo "Iniciando subida de archivo a drive .... n";
        
        try {
            $apiUrl = 'https://www.googleapis.com/';
            $ch1 = curl_init();

           
            /* MEtODO 1 */
            $mime_type = 'text/csv';
            $data = '
            --section_divider
            Content-Type: application/json; charset=UTF-8
            {
                "name": "test.xlsx",
            }

            --section_divider
            Content-Type: '.$mime_type.',
            '.$fileContent.'
            --section_divider--
            ';

           
            //print_r($body);die();
            curl_setopt($ch1, CURLOPT_URL, $apiUrl . 'upload/drive/v3/files?uploadType=multipart');
            curl_setopt($ch1, CURLOPT_POST, 1);
            curl_setopt($ch1, CURLOPT_POSTFIELDS, $data);
            curl_setopt($ch1, CURLOPT_RETURNTRANSFER, true);

            curl_setopt($ch1, CURLOPT_HTTPHEADER, array('Content-Type: multipart/related;section_divider', 'Authorization: Bearer' . $token) );

            $response = curl_exec($ch1);
            if ($response === false) {
                echo 'Curl error: ' . curl_error($ch1);
            } else {
                echo "Operation completed without any errors n";
                $output = $response;
            }
            curl_close($ch1);
            var_dump($output);die();
            return $output;

        } catch (Exception $e) {
            print "An error occurred: " . $e->getMessage();
        }

    }

I don’t know what I’m doing wrong

I hope you can give some advice
thanks

The expected results. See the CSV file uploaded on google drive.

See in the console a response indicating that all it’s done

2

Answers


  1. I thought that in your script, $data and Content-Type are required to be modified. So, how about the following modification?

    From:

    $data = '
    --section_divider
    Content-Type: application/json; charset=UTF-8
    {
        "name": "test.xlsx",
    }
    
    --section_divider
    Content-Type: '.$mime_type.',
    '.$fileContent.'
    --section_divider--
    ';
    
    
    //print_r($body);die();
    curl_setopt($ch1, CURLOPT_URL, $apiUrl . 'upload/drive/v3/files?uploadType=multipart');
    curl_setopt($ch1, CURLOPT_POST, 1);
    curl_setopt($ch1, CURLOPT_POSTFIELDS, $data);
    curl_setopt($ch1, CURLOPT_RETURNTRANSFER, true);
    
    curl_setopt($ch1, CURLOPT_HTTPHEADER, array('Content-Type: multipart/related;section_divider', 'Authorization: Bearer' . $token) );
    

    To:

    $data = '
    --section_divider
    Content-Type: application/json; charset=UTF-8
    
    {"name": "test.csv", "mimeType": "text/csv"}
    
    --section_divider
    Content-Type: '.$mime_type.',
    
    '.$fileContent.'
    
    --section_divider--';
    
    //print_r($body);die();
    curl_setopt($ch1, CURLOPT_URL, $apiUrl . 'upload/drive/v3/files?uploadType=multipart');
    curl_setopt($ch1, CURLOPT_POST, 1);
    curl_setopt($ch1, CURLOPT_POSTFIELDS, $data);
    curl_setopt($ch1, CURLOPT_RETURNTRANSFER, true);
    
    curl_setopt($ch1, CURLOPT_HTTPHEADER, array('Content-Type: multipart/related;boundary=section_divider', 'Authorization: Bearer ' . $token) );
    
    • By this modification, the following file metadata of the uploaded file is returned.

        {
         "kind": "drive#file",
         "id": "###",
         "name": "test.csv",
         "mimeType": "text/csv"
        }
      

    Note:

    • In your script, although you want to upload a CSV file, the filename is test.xlsx. And also, the mimeType is not set. By this, the mimeType of the uploaded file is automatically set as application/vnd.openxmlformats-officedocument.spreadsheetml.sheet. When you want to upload a CSV file as the CSV data, please set the mimeType of text/csv.

    • If you want to upload the CSV data as Google Spreadsheet, please set the mimeType as "mimeType": "application/vnd.google-apps.spreadsheet" instead of "mimeType": "text/csv".

    • In your script, 'Authorization: Bearer' . $token is used. In this case, if $token is ya29.###, it is required to insert a space like 'Authorization: Bearer ' . $token. In my modification, 'Authorization: Bearer ' . $token is used. Please be careful about this.

    Reference:

    Added 1:

    From your following reply,

    I did the changes as you has recommended. the process ends, but file isn’t uploaded on the drive. I’ve put a print_r($output) and I get this message: "Invalid multipart request with 0 mime parts."

    In order to upload the file with multipart/related, the spaces and the line breaks in the request body are important. From your current error message, I’m worried about it. So, in order to avoid this, I would like to propose one more modification. Please modify as follows. "### From:" is the same as the above modification.

    To:

    $data = implode([
        "--section_dividerrn",
        "Content-Type: application/json; charset=UTF-8rnrn",
        "{"name": "test.csv", "mimeType": "text/csv"}rnrn",
        "--section_dividerrn",
        "Content-Type: ".$mime_type."rnrn",
        $fileContent."rnrn",
        "--section_divider--",
    ], "");
    
    //print_r($body);die();
    curl_setopt($ch1, CURLOPT_URL, $apiUrl . 'upload/drive/v3/files?uploadType=multipart');
    curl_setopt($ch1, CURLOPT_POST, 1);
    curl_setopt($ch1, CURLOPT_POSTFIELDS, $data);
    curl_setopt($ch1, CURLOPT_RETURNTRANSFER, true);
    
    curl_setopt($ch1, CURLOPT_HTTPHEADER, array('Content-Type: multipart/related;boundary=section_divider', 'Authorization: Bearer ' . $token) );
    
    • When I tested the above 2 modified scripts, I confirmed that no error occurs and the CSV data is uploaded with multipart/related in my Google Drive.

    Added 2:

    From your following reply,

    I try with the new code. now returns { "kind": "drive#file", "id": "1Qorzy6e5Vm_x2PU_lGdF066SI8c76DZy", "name": "test.csv", "mimeType": "text/csv" } BUT the big "but", the file isn’t appears on google drive.

    Yes your script works. I get the token through service account.

    It was found that your error of Invalid multipart request with 0 mime parts. was resolved, and your question was resolved.

    About BUT the big "but", the file isn't appears on google drive., I think that this is a new issue. In this case, it is required to know about the access token.

    If your access token is retrieved from OAuth2, I think that the uploaded file can be seen in the root folder of your Google Drive. So, from BUT the big "but", the file isn't appears on google drive., I guessed that your access token might be retrieved from the service account. If your access token is retrieved from the service account, the uploaded file is put into the root folder of the service account. By this, the file cannot be directly seen in your Google Drive. If you want to see the uploaded file in your Google account, please use the access token retrieved with OAuth2 from your account. Or, if you are required to use the service account, for example, how about the following flow?

    1. Create a new folder in your Google drive.

    2. Share the created folder with the email of the service account as the writer. And please copy the folder ID.

    3. Upload the file to your folder. In this case, please modify the above script as follows.

      • From

          "{"name": "test.csv", "mimeType": "text/csv"}rnrn",
        
      • To

          "{"name": "test.csv", "mimeType": "text/csv", "parents": ["###folderID###"]}rnrn",
        
      • Please replace ###folderID### with your folder ID.

    Of course, you can also see the uploaded file in the Google Drive of the service account by sharing the uploaded file with your Google account. In that case, please use Permissions of Drive API.

    Login or Signup to reply.
  2. Your curl request does not look good.

    xlsx mime type is

    application/vnd.openxmlformats-officedocument.spreadsheetml.sheet

    You are doing a text based transfer, you likely need to do a binary transfer, or base64 encoded.

    Where did you get this code?
    Is there some documentation?

    I assume you do not want to use their Drive API.
    I set token value to 12345.
    I created the CSV content:

    key,value
    key,value
    key,value
    

    And this is what your request header looks like.

    POST /<my curl test> HTTP/1.1
    Host: mycurltest.com
    Accept: */*
    Content-Type: multipart/related;section_divider
    Authorization: Bearer 12345
    Content-Length: 294
    

    Your request BODY=

            --section_divider
            Content-Type: application/json; charset=UTF-8
            {
                "name": "test.xlsx",
            }
    
            --section_divider
            Content-Type: text/csv,key,value
    key,value
    key,value
            --section_divider--
            
    

    You may need a space after "Bearer"

    'Authorization: Bearer' . $token)
    

    I do not and will not use Google so I cannot get what a request should look like.

    If you do not want to use their Drive API and you want my help, you have to get me the curl me request. Or some documentation. Like why Bearer authorization, why multipart/related, Why JSON in the post fields?

    Go to Google Drive to the form where you upload a file.
    Before you submit, in you Browser open the Network tab in the DevTools
    I assume you are using Google’s Chrome Browser (another thing I would never do).
    Upload your spreadsheet to Google Drive.
    Right click the first Request on the Network tab and Copy=>Copy as cURL
    Paste the curl request in your answer.

    Google

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search