Then, my app requests an app access token. Validating this one:
> curl -X GET 'https://id.twitch.tv/oauth2/validate' -H 'Authorization: Bearer wvsi...'
{"client_id":"mvkpu...","scopes":null,"expires_in":4794596}
Then, I try to subscribe to EventSub channel.chat.message with this client id mvkpu... and bearer auth using the access token. However, that keeps returning
What could I be doing wrong? The user access token scopes should allow subscribing to channel.chat.message as far as I can tell. The Client Id matches between the user access token and the app access token.
This sounds like you are trying to use conduits or webhooks, for eventsub know the transport is important information.
This suggests you didn’t get permission from the broadcater to be present or you are a not a mod of the broadcaster in question that you are trying to join.
Straight websockets
user token from the user you want to read chat as with user:read:chat
Webhooks or Conduits
Generate a user access token for the user to read chat as (with user:read:chat and user:bot), and moderator permission, then generate app access (no scopes)
user:read:chat from the user account you wish to read chat as (usually the bot)
user:bot from the user account you wish to act as a bot as
moderator status in the channel you wish to connect to
or
Generate a user access token for the user to read chat as (with user:read:chat and user:bot), and a second user access token from the broadcaster of the channel you want to be (with channel:bot), then generate app access (no scopes)
user:read:chat from the user account you wish to read chat as (usually the bot)
user:bot from the user account you wish to act as a bot as
channel:bot from the channel you wish to connect to
You have shown getting a user token channel:bot which is needed for the broacaster token