Dialogflow ES re-sending request to webhook when TIMEOUT

315 views Asked by At

Since about a week ago all my agents are sending a second duplicate request to my webhook (which is a GC HTTP Function) within milliseconds of sending the 1st request and thus making my webhook process the request twice. These duplicates even share the same responseId.

I'm aware that Dialogflow ES agents wait up to 5 seconds for the webhook to response or it will throw a time out error. However to my knowledge it did not re-send the request on a timeout error:

  "webhookStatus": {
    "code": 4,
    "message": "Webhook call failed. Error: DEADLINE_EXCEEDED, State: URL_TIMEOUT, Reason: TIMEOUT_WEB."
  }

I tried using cache (npm node-cache) to check if the responseId has already been processed but it didn't work because the duplicate request is sent before I'm actually able to finish processing the first one so the responseId is not cached.

Is anyone else experiencing this? If so, how are you handling the duplicate requests? Are there any settings that may be causing this that I'm missing?

1

There are 1 answers

0
Swid On

I had the same problem for about a week. When a triggered webhook reaches the timeout of Dialogflow ES (5 seconds), it is executed again.

Previously, Dialogflow returned an error after the timeout (as described above by @mg1994), but provided the text response of the intent in the UI. So it was possible to output this message and then, as soon as the webhook was completed, send its response delayed via push to the UI.

I also don't see any way to cancel or otherwise intercept the second call.

For example, here is a very simple webhook to test for a duplicate request.

    const express = require('express');
    const app = express();
    const PORT = 3033;
    
    const delay = (milliseconds) =>  new Promise(resolve => setTimeout(resolve, milliseconds));
    
    app.post('*', async (req, res) => {
    
        const d = new Date().toLocaleString();
        console.log(">>> Webhook", d);
        await delay(5000);
    
        res.status(200).json({ fulfillmentText: `Sorry, I'm not able to help with that (${d}).` });
        res.end()
    });
    
    app.listen(PORT, () => {
        console.log(`Server is up and running at ${PORT}`);
    });

Anybody had the same experience and have any ideas?