External events work independently.
Where do you want to return the data as you can’t further process that data.
In case you need to see what’s the response you are getting from the HTTP request, you can print all the responses (success/error) at console and later see them at serverless logs (in case app is uploaded as custom app) or at command line (in case app is running locally).
But it seems to have a very small timeout, i.e., if you do anything on this event that takes some time, like a http request call and then set renderData(), it does not works anymore, the default value is returned before the call to renderData().
So the possibility to configure the timeout or have a higher timeout value, would be a very good feature!
Thanks for the detailed feedback for actively exploring the platform!
I am curious about the time taken for execution in your case. Currently, the timeout is at 20s. Can you help with the average time taken in your case? (if possible, feel free to add why it takes > 20s). This will provide more insights about the challenge you are facing
Unfortunately, at the moment, the timeout value is fixed and there’s little flexibility over modifying the response formats from within the onExternalEvent handler. We will consider the feedback reg the same
For timeouts, if it arises as a result of using $request for making REST API calls, it can be substituted with Axios/HTTP packages (the tradeoff would be the iparam templating feature). If the total time taken for onExternalEvent handler execution exceeds 20s, this is where the platform would enforce the time limit. This value is fixed at the moment however, we will be definitely interested in use-cases that require more processing/execution time.
We are looking for some opinions in order to make this feature request a reality.
Problem Statement
As we assessed the topics related to this feature request, we understood following
External Events feature for apps essentially generates a webhook URL that is registered with any 3rd party system. So 3rd party invokes webhook. webhook invokes a handler fn. handler fn executes and timeouts in 20s.
Developers like you want a way to run javascript (logic or REST API calls Methods) and finally communicate with 3rd party again. In this case, collect some ticket data and POST it to 3rd party system.
Currently when 3rd party invokes webhook, it only hears {success: true} from the app. But it would be nice to control the timeout so that the app can make API calls(with data) to 3rd party again.
Open questions
Is our understanding of problem statements correct?
Will providing the developers to control the timeout be sufficient? If yes, would ~ 30s seem a good number?
Since this topic has been open for a while now, how did you folks solve the problem?
Lastly, we want to hear a business use case on how this feature can help. So far we were able to understand from a technical perspective. Could anyone of you give an example?
At the time we reported this feedback, the behavior was:
The onExternalEvent fn itself has a timeout of 20s, but the return to the caller is almost right away, I mean, we found out that calling renderData(null, {field_one: 1, field_two: 2}); immediately after the onExternalEvent fn begins, we can return to the caller some custom payload. But if it take sometime doing something, like making a request api, setting renderData() after won’t work anymore, because it already has returned to the caller with just {“success”: true}.
What we want is the possibility to return to the caller some custom payload.
Usecase example 1: In a flow from Freshbots we want to create a ticket, but we can only do it after making some custom processing - since we cannot do it on the Freshbots, we could do it on the a app, calling the webhook.
Usecase example 2: In a flow from Freshbots I want to show the customer their tickets and let them select witch one them wants to see details. Using Freshchat widget this is possible using buttons. But if the bot is deployed in WhatsApp, we can’t use buttons. So we could call the webhook app to get the tickets and return to the bot s pre formatted list, like:
“Type the ID for the ticket you want to see details:
11245 - Ticket A
29865 - Ticket B
12378 - Ticket C”
Currently we are resolving these use cases building ourselves a middleware, using serverless or something else - you can see that this adds to much complexity to the solution, where a simple return from the onExternalEvent fn would solve the case.
The Advanced Automations app is now a framework of sorts, where you can possibly call another App’s external event.
But, since the externalEvent returns immediately without the possibility of responding with the custom payload, it is not possible to use the externalEvent in a meaningful way.
The requirement is simple: It is to allow externalEvent to return a promise with a custom payload.
And have generous limits to the timeout and the size of the payload that can be returned. FYI 100kb is definitely not sufficient.
OnExternalEventHandler(..) has execution timeout of 20 seconds. This doesn’t appear to be sufficient.
The payload size limit of 100 KB is not sufficient. I assume this is the payload size that will be sent to the app on external event occurrences. (Please correct me here otherwise)
@samuelpares, @arunrajkumar235 - Thank you for helping us understand this case. We are in a lot better position ideating on this. For the above two, can you approximate and let us know what could be the ideal limits that are sufficient for timeouts and size?
One of the things that stuck with us is - We are imaging external events as more like webhooks in the industry. Like Fire-and-Forget sort of thing. But in this case, this requirement can be a new avenue of opportunity.
As we continue our ideation on it, here are couple of learnings over externalEvents interms of custom response.
There is a configurable option in chatbots feature within Freshdesk Messaging. Based on couple of options that visitor selects in the chatbot, admin can wire it to make an API call to do any CRUD operations necessary for business case.
Likewise, chatbots has configurability to invoke a JS function. That means based on response from a visitor on the chat, admin can configure a 'JSON':'payload' to be sent and receive response. It can be translated to chatbot response to the visitor.
It is at #2, where it appears like external events features can evolved to return a promise or JSON response (unsure, because the system on receiving end might not necessarily await) so that chatbot observes it and traslates it into respose to a visitor chatting. Maybe at this point, current state of external events just returns "success": true
On a worthy note to be observed here is, if onExternalEventHandler() has more timeout runtime to be execute, the app may not know what API Endpoint to respond. That results in developer not knowing an endpoint to write a line of code that makes a needed request to originator who actually triggered the webhook.
@Saif , the execution time fo the ExternalEvent is 20s. That is sufficient for most use-cases. But, it does not allow us to return a promise. Currently, it behaves synchronously. We want to behave asynchronously.
Also, regarding the payload, currently it does not allow us to return any payload. All I’m saying is, when you do allow the externalEvent to return a payload, do not restrict it to just 100kb. FYI, current size of the payload that ExternalEvent can return is 0.
The facility to delay the returning of the function is available in all other events like Product Events, SMI functions, onInstall, onUninstall using the renderData() method. The same treatment is not available for the onExternalEvent callback.
Also, it makes it impossible to write automated tests without the onExternalEvent method returning any data. My externalEvent test cases are a blind shot currently.
Whether anyone has a use-case or not is immaterial. These are basic requirements of cloud functions: to be able to return a promise with a payload.
Current
Expected
Execution Time
20 seconds
No change
Incoming Requests Rate Limit
250 / minute
No change
Incoming Request Payload Size
128 KB
Do not have any limits (if possible). If not, keep more generous limits like 10MB.
Returns
Immediately
Promise (asynchronous)
Return Payload Size
Zero (since it does not support returning anything at all currently)
Do not have any limits (if possible). If not, keep more generous limits like 10 MB.
My use case for being able to return a value is this:
We Implement a Flow that does the following:
User Submits Microsoft Form
Flow submits a webhook to FreshSales Serverless app.
FreshSales serverless app creates a Custom Module Record
We need to get a Custom Module Record ID back (in order to perform update further down in this Flow)
System sends Microsoft Approval Email (approval email allows an executive type person to click either “Approve” or “Reject” and type a comment right in the email).
The Flow uses the ID that it got back in Step 2 to submit another webhook call to FreshSales Custom Module Serverless App to update the status of the request
This flow depends upon getting back the ID for the Custom Module record that was created in order to update it in the subsequent step in the flow.
I have a workaround to the problem which is to send a randomly generated unique ID from the Microsoft Flow and put that into the custom module record custom field. And then to update we first need to search for that custom module record containing the randomly generated ID and then perform the update. Its just more work and it would be nice not to have to do so.
Hi @Saif, is there any development in this request?
Today I have another use case. An integration between Freshdesk and ServiceNow - they will create tickets in Freshdesk and need to receive the response with the ticket ID. The issue is that it involves financial institutions customers and they don’t want to give away the API Key to the third party, what would allow them to access the companies and contacts information, since in Freshdesk we don’t have an access scope to it. So if I could return a payload from external event, it would resolve this case. Since this is not possible, I would need to create a middleware, et cetera…