0

Facebook messenger api requires a 200 response be sent as soon as the webhook request is received on my server, within 20 seconds. This is potentially longer than the rest of the middleware needs to finish executing, so I send the 200 response first, then start executing middleware to handle sending a reply on messenger etc.

However, this breaks Jest, as the middleware continues to output to the console after the response is retrieved from the jest mock function. There is no way I can think of to send multiple responses with res.send(), as that calls res.close() internally.

Is this the correct approach? Should I not be sending the 200 response instantly? Is there a way to send multiple?

I have tried using res.write(), but that does not send the response instantly.

private webhookEndpoint = async (req: express.Request, res: express.Response): Promise<any> => {
        let body: MessageBodyRequest = req.body
        if (
            !isValidSHA1(
                process.env.APP_SECRET as string,
                JSON.stringify(req.body),
                req.get('X-Hub-Signature') as string
            )
        ) {
            console.error("Invalid webhook signature")
            return res.sendStatus(403);
        }

        // Checks this is an event from a page subscription
        if (body.object === 'page') {
            // Returns a '200 OK' response to all requests
            res.status(200).send('EVENT_RECEIVED')
            // Iterates over each entry - there may be multiple if batched
            try {
                //await triggers the try catch
                return await Promise.all(body.entry.map(async (entry) => {
                    let message = entry.messaging[0] //will only ever have 1 message
                    console.log("message received: ", message)
                    let messageReceived = new MessageReceived(message)
                    return messageReceived.handle() 
                }))
            } catch (error) {
                console.error("Error handling incoming message: ", error)
            }

        } else {
            // Returns a '404 Not Found' if event is not from a page subscription
            return res.sendStatus(404)
        }
    }
skyboyer
  • 22,209
  • 7
  • 57
  • 64
God Himself
  • 209
  • 1
  • 4
  • 15
  • Could you add the test as well? Also, you mean break because continuing to execute? because if thats the behavior, then you should expect for that console print as well. – Coding Edgar Jul 31 '19 at 03:05
  • A HTTP request can have multiple 'responses', but the responses all have statuscodes in the 1xx range, such as 102 Processing. https://stackoverflow.com/a/53231701/395461 – Shannon Matthews Jul 31 '19 at 05:17
  • What is your middleware doing that it could take longer than 20 seconds to process? Can you reduce that somehow? – Shannon Matthews Jul 31 '19 at 05:18
  • @Shannon things like sending videos take a long time to await – God Himself Jul 31 '19 at 15:41
  • Possible duplicate of [Are multiple responses legal in HTTP?](https://stackoverflow.com/questions/53231492/are-multiple-responses-legal-in-http) – Shannon Matthews Aug 01 '19 at 01:51

1 Answers1

0

From what I understand, it's not possible to send multiple responses per request, unless sending a 100 Continue response. See the W3 HTTP protocol documentation for more info.

Shannon Matthews
  • 9,649
  • 7
  • 44
  • 75