StreamOverlay/lib/twitcher_extended/chatbot_authorization.gd
2026-02-23 18:38:03 -06:00

117 lines
3.4 KiB
GDScript

@tool
extends Twitcher
class_name ChatbotAuthorization
@export var token: OAuthToken:
set(value):
token = value
if auth:
auth.token = token
auth.token_handler.token = token
@export var oauth_setting: OAuthSetting
@export var scopes: OAuthScopes = preload("res://addons/twitcher/chat/twitch_bot_scopes.tres")
var api: TwitchAPI
var auth: TwitchAuth
@export_tool_button("Reset Token") var _reset_token := func() -> void:
token.remove_tokens()
var _config_file: ConfigFile = ConfigFile.new()
signal _waiting_for_authentication
func _init() -> void:
child_entered_tree.connect(_handle_child_entered)
child_exiting_tree.connect(_handle_child_exiting)
func _handle_child_entered(child: Node) -> void:
if child is TwitchAuth: auth = child
if child is TwitchAPI: api = child
func _handle_child_exiting(child: Node) -> void:
if child is TwitchAuth: auth = null
if child is TwitchAPI: api = null
func _ensure_nodes() -> void:
if (api == null):
api = TwitchAPI.new()
api.name = "ChatbotAPI"
add_child(api)
api.owner = get_tree().edited_scene_root if Engine.is_editor_hint() else owner
if (auth == null):
auth = TwitchAuth.new()
auth.name = "ChatbotAuth"
add_child(auth)
auth.owner = get_tree().edited_scene_root if Engine.is_editor_hint() else owner
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
_ensure_nodes()
api.token = token
api.oauth_setting = oauth_setting
auth.token = token
auth.oauth_setting = oauth_setting
auth.token_handler.token = token
auth.scopes = scopes
auth.token_handler.token_resolved.connect(_waiting_for_authentication.emit)
auth.token_handler.unauthenticated.connect(_waiting_for_authentication.emit)
func authenticate() -> bool:
auth.token._load_tokens()
if auth.token.is_token_valid():
return true
if auth.token.has_refresh_token():
auth.force_verify = false
auth.refresh_token()
await _waiting_for_authentication
if auth.token.is_token_valid():
return true
else:
return false
auth.force_verify = true
return await auth.authorize()
func _load_from_cache() -> TwitchUser:
var user: TwitchUser = TwitchUser.new()
if (_config_file.load(token._cache_path) == OK
and _config_file.has_section(token._identifier)
and _config_file.has_section_key(token._identifier, "bot_id")):
user.id = _config_file.get_value(token._identifier, "bot_id", "")
user.display_name = _config_file.get_value(token._identifier, "bot_display", "")
user.login = _config_file.get_value(token._identifier, "bot_login", "")
return user
return null
func _save_to_cache(user: TwitchUser) -> void:
if _config_file.load(token._cache_path) == OK and _config_file.has_section(token._identifier):
_config_file.set_value(token._identifier, "bot_id", user.id)
_config_file.set_value(token._identifier, "bot_display", user.display_name)
_config_file.set_value(token._identifier, "bot_login", user.login)
_config_file.save(token._cache_path)
func get_user() -> TwitchUser:
var user: TwitchUser = _load_from_cache()
if not user:
if not auth.token.is_token_valid():
push_error("Please authenticate first, before calling get_user()")
return null
var res: TwitchGetUsers.Response = await api.get_users(null)
if res.data.size() > 0:
user = res.data[0]
_save_to_cache(user)
else:
push_error("Failed to fetch token user information")
return null
return user
func invalidate_token() -> void:
auth.token_handler.revoke_token()
auth.token.invalidate()