Clockify API - Restart time entry - clockify

I would like to mark the last time entry for a user as the current time entry. In other words, I would like to clear the end field of a given time entry, to indicate that it it not finished yet, it's still running.
Is it possible to do that?
I tried using the Update time entry on workspace endpoint, like so:
curl -H 'Content-Type':'application/json' \
-H 'X-Api-Key':'API_KEY' \
-X PUT https://api.clockify.me/api/workspaces/WORKSPACE_ID/timeEntries/TIME_ENTRY_ID \
-d '{"end":null}'
But the response code is 400 with the following response:
{"message":"text","code":3002}
What does this error code mean?

So the documentation for the UpdateTimeEntryRequest (https://clockify.github.io/clockify_api_docs/#/definitions/UpdateTimeEntryRequest) is a bit wrong or incomplete. I figured it out through some testing, here's what you need to do:
First, you need to make sure you have the current data of the time entry, specifically the start date and billable status (as these are the only two "required" fields in the API call). You are getting the 400 bad request because you are missing these two fields - the error message is obviously no help here, but a 400 response code means "the server was unable to process the request sent by the client due to invalid syntax.", which makes sense, since your input is invalid.
Assuming you have the time entry information already (which is the only way I could see how you would know the ID), you could recreate the whole UpdateTimeEntryRequest data but then null out the end field or leave it out completely, like this:
{
"start": START_FROM_THE_TIME_ENTRY,
"billable": BILLABLE_FROM_THE_TIME_ENTRY,
"description": DESC_FROM_THE_TIME_ENTRY,
"projectId": PROJECT_ID,
"taskId": TASK_ID,
"end": null,
"tagIds": TAGS_ARRAY
}
From my testing, this restarts the timer. If you leave out any field, those fields are reset, for example:
{
"start": START_FROM_THE_TIME_ENTRY,
"billable": BILLABLE_FROM_THE_TIME_ENTRY
}
would restart the timer, but it would clear the description, project/task, and tags, which is probably not preferable.

Related

Remove Subscription line items via API for items that no longer exist in WooCommerce Store

Background:
I have about 1000 subscriptions that I need to run through and delete line items. Woocommerce has somehow allowed us to delete products that are tied to subscriptions, meaning there are now up to 1000 subscriptions with products in them which no longer exist.
This creates many problems for the subscribers, such as not being able to manually renew, as they get errors for the products that do not exist.
I can delete them manually, where I will click into a subscription and remove 10+ items 1 by 1 per subscription. This will take way too long manually.
What I’m trying to do:
I want to run through all the subscriptions 1 by 1, look through the line items, and remove any line items where the “parent_id” is 0.
What I have tried so far:
I’ve tried many variations of the JSON below (also both with and without the 'subscription' line), and this is where I am at currently.
See API info here
See line item info here
NOTE: I get no error messages, the request reponse is 200. But no items are removed...
curl -X PUT https://example.com/wp-json/wc/v3/subscriptions/{subscriptions_id} \
-u consumer_key:consumer_secret \
-H "Content-Type: application/json" \
-d '{
"subscription":{
"line_items":[
{
"product_id":0,
"quantity":0
}
]
}
}'
What I would like help with:
At the very least to know if I'm on the right track, or if what I'm trying to do is even possible. But ideally, to point me in the right direction, or help fix up my API request.
Thanks in advance!!
NOTE 2:
I can't use AutomateWoo for this, as AutomateWoo requires the product to exist before you can select it / remove it.
Figured it out...
So you need to refer to the line item by using 'id' and not 'product_id' if you want to remove it. Because the 'id' is never empty (even if the product doesn't exist), I had to build a complex automation using different API endpoints.
You need to
list all subscriptions
have automation run through line items per subscription, only allowing ones with product_id = 0 to pass
run the proper JSON to delete the line items referencing the 'id'
{
"line_items": [{
"id": 18756,
"quantity": 0
}]
}

How to disable the execution info (execution timestamp, elapsed time, user etc.) in Google Colab?

After I execute some code cell in Google Colab, there is a piece of information saved and displayed when hovering over the execute icon, which shows the execution time, time elapsed, the user who executed it, etc. When I look at the .ipynb source code this is stored as JSON as thus (prettified):
"metadata": {
...
"executionInfo": {
"status": "ok",
"timestamp": <execution time>,
"user_tz": ...,
"elapsed": <elapsed time>,
"user": {
"displayName": <Google account name>,
"photoUrl": ...,
"userId": ...
}
}
...
}
I don't want to omit cell output, but can I somehow disable this feature? It is kind of annoying that it actually displays when and who executed this. I know I can delete this information locally, but this has to be done every time it's modified by Colab.
There is no way to suppress this information other than the mechanisms you mention: 1) enabling private outputs, which prevents saving any outputs. Or, 2) editing the notebook by hand.

How can I fix a 501 error from the clockify API?

I'm getting a 501 response from the clockify API when trying to create a Time Entry using CreateTimeEntryRequest
I've verified I can query the API and get data from it, so I'm using the correct X-Api-Key, I've resolved a few issues with bad datetime formats, but I'm still getting the error.
URL I'm posting to:
https://api.clockify.me/api/workspaces/REMOVED/timeEntries/
My POST request header looks like this:
{"x-api-key": REMOVED, "Content-Type": "application/json"}
The body of the request is (For example):
{"start": "2019-01-28T14:53:04Z", "billable": false, "description": "Test Time Entry", "projectID": null, "taskID": null, "end": "2019-01-28T15:53:04Z", "tagIds": []}
I'm getting:
{"message": "Entity not created.", "code": 501}
And the time entry is not being created.
I expect some kind of success message
It has something to do with the "End" variable. If you remove it, it'll work. This of course means the timer will be running (also you will get a 400 error if you already have a timer running), so if you want to stop it, you'll have to immediately call PUT /workspaces/{workspaceId}/timeEntries/endStarted or if you want the stop time to be at some point in the past, you'll have to update the timer with PUT /workspaces/{workspaceId}/timeEntries/{id}. However the update doesn't seem to work either (same issue). My guess is they made a change to the endpoint (perhaps renamed the "end" variable), because I'm about 75% sure I used this API within the last month or so and it worked.
Hopefully someone from Clockify will see this and give an update. I had a similar issue happen with the "me" field in the GetSummaryReportRequest object. It stopped working and removing the field fixed it.

How to give empty value for argument in POST request for hyperledger composer rest server

I am trying to make a post request via R using the httr package to composer rest server. I have written a code and then created the composer rest server from it. These are my details
Request URL : http://localhost:3000/api/nl.amis.registry.fruits
Body: {
"$class": "nl.amis.registry.fruits",
"Id": "9",
"name": "orange",
"description": "string",
"count": ""
}
First, I have tried with the composer rest server. For my purpose, I needed the count to be blank and the value will be appended by another API call. I was able to make the transaction successfully with the count: "". This I was able to check in the test section of the composer playground. The remaining code works fine which appends the count variable later on.
Now I am writing an R code to make a similar transaction through POST request. Here I am facing an error that "count cannot be blank" and returns with error 422 Unprocessable entity. The content type I was used was application/json. While using the "count":{} , the post request process fine and i am getting "count":[object Object] in the response. But the later on code which does the appending will do something like count:"[object Object],1" wherein I am expecting "count":"1". Everything works fine while using the test in composer playground but while trying to access externally via rest API is creating the problem. Please help.
you can use an Optional keyword to declare a count in an asset of the model file. using Optional keyword you can post an empty value of count.
for example:
asset fruits identified by Id {
o String Id
o String name
o String description
o String count optional
}

Restful api data syncing only changed models on big collections

I'm trying to find a best practice method to make my api respond with a 204. Lets consider the following simplified steps:
Client GET: Server response 200 full collection of 10 records
No changes are made
Client GET: server response 304 data not changed
Changes are made to record 5. Record 11 is added. Record 2 is deleted
Client GET: server response 200 with the new collection of 10 records
For 10 records this is not a big issue. However when a collection is lets say a few thousands records you don't want to refresh your entire locally stored collection. In this case it's easier to change the 3 updated models (delete record 2, update record 5, add record 11) So I want something like this
Client GET: Server response 200 full collection (paginated or not)
No changes are made
Client GET: server response 304 data not changed
Changes are made to record 5. Record 11 is added. Record 2 is deleted
Client GET: server response 204 with only information about the 3 changed records
In the above case the request cycle is optimized, but the problem is: how do I get the server to respond like this. I must send some information from the client in either a header or body. I was thinking about exploiting the Last-modified-since header. This will be the date change on the server. The client stores this date when status is 200 or 204. When the client sends this header to the server, the server will only respond with records that are changed or deleted since then. For example:
{
"total": 113440,
"from": 0,
"till": 2,
"count": 3,
"removed": [1,2],
"parameters": [{"id"}, {"title"}],
"collection": [
{
"id": 3,
"title": "Updated record"
},
{
"id": 4,
"title": "New record"
},
{
"id": 5,
"title": "Another new record"
}
],
}
Downside is that the server will be more complex because it needs to keep track of the deleted data and the last updated records.
Keep in mind that I did think of sending silent push updates but I don't want to do this since the user is not always happy with background data traffic.
What do you guys think about this solutions and do you have a similar or better solution keeping the following in mind?
lower the amount of needed requests
make the api descriptive and cellular (api being it's own documentation allowing clientside generators)
be as live as possible
effectively deal with huge collections (ex: pagination, only fetch
updated records, caching etc)
You could send up a If-Modified-Since header with your GET requests for the collection. The endpoint could then return only those contents that have changed since the provided date.
Note that this is not the behaviour specified by the HTTP spec for conditional requests. Carefully consider whether this is the approach you want to take. I would not suggest it.
In the spec as written, there is no way I'm aware of to retrieve a subset of a collection conditionally. The closest I can think of is to have the collection contain only links to the individual elements. Make the client call a GET on each individual element, using If-None-Match or If-Modified-Since so you only pass stale entities over the wire. You'd still have to make a server hit for the collection entity, though you could also use a conditional header on that request.
IMHO this calls for a query interface, where you tell the rest service in the GET parameters what you want, simar to how you would do it in SQL or in a solr or elasticsearch query.
Why hide something in HTTP headers, that the client is explicitly querying, right?

Resources