0

I've spend a week trying to work out how to update some card information, I'd hoped to update a load of fields at one, e.g. name, desc, idList, closed etc, but after looking around it seems they have to be done individually, but when I try I keep getting a 400 response with message "invalid value for value" .

e.g. When I try to PUT https://api.trello.com/1/cards/[cardid]/desc?key=[mykey]&token=[mytoken]value=just+yet+another+test+of+trello+side+extended

what am I doing wrong?

Java code used to send Put is

private static InputStream doRequest(final String url, final String requestMethod, final Map<String, String> map) 
{
    try 
    {
        final HttpsURLConnection conn = (HttpsURLConnection) new URL(url)
                .openConnection();
        conn.setRequestProperty("Accept-Encoding", "gzip, deflate");
        conn.setDoOutput(requestMethod.equals(METHOD_POST) || requestMethod.equals(METHOD_PUT));
        conn.setRequestMethod(requestMethod);

        String plus = "";
        if (map != null && !map.isEmpty()) 
        {
            final StringBuilder sb = new StringBuilder();
            for (String key : map.keySet()) 
            {
                sb.append(sb.length() > 0 ? "&" : "")
                    .append(key)
                    .append("=")
                    .append(URLEncoder.encode(map.get(key), "UTF-8"));
            }
            conn.getOutputStream().write(sb.toString().getBytes());
            conn.getOutputStream().close();
            plus = sb.toString();
        }
        final int rc = conn.getResponseCode();
        logger.info("response " + rc + " from " + requestMethod + " " + url + plus);
        if (rc > 399) 
        {
             return null;
        } 
        else 
        {
            return getWrappedInputStream(
                conn.getInputStream(), GZIP_ENCODING.equalsIgnoreCase(conn.getContentEncoding())
            );
        }
    } 
    catch (IOException e) 
    {
        throw new TrelloException(e.getMessage());
    }
}
user2790622
  • 11
  • 1
  • 5
  • It might be helpful to know what the message is accompanying the 400. Also, is there a reason you can't use https://trello.com/docs/api/card/index.html#put-1-cards-card-id-or-shortlink to update multiple fields at once? – Aaron Dufour Sep 18 '13 at 15:52
  • I've no idea how to get at the response message. And yea I have also tried using the one you said as well, but cant get that to work either. – user2790622 Sep 18 '13 at 16:30
  • What are you using to make the request? Try `curl -i -X PUT https://api.trello.com/1/cards/[cardid]/desc?key=[mykey]&token=[mytoken]value=just+yet+another+test+of+trello+side+extended` and grab the output. That should include the message. – Aaron Dufour Sep 18 '13 at 16:47
  • I'm doing it from java. No idea what curl is – user2790622 Sep 18 '13 at 17:14
  • If you're on OS X or Linux, it is probably already installed, and you can paste that into a terminal. – Aaron Dufour Sep 18 '13 at 17:16
  • What Java library are you using? Can you put some code in your question? – Aaron Dufour Sep 18 '13 at 17:47
  • It sounds like http://docs.oracle.com/javase/7/docs/api/java/net/HttpURLConnection.html#getResponseMessage() might get the response message. – Aaron Dufour Sep 18 '13 at 18:14
  • response Message is just "Bad Request" – user2790622 Sep 18 '13 at 19:30

2 Answers2

1

I found that I was missing one line in the code

            conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");

that solved the problem, so here is the complete code for doRequest now...

    private static InputStream doRequest(final String url, final String requestMethod, final Map<String, String> map) 
{
    try 
    {
        final HttpsURLConnection conn = (HttpsURLConnection) new URL(url).openConnection();
        conn.setRequestProperty("Accept-Encoding", "gzip, deflate");
        conn.setDoOutput(requestMethod.equals(METHOD_POST) || requestMethod.equals(METHOD_PUT));
        conn.setRequestMethod(requestMethod);
        // following line was missing and caused PUT not to work.
        conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");

        String arguments = "";
        if (map != null && !map.isEmpty()) 
        {
            final StringBuilder sb = new StringBuilder();
            for (String key : map.keySet()) 
            {
                sb.append(sb.length() > 0 ? "&" : "");
                sb.append(URLEncoder.encode(key, HTTP_CHARACTER_ENCODING));
                sb.append("=");
                sb.append(URLEncoder.encode(map.get(key), HTTP_CHARACTER_ENCODING));
            }
            conn.getOutputStream().write(sb.toString().getBytes());
            conn.getOutputStream().close();
            arguments = sb.toString();
        }
        conn.connect();

        final int rc = conn.getResponseCode();
        final String responseMessage = conn.getResponseMessage();
        if (rc != 200)
            logger.info("response " + rc + " (" + responseMessage + ") from " + requestMethod + " " + url + " args:" + arguments);
        if (rc > 399) 
        {
            final String str = stream2String(conn.getErrorStream());
            logger.info("error response:" + str);
            return null;
        } 
        else 
        {
            return getWrappedInputStream(
                conn.getInputStream(), GZIP_ENCODING.equalsIgnoreCase(conn.getContentEncoding())
            );
        }
    } 
    catch (IOException e) 
    {
        throw new TrelloException(e.getMessage());
    }
}
user2790622
  • 11
  • 1
  • 5
0

Based on your code:

sb.append(sb.length() > 0 ? "&" : "")
                .append(key)
                .append("=")
                .append(URLEncoder.encode(map.get(key), "UTF-8"));

It looks like you're actually building a url that looks like:

https://api.trello.com/1/cards/[cardid]/desc?key=[mykey]&token=[mytoken]value=just+yet+another+test+of+trello+side+extended

Note that there is no & between the token and value parameters.

Aaron Dufour
  • 17,288
  • 1
  • 47
  • 69
  • The key and token are added to the url that's passed in – user2790622 Sep 18 '13 at 19:41
  • @user2790622 What is the output of the `logger.info` line? – Aaron Dufour Sep 18 '13 at 20:03
  • response 400 (Bad Request) from PUT https://api.trello.com/1/cards/[cardid]/desc?key=[mykey]&token=[mytoken]value=just+yet+another+test+of+trello+side+extended – user2790622 Sep 18 '13 at 20:19
  • tried that (with and without the "&" before value), makes no difference – user2790622 Sep 18 '13 at 21:03
  • It sounds like there's something wrong with the library you're using. "Bad Request" would only be the response if it wasn't properly-formatted http. That means that this is a Java question, not a Trello question. – Aaron Dufour Sep 18 '13 at 21:33
  • I've done a GET and POST no problems, so I'm stumped on where to look for an answer now. – user2790622 Sep 18 '13 at 21:36
  • That route works just fine, and there's nothing wrong with the URL you said you're using (other than the missing `&`), so there must be something you're not showing me. We don't actually send a response of "Bad Request", so if you can find the actual response, that might be useful. – Aaron Dufour Sep 18 '13 at 21:43
  • Just found out that there is a conn.getErrorStream(), using that It returns "invalid value for value" – user2790622 Sep 18 '13 at 21:52
  • @user2790622 The only restrictions on `value` is that it exist and be less than 16384 characters. – Aaron Dufour Sep 19 '13 at 15:11