@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 @warning_ignore("unused_private_class_variable") @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()