Autodesk Data Management webhooks firing events two times? - autodesk-forge

I'm receiving two similar events in my server. I'm sendig a response with status 201, but it doesn't solve the problem (after that, i was receiving 4 similar events). The only difference between the events are two fields in the headers (X-Adsk-Delivery-Id and X-Forwarded-For).
The events are received exactly at the same moment (less than a second of difference).
It's by default launching two events?
Thank you for your help.

Did you send a 2xx response immediately when you receive the callbacks?
Our service would send another callback if it doesn't get a response within 6 seconds so if you got other workflows to finish before sending responses be sure to process them asynchronously.
See here for details:
Webhooks guarantees at least once delivery. When the event occurs, the webhooks service sends a payload to the callback URL as an HTTP POST request. The webhook service expects a 2xx response to the HTTP POST request. The response must be received within 6 seconds. A non-2xx response is considered an error. In the event of an error, the webhook service will retry immediately, in 15 minutes, and 45 minutes thereafter. The webhook service retries for 48 hours and disables the webhook if the callback does not succeed during this time. You may need to reconfigure your webhooks if they are disabled.

Related

How does a server process multiple API requests at same time?

Given the following situation:
Server receives API request from client A.
Server starts processing API request
Server receives API request from client B.
(What happens here?)
What happens in step 4?
My understanding is that, since the server is busy processing the first request, it won't even respond to the second request. To expand: I am picturing the application idle waiting for a request, but when it receives the first request (from client A), the application starts processing it and therefore is unable to even receive the second request.
I am assuming this is incorrect, but if someone can provide a detailed explanation of what happens in this situation, that would be very enlightening.

Problem creating a Strava webhook subscription using Google Apps Script

EDIT 2 - I have now provided my own answer to the issue - any further thoughts or inputs would still be appreciated
EDIT 1 - POTENTIAL RELEVANT INFORMATION:
I've found this footnote at the bottom of the Content Service documentation page that says:
For security reasons, content returned by the Content service isn't served from script.google.com, but instead redirected to a one-time URL at script.googleusercontent.com. This means that if you use the Content service to return data to another application, you must ensure that the HTTP client is configured to follow redirects. For example, in the cURL command line utility, add the flag -L. Check the documentation for your HTTP client for more information on how to enable this behavior.
This seems relevant as I am using ContentService to serve data to Strava's GET request - would this not mean that the response it receives comes from a different URL and hence not from the specified callback URL?
I've been trying to use Google Apps Script to create a webhook subscription to Strava and I feel like I'm extremely close to figuring it out, but I've encounter one last hurdle that I can't seem to pass.
The documentation for creating a webhook subscription to Strava is listed here and I've reached the stage at which I'm making a POST to the Strava API requesting a subscription. Strava then sends an HTTP GET request to my callback_url that I've specified which contains some parameters - most important of which is the hub.challenge parameter. This param must then be sent back within 2 seconds by my callback address in order for the link to be validated. This is where I'm having some grief.
function doGet(e) {
var hubChal = e.parameter["hub.challenge"];
var result = {
"hub.challenge": hubChal
};
return ContentService.createTextOutput(JSON.stringify(result))
.setMimeType(ContentService.MimeType.JSON);
}
Above is my current function that is dealing with incoming GET requests.
In the documentation it states:
Your callback address must respond within two seconds to the GET request from Strava’s subscription service. The response should indicate status code 200 and should echo the hub.challenge field in the response body as application/json content type: { “hub.challenge”:”15f7d1a91c1f40f8a748fd134752feb3” }
However, when I send the POST to the webhook subscription API I receive this response on Postman:
{
"message": "Bad Request",
"errors": [
{
"resource": "PushSubscription",
"field": "callback url",
"code": "GET to callback URL does not return 200"
}
]
}
I checked through the troubleshooting advice that is offered on the doc page, an element of which gives a sample GET request for you to send yourself to see what your callback address offers in return:
Check that the response to the above request shows a 200 status and correctly echos the hub.challenge in the JSON body. The response body to the above sample curl request should look like { “hub.challenge”:”15f7d1a91c1f40f8a748fd134752feb3” }
With the following dummy GET request:
{your-callback-url}?hub.verify_token=test&hub.challenge=15f7d1a91c1f40f8a748fd134752feb3&hub.mode=subscribe
Plugging in my callback url and sending a GET request via Postman returns the following to me:
{
"hub.challenge": "15f7d1a91c1f40f8a748fd134752feb3"
}
Along with showing a 200 OK Status code and in well under 2 seconds.
I really can't see what I've done incorrectly here, as it seems like I'm fulfilling the criteria laid out to set up a subscription. It's worth mentioning that I'm not very familiar with Google Apps Script, so it's entirely possible and even likely that I'm missing something basic, but I can't see it for the life of me.
I've gone through all of the troubleshooting advice and haven't been able to find an answer online despite an entire afternoon and evening of searching yesterday. Any help would be enormously appreciated - thanks.
I believe I've finally figured out my issue and unfortunately it seems it is not possible to set up a webhook subscription to Strava using Google Apps Script - at least not whilst using ContentService to serve data to Strava GET requests.
At the end of the ContentService documentation it says:
For security reasons, content returned by the Content service isn't served from script.google.com, but instead redirected to a one-time URL at script.googleusercontent.com. This means that if you use the Content service to return data to another application, you must ensure that the HTTP client is configured to follow redirects. For example, in the cURL command line utility, add the flag -L. Check the documentation for your HTTP client for more information on how to enable this behavior.
The problem with this is that Strava expects and will only accept a 200 status code attached to the response to its GET request, however ContentService sends a 302 redirect to this one-time URL. I was able to verify this in Postman by turning off "Automatically follow redirects" in the request settings of my dummy GET request:
https://i.stack.imgur.com/vAvIm.png
Since I have auto redirect enabled by default on Postman, I wasn't seeing the 302 at any point when sending my own requests, leading to everything appearing to be in order.
If there is a way around this ContentService issue then please do inform me, as the outcome of this is that I'm now going to have to poll Strava for new data (booo) which will make my finished product significantly more clunky.
Hopefully this post will now stand to help anyone else who finds themselves with my issue in the future and will save them a few days of confusion!
I am not familiar with Goole Apps Script (very cool, by the way!), but it sounds like you have Strava webhooks well understood.
It sounds like your doGet method is returning something other than 200. Do you have a logging feature that can output what the doGet method is being sent, what it's sending back, etc?
If you haven't already, you may want to check out the Strava tutorial on subscribing to webhooks using Node, Express and Ngrok. A few extra steps, but fairly easy to follow and debug.

Bim360 api - 429 - too many requests

We have desktop and mobile app (2 different client id) integrated with bim360 api. We have a problem with 429 error responses. Documentation: https://forge.autodesk.com/en/docs/data/v2/developers_guide/rate-limiting/ doesn't give us a lot of details.
How does it work? How can we avoid it?
What will happen if 1000 different users from apps with the same client_id at once try to get issues list? Will it be distinguish as Ddos? Are hubId, projectId, user account, ip address considered in rate-limiting algorithm?
As I know, each API has a well-configured rate-limit per minute per client id. After reaching the limit, you will see a retry-After parameter appears in the response header of each of your API call. It stands for the retry time when you can call the API again, and the unit of this value is in second. You can schedule a retry task along this retry time in your code.
Note. The value of the retry-After will reset if you make another call before reaching the Retry-After duration.
Hope it help, Cheers!

What is ErrorMessagePerFolderCountReceiveQuotaExceeded?

I'm synchronizing Office 365 mail folders via the Office 365 REST API by doing a GET on me/MailFolders/{folder_id}/messages. For two different accounts, I've recently been getting 500 responses to these GETs with the error code ErrorMessagePerFolderCountReceiveQuotaExceeded and error message "The number of received messages has exeeded the quota for the folder." (Typo theirs, not mine.)
I can't find any documentation on this error. What does it mean? What should I do to fix this situation?
I couldn't seem to find any documentation for it either.
From the error message, it seems it might be related to the "Maximum number of messages per mailbox folder" limit on Exchange Online. Do you know if the folder contains 1M+ messages?
https://technet.microsoft.com/en-us/library/exchange-online-limits.aspx#MailboxFolderLimits
I guess my other idea would be that you're getting too many messages in too short of a time period. Suggestion would be to use the endpoint GET https://outlook.office365.com/api/v2.0/me/MailFolders('{folder_id}')/messages with $deltaToken and $skipToken to skip previously synced messages.
https://msdn.microsoft.com/en-us/office/office365/api/mail-rest-operations#synchronize-messages
When you do a sync to an Exchange folder via the Outlook REST API, you pass it a sync token. In response, the API returns a new sync token and a set of changes. And the client is expected to send the new token back with their next sync request.
With most systems that support sync, using a stale sync token (i.e. one that has been sent to the server once) in a subsequent request will generally just succeed with no problems. And Exchange appears to work like that... for the first 999,999 times you do it. On the 1,000,000th time (and each time thereafter), you get ErrorMessagePerFolderCountReceiveQuotaExceeded. This is (I think) because Exchange keeps track of each token that it's given out and updates the token in its store each time it's used for sync. If a client uses a stale token, Exchange views it as a new client and adds that stale token as a new entry in its list of active tokens. That active token list can have at most 1,000,000 entries. ErrorMessagePerFolderCountReceiveQuotaExceeded is the cryptic error indicating that Exchange's active token list has overflowed.

Chrome Google-Cast sender not receiving media status updates on original media load

I've been working on both the receiver and web sender (Chrome) apps for Chromecast for a while, and since the new API (publicly released yesterday) I've been unable to receive any media status updates after performing a loadMedia request.
Upon refreshing the page, I am able to receive the updates as expected, but both channels receive the media session object the exact same way and perform the exact same methods upon it (addUpdateListener)
We're working with an HLS stream on the receiver side, but I can see updates being sent out to the senders (and obviously they are, as a reload allows the web sender to receive them). Also, on the sender side, I can see updates when I perform actions such as play/pause/volume/mute and seek requests, but only one update after each action.
TL;DR: Don't see any regular media status updates for events such as loading->buffering->playing, and I also don't even see the play/pause/volume/etc updates from other senders connected to the session.
Here's all I get from the sender before it just stops sending any status updates:
[chrome.cast.ApiImpl] Getting message from extension:
{"type":"v2_message","message":{"type":"MEDIA_STATUS","status":[{"mediaSessionId":1,"playbackRate":1,"playerState":"BUFFERING","currentTime":500,"supportedMediaCommands":15,"volume":{"level":1,"muted":false},"media":{removed}","streamType":"buffered","contentType":"contentType","metadata":null,"duration":1450.1558329999993,"customData":null},"sessionId":"FD5AA3F0-F93C-050A-4900-7C6D916525BA"}],"requestId":92278937},"seqNum":"a14772002","clientId":null,"appOrigin":null}
[chrome.cast.ApiImpl] Creating new Media object:
FD5AA3F0-F93C-050A-4900-7C6D916525BA:1 cast_sender.js:3428 New media
session ID: 1 (loadMedia)
But I can tell that the receiver is still sending out updates by looking in the debug console, there's a bunch of these firing off:
[245.485s] [cast.receiver.IpcChannel] IPC message sent:
{"namespace":"urn:x-cast:com.google.cast.media","senderId":":","data":"{\"type\":\"MEDIA_STATUS\",\"status\"
...removed [247.495s] [cast.receiver.MediaManager] Sending broadcast status message
I've also noticed that when I do get messages prior to the loadMedia callback, they're all in the BUFFERING state, never a PLAYING
This bug is confirmed and it has been fixed as of Feb 10 update of Cast extension.
Old workaround:
For now there is a workaround for this type of issues where status updates from receiver apps are routed to Chrome Cast extension but not getting routed to the Chrome sender apps.
The trick for now to see incoming status updates from receiver apps is to open up at least 2 tabs that run the same sender app. You initiate a session from one of the tabs and then join that session from the other tab. Now any status update messages from receiver app will not be intercepted by the Cast extension anymore.
I see this bug has been fixed with Feb 10 update, however I am not seeing currentTime event. From the docs -
Changes to the following properties will trigger the listener: currentTime, volume, metadata, playbackRate, playerState, customData.
Should we expect to get an update when the time changes?