How to return the response from $request.post back to the caller in onExternalEventHandler

I am testing an externalEventHandler that would create a ticket in FreshService and return the ticketID back to the caller. I have browsed through a lot of serverless sample apps in GitHub - they all use console.log to log the response from the API, but I want to return the response back to the caller. I found renderData to be the way and here is how I am using it, but it is resulting in error.

Here is the relevant portion of the code…

onExternalEventHandler: async function (args) {
    var remote_url = "https://something";
    var options = {
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(args.data),
    };
    $request.post(remote_url, options).then(
      function (data) {
        //"data" is a json string with status, headers, and response.
        console.info("response back at: " + Date());
        console.info(JSON.stringify(data.response, null, 4));
        renderData(null, {
          success: true,
          data: JSON.stringify(data.response, null, 4),
        });
      },
      function (err) {
        console.info("error back" + JSON.stringify(err, null, 4));
        renderData(null, { success: false, error: err });
      }
    );
  }

the ticketID is printed in the console properly. but it is not returned to the caller. Instead I get this error in the console. Can someone tell me what I am doing wrong? I tried converting the then blocks into synchronous using await and even tried the axios package, but all result in the same error

1 Like

Hi @siraj.samsudeen,

It’s not possible to return a custom response from the External Events. It always returns a constant response to the sender.

Please check this thread.

@siraj.samsudeen,

There is something I am not getting correctly.

The External Events feature of the App platform lets your app generate a webhook and register the webhook with a 3rd party system. When 3rd party system does make a POST API call to the generated webhook the handler tied to onExternalEvent (usually labeled onExternalEventHandler) is invoked and POST data or iparams are passed as arguments to its execution context.

Now coming to your question, what I can refer to is; you need to grasp the ticket ID and POST to https://something. You can do this using the Product event. For example onTicketCreate is a product event that can POST to http://something with the ticket ID of the ticket that’s just created.

However, if there’s any other hypothesis or elements about your use case of yours that I missed grasping, please elaborate?

1 Like

Thanks a lot @Raviraj for the immediate response and the linked thread, which pretty much spelled out the various trials I have done. I would respond to Saif with the details of my business case as this is very limiting.

1 Like

@Saif - thanks a lot for the immediate response and the thoughtful explanation. Let me explain my usecase.

I have an external system (SAP ERP) which needs to create tickets in the FreshService as we want to use FreshService as the single system for all communication with offices. So, that external system will be sending a ticketCreate request through this onExternalEvent and we need to respond back with the ticket ID and ticketURL which is then stored in that system.

Now, you may ask - why did we not use ticketCreate API to create ticket and return? We have a number of external systems that we will be integrating and we did not want each of those systems to do all the freshservice SDK-related formating, etc. - hence we have created a 3rd party broker app using Autocode platform - this broker takes the request from the SAP system, does some prepping of data and then calls the ticketCreate API and returns the response.

Now, I am trying to see whether we can move this broker to FreshService itself - so, onExternalEvent will receive the response from SAP system and need to respond back with a ticket created. So, that http URL that I have masked is an URL to the external Node.JS code which returns a ticketID and ticketURL - I need to pass it back to the caller. I am doing as a Proof-of-Concept to see whether we it is possible. Eventually, the ticketCreate call will happen inside onExternalEvent and we need to return the response.

So, our plan to move from that 3rd party broker to freshservice SDK is NOT possible :slight_smile:

1 Like

Hmm. Thank you for the elaboration. I think I get it.

App platform is supposed to be a broker. If it isn’t helpful right now, we should probably bring it to @Product-Managers attention so that the app platform can be beneficial in the future.

So overall, it looks like the follows: (please correct me if I’m wrong)

  1. SAP invokes onExternalEventHandler by having an app’s webhook registered.
  2. Within the execution context -
    2.1. API call should be made to Create Ticket API and store the response into a runtime variable - ticketID.
    2.2. API call should send ticket ID and ticket URL back to SAP
  3. Exit. No renderData(..) required.

My questions would be:

  1. Is my understanding of your problem is correct?
  2. At 2.2, I assume you basically refer to as caller. Is there a reason why we shouldn’t make an additional API call to SAP; but we instead expect caller to receive {success: true, speakBackData} which currently only gets {success: true}

Yes your understanding is perfect.

Whenever someone makes a call, we need to return the correct ticketID so that the caller knows which ticketID corresponds to which item in their system. If we have to make a API call again, they have to expose a webhook and all the associated issues.

Even in your example of JIRA to FreshService, I feel that JIRA should display a hyperlink to the FreshService ticket so that someone can click and land on the correct item (knowing that it is synched is not enough).

My use case for being able to return a value is this:

We Implement a Flow that does the following:

  1. User Submits Microsoft Form
  2. 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)
  3. 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).
  4. 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.

1 Like