Jump to content

Recommended Posts

Posted (edited)

I nearly have file uploading working using the /downloads/files end point:
https://invisioncommunity.com/developers/rest-api?endpoint=downloads/files/POSTindex

I am not sure how to set up the POST command, rather than the GET command. My code produces an error, but if I supply the category and other arguments in the URL, the system thinks I am trying to do a GET request.

std::string token = InvisionPower::AuthenticateUser(name, password, "profile");
std::string options = "category=97&description=MyDescription&title=FileName&author=1";

nlohmann::json postData;
postData = {};
postData["category"] = 97;
postData["author"] = 1;
postData["description"] = "Mydescription";
postData["files"].push_back({ "MyFile.zip", "MDAwMDAw" });

auto j3 = InvisionPower::APIPost("/downloads/files/", token, postData.dump());

if (j3["response"].is_string())
{
    Print(std::string(j3["response"]));
}

My code produces this error (no typo):

{
    "errorCode": "1S303\/7",
    "errorMessage": "NO_CATEGEORY"
}

I also tried supplying the POST data this way, but it gave the same result:

std::string options = "category=97&description=MyDescription&title=FileName&author=1";
auto j3 = InvisionPower::APIPost("/downloads/files/", token, options);

My APIPost function looks like this:

nlohmann::json APIPost(String endpoint, String bearerToken, String postData)
{
    CURL* curl;
    CURLcode res;

    curl = curl_easy_init();
    std::string readBuffer;

    if (curl)
    {
        std::string url = CommunityURL + "api" + endpoint;
        curl_easy_setopt(curl, CURLOPT_URL, url.c_str());

        std::string bearerTokenHeader = "Authorization: Bearer " + bearerToken;

        struct curl_slist* headers = NULL;
        headers = curl_slist_append(headers, bearerTokenHeader.c_str());
        headers = curl_slist_append(headers, "Content-Type: application/json"); // Set content type for JSON
        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);

        // Set the POST method
        curl_easy_setopt(curl, CURLOPT_POST, 1L);

        // If there's postData, set it as the request body
        if (!postData.empty())
        {
            curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postData.c_str());
        }

        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);

        res = curl_easy_perform(curl);

        if (res != CURLE_OK)
        {
            fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
        }

        curl_easy_cleanup(curl);
    }

    String response = readBuffer;
#ifdef _DEBUG
    Print(response);
#endif
    auto j3 = ParseJson(response);
    if (j3.is_object() && j3["errorMessage"].is_string())
    {
        Print("Error: " + std::string(j3["errorMessage"]));
        return {};
    }
    return j3;
}

Any idea what I am doing wrong?

Edited by Interferon
Posted (edited)

If I change the content-type to "application/x-www-form-urlencoded" then I get past the category and other errors, and just have a NO_FILES error:

std::string options = "category=97&description=MyDescription&title=FileName&author=1";
options += "&files=MyFile.zip%2CMDAwMDAw";
auto j3 = InvisionPower::APIPost("/downloads/files/", token, options);

I do not know how to encode an array in this format. The file name is "MyFile.zip" and the file contents in base64 encoding are "MDAwMDAw" (8 zeroes).

Edited by Interferon
Posted

Also does not work

std::string options = "category=97&description=MyDescription&title=FileName&author=1";
options += "&files=MyFile.zip=MDAwMDAw";// ???
auto j3 = InvisionPower::APIPost("/downloads/files/", token, options);

 

Posted

This looks correct, as far as I can tell, but it does not work:

std::string options = "category=97&description=MyDescription&title=FileName&author=1";
options += "&files=" + urlEncode("[{\"MyFile.zip\":\"MDAwMDAw\"}]");
auto j3 = InvisionPower::APIPost("/downloads/files/", token, options);

 

Posted (edited)

I think this is closer. Now I get the error BAD_FILE_EXT:

std::string options = "category=97&description=MyDescription&title=FileName&author=1&";
options += urlEncode("files[0].MyFile.zip") + "=" + urlEncode("MDAwMDAw");
auto j3 = InvisionPower::APIPost("/downloads/files/", token, options);

.zip files are the only type this category accepts.

Edited by Interferon
Posted (edited)

I changed the category to allow any file type, and upload works now.

std::string options = "category=97&description=MyDescription&title=FileName&author=1&";
options += urlEncode("files[0].MyFile.txt") + "=" + urlEncode("Hello!");
auto j3 = InvisionPower::APIPost("/downloads/files/", token, options);

The contents of the uploaded file are correct, but the file name is a long string of random characters:

"files": [
        {
            "name": "_.8193c6a2743a9ba37be5ba52574f"
            "url": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx,
            "size": 6
        }
]

 

Edited by Interferon
  • Solution
Posted (edited)

Damn, I figured it out thanks to this post:

Files is NOT an array, it is an OBJECT, and the file name and contents are key-value pairs on this OBJECT.

options += "files[MyFile.zip]=Hello!";

 

Edited by Interferon
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...