I am trying to update a subtask. More specifically just the due date.
I have tried several things and have failed.
This is what I have tried so far:
Attempt 1:
URL: https://app.asana.com/api/1.0/tasks/
JSON: {"data":{"due_on":"6/18/2017 12:00:00 AM"}}
Error: The remote server returned an error: (400) Bad Request.
Attempt 2: Added a parent id to JSON request
URL: /tasks/
JSON: ParentID is masked for security reasons
{"data":{"due_on":"6/18/2017 12:00:00 AM","parent":{"id":################,"name":null}}}
Error: The remote server returned an error: (400) Bad Request.
attempt 3: using /subtask in URL
URL: /tasks//subtasks/
JSON: {"data":{"due_on":"6/18/2017 12:00:00 AM"}}
ERROR: The remote server returned an error: (404) Not Found
What should be the correct URL to send the JSON request and what should be in the request to modify the subtask due date ?
Any help is greatly appreciated.
Thanks
Viv
Vivek,
The first thing I noticed is that the URL doesn't contain the ID of the task you're trying to update - I'm not sure if this is a copy-paste omission in the question, but if not and the URL you're using doesn't have the ID of the task, we won't know which task you're trying to set the due date for - so that might be one thing you're seeing :)
Additionally, I'd like to verify that you're using the HTTP verb PUT for these requests; you can POST new tasks in Asana, but to change fields on an existing task, we expect a PUT. Since subtasks count as tasks in Asana, this can be done just against https://app.asana.com/api/1.0/tasks/:task_id route
One more thing: setting the due date or due time in Asana are actually 2 separate things - most tasks have their due date set, but in our web app you can choose to add the time when setting the due date. This is represented in our API by the fields due_on for dates and due_at for times. If you just want the due date (inferred by the fact that the time is 12:00 AM) you'll probably want due_on and a string whose format is YYYY-MM-DD (in this case, 2017/06/18). If you want to set the actual time, you can use due_at with an ISO8601 timestamp, such as 2017-06-18T08:00:00Z
Putting it all together, here's a curl request I tested here with "due_at" to keep the time aspect in:
curl --request PUT \
--header "Authorization: Bearer $ASANA_PERSONAL_ACCESS_TOKEN" \
"https://app.asana.com/api/1.0/tasks/$TASK_ID" -d '{
"data": {
"due_at": "2017-06-08T12:00:00Z"
}
}'
Finally, and completely unrelated: do you happen to be the Vivek Patel currently working for Yelp? If so, I used to work with you at Sharpcast - small world! If not, no worries, feel free to ignore!
Related
I am using put to modify a resource. I was wondering what is the appropriate status code to return when the id given in the path is different from the id given to the body of the resource.
e.g.
REST api action method is: /resources/{id}
Body:
{
"id": "test",
"name": "my_resource"
}
What HTTP Status Code should be returned to the following curl request?
curl -X PUT 'localhost:8080/resources/test2' \
--header 'Content-Type: application/json' \
--data-raw '{
"id": "test",
"name": "my_resource"
}'
You can probably make an argument for any of
403 Forbidden (I understand your request, and I decline to fulfill it - see response body for details)
409 Conflict (Your proposed change conflicts with the current state of the resource - see response body for details)
422 Unprocessable Content (The body of your request is internally consistent, but doesn't make sense here - see response body for details).
For the general purpose elements of the HTTP application itself, it doesn't very much matter which of these you choose - they are all non-cacheable errors, the component isn't going to have any sort of automatic recovery, etc.
One tie breaker you might consider is how these entries are going to appear in your access logs / how your automated monitoring is going to handle them: if you want these messages to stand out in your logs, then you'll want to choose status code that's not overloaded with other meanings.
For more details, see section 15.5 of HTTP Semantics
Do you think that a 500 Internal Server Error with a proper explanation would be fine as well or is it confusing?
5xx Server Error is inappropriate when the information in the request is the source of the problem, because the form of the request is the client's responsibility, not the server's.
Loosely: 4xx covers all of the cases where the server is announcing "you should not have asked for that". 5xx is for variations of "what you asked for is fine, but I couldn't do it."
See the HTTP Semantics spec, in particular sections 15.5 and 15.6 (or, if you prefer the earlier reference, RFC 7231 6.5 and 6.6)
I'm not sure when this started happening (I believe fairly recently). This is a breaking change if you rely on the steps documented here:
https://msdn.microsoft.com/en-us/office/office365/howto/sync-calendar-view
The issue is that the the Office 365 & Outlook.com calendarview api no longer seems to return a #odata.nextLink when there is more data to be fetched if you specify "odata.track-changes" for the "Prefer" header in your request.
Here is a CURL request to repro the issue... be sure make the request authenticated as a user with at least 50 events during the time frame specified (to trigger paging).
curl -H "Authorization: Bearer <OMITTED>" -H "Accept: application/json; odata.metadata=none" -H "Prefer: odata.track-changes" "https://outlook.office.com/api/v2.0/me/calendarview?startdatetime=2016-06-16T00:00:00Z&enddatetime=2017-06-23T00:00:00Z"
When I make this request, the resulting response has 10 entries (even though there are at least 50 events) and the response does not have an #odata.nextLink. It does have a #odata.deltaLink however.
Is anyone else experiencing this issue?
As far as I know it has always worked this way. The initial sync returns a deltaLink instead of a nextLink. You have to treat that initial sync request specially and go ahead and issue the next request using the deltaToken.
Initial sync request: The very first sync request sets up the sync state.
Initial sync response:
Check for "Preference-Applied: odata.track-changes" in the response header to confirm a successful sync attempt and the resource supports synchronization.
If the sync attempt was successful, the initial response always contains an #odata.deltaLink with a deltaToken value. If the response contains any data, save the deltaToken value for the second request.
If the initial response wasn't successful, or doesn't return any data indicating there are no events in the specified calendar view, this round of sync ends.
Subsequent sync request: Use the deltaToken or skipToken value from the previous request to issue the next request. See the second and third sync requests as examples.
Subsequent sync response:
If the response returns any data, and, there is more data to sync in that time range, the response would include an #odata.nextLink and a skipToken value. Save the skipToken for the next sync request.
Go back to step 3, follow the nextLink, if any, apply the corresponding skipToken value in the next sync request, and follow any subsequent nextLink, until you have synchronized all the data in the time range for that calendar.
Final sync response: When all events in the calendar view are synchronized, the final response in this round would include an #odata.deltaLink and a deltaToken again. Save the deltaToken value for the next round of synchronization.
I'm having problems using the server-side paging, utilizing the #odata.nextlink to fetch the next page of data from Microsoft Graph, based on the information in this page. I'm using raw GETs, with the authorization token set in the header (ie, I'm not using a language API, I'm trying this from Powershell using curl). I've scrubbed sensitive data from the following snippets, replacing them with x's, but hopefully the problematic info comes across.
For the first GET, I query with
https://graph.microsoft.com/beta/drives/b!Gxxxxx-xxxxxxge/root:/ReallyBigFolder:/children?top=200
and I get a response with 200 items, as expected. The #odata.nextlink field in this response is
https://graph.microsoft.com/beta/drives/b!Gxxxxx-xxxxxxge/root/children?top=200&$skiptoken=Paged%3dTRUE%26p_SortBehavior%3d0%26p_FileLeafRef%3d279%252ezip%26p_ID%3d208%26p_FileDirRef%3dMaintenance%2520Department%252fReallyBigFolder%26RootFolder%3dMaintenance%2520Department%252fReallyBigFolder
For the examples in the Microsoft Graph documentation linked above, the $skiptoken=... part has random-looking numbers, but mine has $skiptoken=Paged=TRUE&etc. Perhaps the API has changed the response since the documentation was written, or mine is completely incorrect.
My understanding from the documentation is that I should be able to use this URL as an opaque value, and GET it from the Graph API (with auth token of course) without modification. However, when I do this, the response is
{"#odata.context":"https://graph.microsoft.com/beta/$metadata#drives('b%21Gxxxxx-xxxxxxge')/root/children","value":[]}
Where I'm expecting to get another 200 files listed, there are no files returned at all, and it appears the path is gone, pointing to the root rather than the subfolder like it should have been.
I've also tried this in Graph Explorer with both the /beta and /v1.0 endpoints, and it fails in the same way there as well.
Where am I going wrong?
Edit with details for debugging: Note: Graph Explorer doesn't seem to display the Date field from headers, so I'm using Postman Chrome Plugin for these values.
First GET request is to
beta/drives/b!xxx-xxxge/root:/Really%20Big%20Folder/ReallyBigFolder:/children
With response headers
Cache-Control →private
Content-Encoding →gzip
Content-Type →application/json;odata.metadata=minimal;odata.streaming=true;IEEE754Compatible=false;charset=utf-8
Date →Fri, 26 May 2017 19:07:54 GMT
Duration →2033.3889
OData-Version →4.0
Transfer-Encoding →chunked
Vary →Accept-Encoding
client-request-id →6faf5d1d-a291-410a-b269-f4667187d7cb
request-id →6faf5d1d-a291-410a-b269-f4667187d7cb
x-ms-ags-diagnostic →{"ServerInfo":{"DataCenter":"North Central US","Slice":"SliceB","ScaleUnit":"002","Host":"AGSFE_IN_11","ADSiteName":"CHI"}}
and nextLink (obfuscated slightly for security)
https://graph.microsoft.com/beta/drives/b!xxx-xxxge/root/children?$skiptoken=Paged%3dTRUE%26p_SortBehavior%3d0%26p_FileLeafRef%3d279%252ezip%26p_ID%3d208%26p_FileDirRef%3dGSH%2520Test%252fMaintenance%2520Department%252fReally%2520Big%2520Folder%252fReallyBigFolder%26RootFolder%3d%252fGSH%2520Test%252fMaintenance%2520Department%252fReally%2520Big%2520Folder%252fReallyBigFolder
Following the nextLink produces headers (unchanged headers omitted):
Date →Fri, 26 May 2017 19:15:17 GMT
Duration →512.9537
client-request-id →6ba61712-a423-4bc8-9376-cc62bf854329
request-id →6ba61712-a423-4bc8-9376-cc62bf854329
x-ms-ags-diagnostic →{"ServerInfo":{"DataCenter":"North Central US","Slice":"SliceA","ScaleUnit":"001","Host":"AGSFE_IN_7","ADSiteName":"CHI"}}
and resulting body:
{
"#odata.context": "https://graph.microsoft.com/beta/$metadata#drives('b%21xxxx-xxxxge')/root/children",
"value": []
}
You are correct that the nextLink should be an opaque URL that returns you the next set of results. The format of that string may change over time, so you should not try to parse or otherwise interpret the string, but the usage should be the same.
The response that you are getting back is consistent with an empty result -- meaning that there are no additional files to list.
How many results do you have in ReallyBigFolder? What happens if you set top to a different value (say, 5? 1000?)
Note that the #odata.context describes the result, but is not necessarily the same as the request URL. Is the #odata.context that you get back from nextLink different than that you got back from the initial request? It should be the same...
I am using webhooks for the first time with calendly.com. I would like to create a subscription as described here. When I get to doing this
curl --header "X-TOKEN: <your_token>" --data "url=https://blah.foo/bar&events[]=invitee.created" https://calendly.com/api/v1/hooks
I am concerned that the url is not in a valid format. I tried replacing the & with a ? as in here
curl --header "X-TOKEN: <your_token>" --data "url=https://blah.foo/bar?events[]=invitee.created" https://calendly.com/api/v1/hooks
but I receive this error
{"events":{"events":["can't be blank]}}
Likewise, I try to leave the & and everything after it blank and it give the same error as above.
But using a url with the & and everything in it gives a 404 not found error. Can a url even have the format they are saying is required?
But using a url with the & and everything in it gives a 404 not found error.
The URL part in the following is just the https://blah.foo/bar part before the & character.
curl --header "X-TOKEN: <your_token>" --data "url=https://blah.foo/bar&events[]=invitee.created" https://calendly.com/api/v1/hooks
The events[]=invitee.created part is a separate parameter and value. It’s not part of the url.
See the Create A Webhook Subscription page in the calendy docs:
So the URL is the site that runs your webhook; you don’t send the events parameter/value back to that site—instead you’re sending both the url param and events param to the calendly API endpoint at https://calendly.com/api/v1/hooks. The calendly backend presumably then calls to https://mywebsite.com/webhooks/invitee_created or https://blah.foo/bar whatever url you’ve given it—but without the events parameter, which is for calendly’s internal use.
I'm trying to verify if there is a remote url with following code:
endpoint_uri = URI.parse(#endpoint.url)
endpoint_http = Net::HTTP.new(endpoint_uri.host, endpoint_uri.port)
endpoint_request = Net::HTTP::Head.new(endpoint_uri.request_uri)
endpoint_response = endpoint_http.request(endpoint_request)
I'm still getting 405 Method not allowed. When I use Get instead Head in Net::HTTP::Head.new I'm getting 200 Success but also with whole remote document in response what results in bigger response time (0.3s => 0.9s).
Any ideas why this is happening? Thx
There's a chance that the #endpoint url you're trying to interact with doesn't support HEAD requests (which would be really weird, but still may be the case). Your code works fine for me with a handful of urls (google.com, stackoverflow.com, etc.)
Have you tried a curl request to see what it returns?
curl -I http://www.the_website_you_want_to_test.com