[PubSub] inconsistent datatype for userInput of Channel Points Event Message

The datatype of the optional userinput for Channel Points Event Message is just a string, but it really should be an “sub_message” datatype since user can input the emotes into the user input within the reward for the channel points.

As I can see on the another examples of the docs such as Channel Subscriptions Event Message, it has the sub_message datatype, hence the inconsistent datatype.

The ideally outcome of json response of Channel Points Event Message should be like this (see the userinput field as it is in sub_message datatype and I have tried to make this so it is focused on the datatype itself than bloated data):

"type": "reward-redeemed",
"data": {
  "timestamp": "...",
  "redemption": {
    "id": "...",
    "user": {
      "id": "...",
      "login": "",
      "display_name": ""
    "channel_id": "...",
    "redeemed_at": "...",
    "reward": {
      "id": "...",
      "channel_id": "...",
      "title": "say something on stream",
      "prompt": "talking bot \n",
      "cost": 10,
      "is_user_input_required": true,
      "is_sub_only": false,
      "image": {
      "default_image": {
      "background_color": "#00C7AC",
      "is_enabled": true,
      "is_paused": false,
      "is_in_stock": true,
      "max_per_stream": { "is_enabled": false, "max_per_stream": 0 },
      "should_redemptions_skip_request_queue": true
    "user_input": {
        "message": "A Twitch baby is born! KappaHD",
        "emotes": [
            "start": 23,
            "end": 7,
            "id": 2867
    "status": "FULFILLED"

I am not sure if I should reported this as well in the Issues · twitchdev/issues · GitHub, but please let me know if I should. It is not a docs issue, but an pubsub issue.

For the reference, I am using pubsub because of twitchlib.pubsub in a C# project and cannot moved to eventsub.

Given the announced removal of PubSub from third party usage the recommendation is to move to eventsub

You can find the relevant topic here:


Ones with user input can also be retrieved from


Yeah… thank you for let me know about the announcement of the legacy pubsub, Barry.

I already am aware that the pubsub is deprecated. It is easy to say that I should moved to Eventsub (which I agreed that I should), but I have yet to find C# examples from twitchlib that would works in similar manner as pubsub examples. So that is stopping me from moving to eventsub (beside there arent a lot of twitchlib docs about eventsub, but that is another problem that I have to resolved later)

Also I noticed that channel.channel_points_custom_reward_redemption.add is still having the same inconsistent datatype for its userinput for eventsub.

Perhaps it would be easier to explained my use case, so it makes sense to see what the end goal is?
I have users who submitted emotes in the userinput within the custom reward, and the data (userinput which is just a string) doesnt tell me where the emotes are in the string (however in the example of sub_message; the data do tell where they are in the string, which was why I want it to be ideally result for the userinput.). The reason for the use case? So I can filtered the emotes from the userinput and displayed it as an normal text without the emotes, since it is being reading by a TTS bot that I wrote myself.

Also curious question, but I dont see how I can chained between these two topics to get the result that I needed?
I do noticed that channel.chat.message have an channel_points_custom_reward_id field, but it feels like a dirty hack to listen twice (one for channel point redeemed, and another one for the message) in order to find the emotes within the userinput from channel.channel_points_custom_reward_redemption.add?
Not to mention how would that even work logically in a flow?

Well EventSub over Websockets is basically the same as pubsub.

Just instead of LISTEN sends over the socket you use the HTTP API to create subscriptions.

In psuedo code

if channel.channel_points_custom_reward_redemption.add and reward has NOT user input
else if channel.chat.message and is reward

As channel.chat.message will give you the fragments to ignore emotes.

You’ll still need to parse out and remove third party emotes from things such as BTTV and FFZ.

So you can either:

  • consume rewards that have user input from redemption.add and parse out emotes manually
  • consume rewards that have user input from chat.message and the emotes are parsed out for you

We can hope that the other topics that handle in part a chat message, such as channel.channel_points_custom_reward_redemption.add get fragments in a v2 but who knows. Probably needs a uservoice.

it is what I will be doing when I complete my migration work. Since my chatbot will be consuming the messages send in a chat room for moderation reasons as well so I need both topics for various use cases

Since I’ll probably fine tune my subscriptions to channel.channel_points_custom_reward_redemption.add for a specific reward rather than all rewards and pipe to the relevant handler functions.

The second option is very likely that I have to do, but the only issue that I see with the first one is that I have to manually catch every emote’s names into the parser. I am not focused on the BTTV and FFZ. This is just alone for the twitch emotes. And there are a ton of the combinations of names for the emotes which would just be an massive array that need to be feed to the parser, and with BTTV & FFZ even more. So It is better to have it parsed the twitch emotes for me which is the second option that you mentioned.

Oh, I agreed. I do hope the devs can see the need of having the fragments in the channel.channel_points_custom_reward_redemption.add for the next version, so yeah. I will try to make a user voice about this eventually when I got eventsub working or at least an attempt on it. :sweat_smile:

Thanks for the replies btw. I’ll try to look deeper into the eventsub and try it out to check if it is possible or if I actually need to make an user voice about this.

yeah it should be straight forward and a little easier, no more nested JSON string/objects :stuck_out_tongue:


1 Like