Webhook 400 missing client secret

Hello everybody,

I’m currently developing a connector for opsdroid (an open-source python bot) and having some issues with webhooks. I’ve generated my OAuth as expected and I can query the API and also join the IRC servers with my tokens.

I’m currently trying to use webhooks to get other events that can’t get through the chat (like broadcaster went live).

We have the webserver running and the bot is exposed to the internet as well. We use aiohttp for the webserver and I’m trying to do the initial post to the endpoint like this:

followers_topic = f"https://api.twitch.tv/helix/users/follows?to_id={user_id}&first=1"
        
        headers = {'Client-ID': self.client_id, 'Authorization': f"Bearer {self.token}"}
        data = {
            "hub.callback": 'https://REDACTED/connector/twitch/follows',
            "hub.mode": 'subscribe',
            "hub.topic": followers_topic,
            "hub.lease_seconds": 60 * 60 * 4,
        }
        
        async with aiohttp.ClientSession() as session:
            response = await session.post(TWITCH_API_ENDPOINT, headers=headers, data=data)

But every time I keep getting a status “400 - missing client secret” error. Nowhere In the documentation says we need to pass the client secret when attempting to subscribe to a webhook so I’m doing something wrong.

Any idea what that could be? I’ve seen the source code of a lot of libraries that use webhooks to connect to twitch and none use the client secret to subscribe to the webhook :thinking:

Any help would be greatly appreciated.
Thank you so much!

That is an odd error to get, however you didn’t JSON encode your data parameters, you just posted as a form.

The hub expects a JSON blob to be posted, or the parameters passed as query string arguments (undocumented). You did neither and sent as post data.

So you didn’t tell the hub to do anything!

Also I’m assuming that TWITCH_API_ENDPOINT is https://api.twitch.tv/helix/webhooks/hub

When testing your logic (posting as a form), I get

{
  "error": "Bad Request",
  "status": 400,
  "message": "Must provide a valid Content-Type header with a request body. Please use application/json or application/x-www-form-urlencoded"
}

As I was expecting, so you need to Post as query string or JSON blob, not multipart

So you got a completely unexpected error, and your hook creation code is incorrect.

Thank you so much for the help, I feel pretty dumb but yeah by sending the same post request with json instead of data fixed the issue since aiohttp will send it as a JSON blob.

Sorry for taking your time with this!

S’all good here to help and/or rubber duck