Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handling a bot that can view events on a different channel (2 different twitch accounts) #24

Open
jitspoe opened this issue Jul 12, 2023 · 5 comments
Assignees

Comments

@jitspoe
Copy link

jitspoe commented Jul 12, 2023

So this is more of a request/discussion than a bug, but I was attempting to create a bot that would sit in my channel and have responses as the bot name but also respond to events like point redeems and follows to my channel. It seems like the only way to do this is to have 2 different authentications: one from my twitch, and one from the bot's twitch. The follow notifications worked by having the bot as a moderator, but it seems like other events don't have that functionality.

So I effectively, I set up 2 different scopes and 2 different authorizations. It was kind of a pain, because, since it opens the browser which is logged into my main twitch account, it would automatically authenticate. I ended up having the 2nd one just copy to the clipboard instead of open a browser window from the shell. That way I could paste it into a different browser that was logged into my bot account.

I'm not sure if this is the intended approach -- seems like a real hot mess, but I did get it technically working. Not sure the best way to handle the UX for this due to needing 2 different logins. I guess an "authenticate channel" button and "authenticate bot account" button that would copy the URLs to be pasted in appropriate browser windows?

I just wanted my bot to respond to point redeems! 😭

Side note, the refresh_tokens() function seems like it might not be entirely correct? Maybe I just don't understand it.

func refresh_token() -> void:
	await(get_tree().create_timer(3600).timeout)
	if (await(is_token_valid(token_user["access_token"])) == ""):
		user_token_invalid.emit()
		return
	else:
		refresh_token()
	var to_remove : Array[String] = []
	for entry in eventsub_messages.keys():
		if (Time.get_ticks_msec() - eventsub_messages[entry] > 600000):
			to_remove.append(entry)
	for n in to_remove:
		eventsub_messages.erase(n)

It seems it waits 1 hour, then, if the token is invalid, it emits a signal and returns. If it's still valid, it calls refresh_token() recursively, which waits 1 hour, etc. So if, after the first hour, the token is invalid, the signal emits (does anything listen to this?) and returns without clearing the eventsub messages (though now that I'm looking at it closer, I guess it only cares about removing old stuff, so maybe that's fine?)

For my thing, I rewrote it like this, but I'm not 100% sure if that's correct, either:

func refresh_token() -> void:
	var tokens_valid := true
	while (tokens_valid):
		await(get_tree().create_timer(3600).timeout)
		if (await(validate_token_and_set_id(token_user["access_token"], ScopeType.SCOPE_TYPE_USER)) == ""):
			tokens_valid = false
		if (await(validate_token_and_set_id(token_channel["access_token"], ScopeType.SCOPE_TYPE_CHANNEL)) == ""):
			tokens_valid = false
		
		if (!tokens_valid):
			user_token_invalid.emit()
			var to_remove : Array[String] = []
			for entry in eventsub_messages.keys():
				if (Time.get_ticks_msec() - eventsub_messages[entry] > 600000):
					to_remove.append(entry)
			for n in to_remove:
				eventsub_messages.erase(n)
			print("TOKENS INVALID!!!!!")

I did eventually run into the token becoming invalid after a few hours, and I'm not sure what to do after that -- just completely reconnect everything? Doesn't look like the original code handles that case either.

I can share more of my code if you'd like, but it's kind of a hot mess...

@issork
Copy link
Owner

issork commented Jul 12, 2023

Currently, it is intended that you handle invalid tokens yourself - for example by requesting a new one, I unfortunately did not find the time yet to add handling all cases and error messages. It is not important for the EventSub messages to be cleared, so I didn't bother with that because clearing after 1h if you decide to reconnect is fine too ^^

Receiving channel point redemption events should work in theory from the bot account by adding the channel:read:redemptions or channel:manage:redemptions scope, but I've also heard from issues with that approach which I couldn't find anything about in the documentation. My guess for one of the issues was that only the app that created the reward may receive notifications of its redemption.

@jitspoe
Copy link
Author

jitspoe commented Jul 13, 2023

Gotcha, so I'm supposed to connect to the invalid token event and get a new token? Also, if the token goes invalid, is there any down time between when the token went invalid and when the check happens that could result in lost events? Sorry, I'm new to all this twitch event stuff, and it's super confusing. 😅

The problem with the scopes is it gives it the scope to read the channel points on the bot's channel, not my channel. At least, I couldn't figure out how to do it -- either I had to be 100% on my account or the bot's account with a single token, so I made 2.

@issork
Copy link
Owner

issork commented Jul 13, 2023

The event subscription has a 'condition' parameter, make sure to pass in a dictionary with "broadcaster_user_id": "<your_broadcaster_user_id>" as an entry. (see https://dev.twitch.tv/docs/eventsub/eventsub-subscription-types/#channelchannel_points_custom_reward_redemptionadd)

I think there is a downtime, but I'm not 100% sure.

@issork
Copy link
Owner

issork commented Jul 13, 2023

Took another look, Twitch does some guessing and sometimes resends events, but it's not guaranteed - so better take into account that an event might've been lost. Maybe by requesting reward redemptions from the regular API upon reconnect? (would also require you to create the rewards with the app itself)

@issork
Copy link
Owner

issork commented Nov 29, 2023

Just an update on this issue - I am currently rewriting the entire plugin and in the coming release multiple bot accounts will be possible by using the "force_verify" parameter, which will forcefully show the login window again on which you can change the account to be used.

@issork issork self-assigned this Nov 29, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants