Flask 405 error when post are allowed

So I was trying to learn about webhooks and thought using eventsub from Twitch api.

Everything works fine but when you subscribe to a event twitch first send a verification challenge request to the port 443. The problem is when it arrives flask shows in the console a post 405 error.

from flask import Flask, Response, request
import twitch

app = Flask(__name__)

# Subscribes to the event, works fine, if you ask for the list of subscriptions it shows but with verification error
twitch.eventsub_subscribe(twitch.user_id, "channel.update") 

@app.route("/")
def hello_world():
  return f"<p>Hello, World!</p>"


# Here is where it arrives (and where 405 error shows)
@app.route("/eventsub/callback")
def callback(method=["GET", "POST"]):
  print(request)
  return Response(status=200)


app.run(host="0.0.0.0", port="443")

You are not correctly specifying that Flask can handle both GET and POST requests.
Instead of placing method=["GET", "POST"] inside the function, it should be passed as an argument to the @app.route() decorator.

Also you need to properly handle the POST request by checking for the Twitch-Eventsub-Message-Type as said in Twitch documentation:
“Challenge messages set the Twitch-Eventsub-Message-Type header to webhook_callback_verification.”

from flask import Flask, Response, request, jsonify
import twitch
import json

app = Flask(__name__)

# Subscribes to the event, works fine, if you ask for the list of subscriptions it shows but with verification error
twitch.eventsub_subscribe(twitch.user_id, "channel.update") 

@app.route("/")
def hello_world():
  return f"<p>Hello, World!</p>"

@app.route("/eventsub/callback", methods=["GET", "POST"])
def callback():
    if request.method == 'POST':
        notification = request.json
        msg_type = request.headers.get('Twitch-Eventsub-Message-Type')
        
        if msg_type == 'webhook_callback_verification':
            return Response(notification['challenge'], status=200)
    else:
        return Response(status=200)

app.run(host="0.0.0.0", port="443", ssl_context=('cert.pem', 'key.pem'))

Try to see if this works.

6 Likes

Thanks I can see my mistake now, however I don’t know anything about ssl so I can’t fill the ssl_context (FileNotFoundError). I deleted it and the 405 error is still there, I guess because of the lack of ssl_context (I don’t really know). Anyways, thank you so much for the help, but I will leave this project for a future when I learn about ssl.

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.