Jotform webhook not accepted by Replit

*Are there rules or limitations to how Replit allows webhooks?

**I’m trying to receive Jotform form submissions on a Flask app (on Replit). I’ve tested the webhook sent by Jotform and it works fine (for example, on webhook.site) but just not on Replit. It also works when I test it locally, and it works when I send the request from the shell in Replit development. It only can’t see the data when Jotform sends the data to Replit. In other words, it’s getting an error trying to read the very first field. So it’s looking like Replit, for whatever reason does not like the data that Jotform sends it.

How can I fix this?

Here is my flask code:

import logging
from flask import Flask, request
import contract
import extractions

# webhook = https://app-2-hankos.replit.app/webhook

# initialize flask app
app = Flask(__name__)


@app.route('/')
def home():
  # Simple route to verify the app is running
  return "Webhook listener is running."


# this is where webhook data is received
@app.route('/webhook', methods=['POST'])
def webhook_listener():
  if request.method == 'POST':
    # check if the incoming request is JSON
    if request.is_json:
      # parse the JSON data from the request
      form_data = request.get_json()
    else:
      # fallback for form-encoded data
      form_data = request.form

    # other code to manipulate data goes here

    # return an empty response indicating success
    return '', 204

  return "done"


if __name__ == "__main__":
  app.run(host="0.0.0.0", port=8080, debug=True)

The app logs:

02/27/24 09:10:37 PMFile “/home/runner/2b7f366a-d614-48c0-a574-af311f41d608/.pythonlibs/lib/python3.10/site-packages/werkzeug/datastructures/structures.py”, line 192, in __getitem__
02/27/24 09:10:37 PMdoc_data.update(extractions.client_full_name(form_data))
02/27/24 09:10:37 PMFile “/home/runner/2b7f366a-d614-48c0-a574-af311f41d608/.pythonlibs/lib/python3.10/site-packages/flask/app.py”, line 1469, in dispatch_request
02/27/24 09:10:37 PMrv = self.dispatch_request()
02/27/24 09:10:37 PMFile “/home/runner/2b7f366a-d614-48c0-a574-af311f41d608/.pythonlibs/lib/python3.10/site-packages/flask/app.py”, line 1484, in full_dispatch_request
02/27/24 09:10:37 PMrv = self.handle_user_exception(e)
02/27/24 09:10:37 PMresponse = self.full_dispatch_request()
02/27/24 09:10:37 PMKeyError: ‘q50_nombre50’
02/27/24 09:10:37 PMFile “/home/runner/2b7f366a-d614-48c0-a574-af311f41d608/extractions.py”, line 15, in client_full_name
02/27/24 09:10:37 PMFile “/home/runner/2b7f366a-d614-48c0-a574-af311f41d608/main.py”, line 35, in webhook_listener
02/27/24 09:10:37 PMFile “/home/runner/2b7f366a-d614-48c0-a574-af311f41d608/.pythonlibs/lib/python3.10/site-packages/flask/app.py”, line 2193, in wsgi_app
02/27/24 09:10:37 PMTraceback (most recent call last):
02/27/24 09:10:37 PMwerkzeug.exceptions.BadRequestKeyError: 400 Bad Request: The browser (or proxy) sent a request that this server could not understand.
02/27/24 09:10:37 PMraise exceptions.BadRequestKeyError(key)
02/27/24 09:10:37 PMname_output.append(data[“q50_nombre50”])
02/27/24 09:10:37 PMreturn self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)
02/27/24 09:10:37 PMFile “/home/runner/2b7f366a-d614-48c0-a574-af311f41d608/.pythonlibs/lib/python3.10/site-packages/flask/app.py”, line 1486, in full_dispatch_request
02/27/24 09:10:37 PMFile “/home/runner/2b7f366a-d614-48c0-a574-af311f41d608/.pythonlibs/lib/python3.10/site-packages/flask/app.py”, line 2190, in wsgi_app
02/27/24 09:10:37 PMresponse = self.handle_exception(e)
02/27/24 09:10:37 PMreturn self.wsgi_app(environ, start_response)
02/27/24 09:10:37 PMFile “/home/runner/2b7f366a-d614-48c0-a574-af311f41d608/.pythonlibs/lib/python3.10/site-packages/flask/app.py”, line 2213, in __call__
02/27/24 09:10:37 PM127.0.0.1 - - [28/Feb/2024 03:10:37] “[35m[1mPOST /webhook HTTP/1.1[0m” 500 -

Hi @hankos , welcome to the forums!
What are you connecting this app to? If /webhook has no place for the user/system to send a request, then the program may not work.

There is a route for that?

1 Like

Here is the full main.py. I should note that it work fine outside of Replit (locally or on a server). It only stops working when Jotform sends its Webhook to the app running in Replit; it does not receive the post data, but it is receiving the request.

import logging
from flask import Flask, request
import contract
import extractions

# webhook = https://app-2-hankos.replit.app/webhook

# initialize flask app
app = Flask(__name__)


@app.route('/')
def home():
  # Simple route to verify the app is running
  return "Webhook listener is running."


# this is where webhook data is received
@app.route('/webhook', methods=['POST'])
def webhook_listener():
  if request.method == 'POST':
    # check if the incoming request is JSON
    if request.is_json:
      # parse the JSON data from the request
      form_data = request.get_json()
    else:
      # fallback for form-encoded data
      form_data = request.form

    # logging.info(f"Received data: {form_data}")
    print(f"Received data: {form_data}")
    # create empty dictionary to store script output
    doc_data = {}
    # get form response data and store in doc_data
    doc_data.update(extractions.client_full_name(form_data))
    doc_data.update(extractions.client_contact_info(form_data))
    doc_data.update(extractions.site_data(form_data))
    doc_data.update(extractions.get_dates(form_data))
    doc_data.update(extractions.atendees(form_data))
    doc_data.update(extractions.responsable(form_data))
    doc_data.update(extractions.marketing(form_data))

    filename = contract.filename(doc_data)

    doc_data.update(extractions.signature(form_data, filename))

    # generate string to name new file and insert data into contract
    contract.contract_filler(doc_data, filename)

    # return an empty response indicating success
    return '', 204

  return "done"


if __name__ == "__main__":
  app.run(host="0.0.0.0", port=8080, debug=True)

Yes, the app stores the incoming json into a dictionary.

Could this have something to do with the way the app is deployed?

1 Like