Chatbot webhooks
2023-11-23
I once wrote a webhook for a Messenger chatbot. The project was more difficult, algorithmically, than I thought it would be. This meant that the web requests that Messenger sent to my webhook would take some time to respond -- meaning, in turn, that Messenger would assume an error on my end and re-send the message.
This would have been bad. Each request sent to the webhook would have triggered the handler function, and each invocation of the handler function could have sent a message to the user. This would have gotten our chatbot reported and taken down quickly, but we caught this in testing.
At the time, the way we dealt with this behavior is by checking a cache for the request ID before performing any effects. This method works, and it satisfies the webhook request. Beware race conditions: this method seemed to work fine for us because we used the atomic SET (with GET) operation of Redis, but it was always a concern in the back of my mind.
The other way to deal with this is to fire off a background job and return HTTP 200 immediately. Since the webhook might not require a substantive HTTP response, you can delegate any effectful code to the background job. Depending on your language of choice, firing off a background job might not be that easy (cough Python), but I think I would prefer this method now since it doesn't require an additional server like Redis. I'm mostly a Python guy, but I'd like to look into how well Go or Elixir would handle this background job method.