@tool
extends Twitcher

# CLASS GOT AUTOGENERATED DON'T CHANGE MANUALLY. CHANGES CAN BE OVERWRITTEN EASILY.

## Interaction with the Twitch REST API.
class_name TwitchAPI

static var _log: TwitchLogger = TwitchLogger.new("TwitchAPI")

static var instance: TwitchAPI

## Maximal tries to reauthrorize before giving up the request.
const MAX_AUTH_ERRORS: int = 3

## Called when the API returns unauthenticated mostly cause the accesstoken is expired
signal unauthenticated

## Called when the API returns 403 means there are permissions / scopes missing
signal unauthorized

## To authorize against the Twitch API
@export var token: OAuthToken:
	set(val):
		token = val
		update_configuration_warnings()
## OAuth settings needed for client information
@export var oauth_setting: OAuthSetting:
	set(val):
		oauth_setting = val
		update_configuration_warnings()
## URI to the Twitch API
@export var api_host: String = "https://api.twitch.tv/helix"

## Client to make HTTP requests
var client: BufferedHTTPClient


func _ready() -> void:
	client = BufferedHTTPClient.new()
	client.name = "ApiClient"
	add_child(client)


func _enter_tree() -> void:
	if instance == null: instance = self


func _exit_tree() -> void:
	if instance == self: instance = null


func _get_configuration_warnings() -> PackedStringArray:
	var result: PackedStringArray = []
	if token == null:
		result.append("Please set a token to use")
	if oauth_setting == null:
		result.append("Please set the correct oauth settings")
	return result


func request(path: String, method: int, body: Variant = "", content_type: String = "", error_count: int = 0) -> BufferedHTTPClient.ResponseData:
	var header : Dictionary = {
		"Authorization": "Bearer %s" % [await token.get_access_token()],
		"Client-ID": oauth_setting.client_id
	}
	if content_type != "":
		header["Content-Type"] = content_type

	var request_body: String = ""
	if body == null || (body is String && body == ""):
		request_body = ""
	elif body is Object && body.has_method("to_json"):
		request_body = body.to_json()
	else:
		request_body = JSON.stringify(body)

	var req: BufferedHTTPClient.RequestData = client.request(api_host + path, method, header, request_body)
	var res: BufferedHTTPClient.ResponseData = await client.wait_for_request(req)

	# Try to fix Godot TLS Bug
	if res.result == 5:
		return await retry(req, res, path, method, body, content_type, error_count + 1)

	match res.response_code:
		401: # Token expired / or missing permissions
			_log.e("'%s' is unauthorized. It is probably your scopes." % path)
			unauthorized.emit()
		403:
			_log.i("'%s' is unauthenticated. Refresh token." % path)
			unauthenticated.emit()
			await token.authorized
			return await retry(req, res, path, method, body, content_type, error_count + 1)
	return res


func retry(request: BufferedHTTPClient.RequestData,
		response: BufferedHTTPClient.ResponseData,
		path: String,
		method: int,
		body: Variant = "",
		content_type: String = "",
		error_count: int = 0) -> BufferedHTTPClient.ResponseData:
	if error_count + 1 < MAX_AUTH_ERRORS:
		return await request(path, method, body, content_type, error_count + 1)
	else:
		# Give up the request after trying multiple times and
		# return an empty response with correct error code
		var empty_response: BufferedHTTPClient.ResponseData = client.empty_response(request)
		empty_response.response_code = response.response_code
		return empty_response


func _handle_error(method_name: String, response: BufferedHTTPClient.ResponseData) -> void:
	var error_json: String = response.response_data.get_string_from_utf8()
	var error = JSON.parse_string(error_json)
	push_error("Problems while calling %s: " % method_name, error["message"])
	_log.d(error_json)


## Converts unix timestamp to RFC 3339 (example: 2021-10-27T00:00:00Z) when passed a string uses as is
static func get_rfc_3339_date_format(time: Variant) -> String:
	if typeof(time) == TYPE_INT:
		var date_time = Time.get_datetime_dict_from_unix_time(time)
		return "%s-%02d-%02dT%02d:%02d:%02dZ" % [date_time['year'], date_time['month'], date_time['day'], date_time['hour'], date_time['minute'], date_time['second']]
	return str(time)



## Starts a commercial on the specified channel.
##
## [no required query parameters to describe]
##
## https://dev.twitch.tv/docs/api/reference#start-commercial
func start_commercial(body: TwitchStartCommercial.Body) -> TwitchStartCommercial.Response:
	var path = "/channels/commercial?"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_POST, body, "application/json")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("start_commercial", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchStartCommercial.Response = TwitchStartCommercial.Response.from_json(result)
	parsed_result.response = response

	return parsed_result


## Returns ad schedule related information.
##
## broadcaster_id - Provided `broadcaster_id` must match the `user_id` in the auth token.
##
## https://dev.twitch.tv/docs/api/reference#get-ad-schedule
func get_ad_schedule(broadcaster_id: String) -> TwitchGetAdSchedule.Response:
	var path = "/channels/ads?"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_GET, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("get_ad_schedule", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchGetAdSchedule.Response = TwitchGetAdSchedule.Response.from_json(result)
	parsed_result.response = response

	return parsed_result


## Pushes back the timestamp of the upcoming automatic mid-roll ad by 5 minutes.
##
## broadcaster_id - Provided `broadcaster_id` must match the `user_id` in the auth token.
##
## https://dev.twitch.tv/docs/api/reference#snooze-next-ad
func snooze_next_ad(broadcaster_id: String) -> TwitchSnoozeNextAd.Response:
	var path = "/channels/ads/schedule/snooze?"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_POST, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("snooze_next_ad", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchSnoozeNextAd.Response = TwitchSnoozeNextAd.Response.from_json(result)
	parsed_result.response = response

	return parsed_result


## Gets an analytics report for one or more extensions.
##
## [no required query parameters to describe]
##
## https://dev.twitch.tv/docs/api/reference#get-extension-analytics
func get_extension_analytics(opt: TwitchGetExtensionAnalytics.Opt) -> TwitchGetExtensionAnalytics.Response:
	var path = "/analytics/extensions?"
	var optionals: Dictionary[StringName, Variant] = {}
	if opt != null: optionals = opt.to_dict()
	if optionals.has("after"):
		path += "after=" + str(optionals.after) + "&"
	if optionals.has("ended_at"):
		path += "ended_at=" + get_rfc_3339_date_format(optionals.ended_at) + "&"
	if optionals.has("extension_id"):
		path += "extension_id=" + str(optionals.extension_id) + "&"
	if optionals.has("first"):
		path += "first=" + str(optionals.first) + "&"
	if optionals.has("started_at"):
		path += "started_at=" + get_rfc_3339_date_format(optionals.started_at) + "&"
	if optionals.has("type"):
		path += "type=" + str(optionals.type) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_GET, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("get_extension_analytics", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchGetExtensionAnalytics.Response = TwitchGetExtensionAnalytics.Response.from_json(result)
	parsed_result.response = response
	if parsed_result.pagination != null:
		var cursor: String = parsed_result.pagination.cursor
		if not opt: opt = TwitchGetExtensionAnalytics.Opt.new()
		opt.after = cursor
		parsed_result._next_page = get_extension_analytics.bind(opt)

	return parsed_result


## Gets an analytics report for one or more games.
##
## [no required query parameters to describe]
##
## https://dev.twitch.tv/docs/api/reference#get-game-analytics
func get_game_analytics(opt: TwitchGetGameAnalytics.Opt) -> TwitchGetGameAnalytics.Response:
	var path = "/analytics/games?"
	var optionals: Dictionary[StringName, Variant] = {}
	if opt != null: optionals = opt.to_dict()
	if optionals.has("after"):
		path += "after=" + str(optionals.after) + "&"
	if optionals.has("ended_at"):
		path += "ended_at=" + get_rfc_3339_date_format(optionals.ended_at) + "&"
	if optionals.has("first"):
		path += "first=" + str(optionals.first) + "&"
	if optionals.has("game_id"):
		path += "game_id=" + str(optionals.game_id) + "&"
	if optionals.has("started_at"):
		path += "started_at=" + get_rfc_3339_date_format(optionals.started_at) + "&"
	if optionals.has("type"):
		path += "type=" + str(optionals.type) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_GET, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("get_game_analytics", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchGetGameAnalytics.Response = TwitchGetGameAnalytics.Response.from_json(result)
	parsed_result.response = response
	if parsed_result.pagination != null:
		var cursor: String = parsed_result.pagination.cursor
		if not opt: opt = TwitchGetGameAnalytics.Opt.new()
		opt.after = cursor
		parsed_result._next_page = get_game_analytics.bind(opt)

	return parsed_result


## Gets the Bits leaderboard for the authenticated broadcaster.
##
## [no required query parameters to describe]
##
## https://dev.twitch.tv/docs/api/reference#get-bits-leaderboard
func get_bits_leaderboard(opt: TwitchGetBitsLeaderboard.Opt) -> TwitchGetBitsLeaderboard.Response:
	var path = "/bits/leaderboard?"
	var optionals: Dictionary[StringName, Variant] = {}
	if opt != null: optionals = opt.to_dict()
	if optionals.has("count"):
		path += "count=" + str(optionals.count) + "&"
	if optionals.has("period"):
		path += "period=" + str(optionals.period) + "&"
	if optionals.has("started_at"):
		path += "started_at=" + get_rfc_3339_date_format(optionals.started_at) + "&"
	if optionals.has("user_id"):
		path += "user_id=" + str(optionals.user_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_GET, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("get_bits_leaderboard", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchGetBitsLeaderboard.Response = TwitchGetBitsLeaderboard.Response.from_json(result)
	parsed_result.response = response

	return parsed_result


## Gets a list of Cheermotes that users can use to cheer Bits.
##
## [no required query parameters to describe]
##
## https://dev.twitch.tv/docs/api/reference#get-cheermotes
func get_cheermotes(opt: TwitchGetCheermotes.Opt) -> TwitchGetCheermotes.Response:
	var path = "/bits/cheermotes?"
	var optionals: Dictionary[StringName, Variant] = {}
	if opt != null: optionals = opt.to_dict()
	if optionals.has("broadcaster_id"):
		path += "broadcaster_id=" + str(optionals.broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_GET, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("get_cheermotes", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchGetCheermotes.Response = TwitchGetCheermotes.Response.from_json(result)
	parsed_result.response = response

	return parsed_result


## Gets an extension’s list of transactions.
##
## extension_id - The ID of the extension whose list of transactions you want to get.
##
## https://dev.twitch.tv/docs/api/reference#get-extension-transactions
func get_extension_transactions(opt: TwitchGetExtensionTransactions.Opt, extension_id: String) -> TwitchGetExtensionTransactions.Response:
	var path = "/extensions/transactions?"
	var optionals: Dictionary[StringName, Variant] = {}
	if opt != null: optionals = opt.to_dict()
	path += "extension_id=" + str(extension_id) + "&"
	if optionals.has("after"):
		path += "after=" + str(optionals.after) + "&"
	if optionals.has("first"):
		path += "first=" + str(optionals.first) + "&"
	if optionals.has("id"):

		for param in optionals.id:
			path += "id=" + str(param) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_GET, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("get_extension_transactions", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchGetExtensionTransactions.Response = TwitchGetExtensionTransactions.Response.from_json(result)
	parsed_result.response = response
	if parsed_result.pagination != null:
		var cursor: String = parsed_result.pagination.cursor
		if not opt: opt = TwitchGetExtensionTransactions.Opt.new()
		opt.after = cursor
		parsed_result._next_page = get_extension_transactions.bind(opt, extension_id)

	return parsed_result


## Gets information about one or more channels.
##
## broadcaster_id - The ID of the broadcaster whose channel you want to get. To specify more than one ID, include this parameter for each broadcaster you want to get. For example, `broadcaster_id=1234&broadcaster_id=5678`. You may specify a maximum of 100 IDs. The API ignores duplicate IDs and IDs that are not found.
##
## https://dev.twitch.tv/docs/api/reference#get-channel-information
func get_channel_information(broadcaster_id: Array[String]) -> TwitchGetChannelInformation.Response:
	var path = "/channels?"

	for param in broadcaster_id:
		path += "broadcaster_id=" + str(param) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_GET, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("get_channel_information", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchGetChannelInformation.Response = TwitchGetChannelInformation.Response.from_json(result)
	parsed_result.response = response

	return parsed_result


## Updates a channel’s properties.
##
## broadcaster_id - The ID of the broadcaster whose channel you want to update. This ID must match the user ID in the user access token.
##
## https://dev.twitch.tv/docs/api/reference#modify-channel-information
func modify_channel_information(body: TwitchModifyChannelInformation.Body, broadcaster_id: String) -> BufferedHTTPClient.ResponseData:
	var path = "/channels?"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_PATCH, body, "application/json")

	if response.response_code >= 400:
		_handle_error("modify_channel_information", response)
	return response


## Gets the broadcaster’s list editors.
##
## broadcaster_id - The ID of the broadcaster that owns the channel. This ID must match the user ID in the access token.
##
## https://dev.twitch.tv/docs/api/reference#get-channel-editors
func get_channel_editors(broadcaster_id: String) -> TwitchGetChannelEditors.Response:
	var path = "/channels/editors?"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_GET, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("get_channel_editors", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchGetChannelEditors.Response = TwitchGetChannelEditors.Response.from_json(result)
	parsed_result.response = response

	return parsed_result


## Gets a list of broadcasters that the specified user follows. You can also use this endpoint to see whether a user follows a specific broadcaster.
##
## user_id - A user’s ID. Returns the list of broadcasters that this user follows. This ID must match the user ID in the user OAuth token.
##
## https://dev.twitch.tv/docs/api/reference#get-followed-channels
func get_followed_channels(opt: TwitchGetFollowedChannels.Opt, user_id: String) -> TwitchGetFollowedChannels.Response:
	var path = "/channels/followed?"
	var optionals: Dictionary[StringName, Variant] = {}
	if opt != null: optionals = opt.to_dict()
	path += "user_id=" + str(user_id) + "&"
	if optionals.has("after"):
		path += "after=" + str(optionals.after) + "&"
	if optionals.has("first"):
		path += "first=" + str(optionals.first) + "&"
	if optionals.has("broadcaster_id"):
		path += "broadcaster_id=" + str(optionals.broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_GET, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("get_followed_channels", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchGetFollowedChannels.Response = TwitchGetFollowedChannels.Response.from_json(result)
	parsed_result.response = response
	if parsed_result.pagination != null:
		var cursor: String = parsed_result.pagination.cursor
		if not opt: opt = TwitchGetFollowedChannels.Opt.new()
		opt.after = cursor
		parsed_result._next_page = get_followed_channels.bind(opt, user_id)

	return parsed_result


## Gets a list of users that follow the specified broadcaster. You can also use this endpoint to see whether a specific user follows the broadcaster.
##
## broadcaster_id - The broadcaster’s ID. Returns the list of users that follow this broadcaster.
##
## https://dev.twitch.tv/docs/api/reference#get-channel-followers
func get_channel_followers(opt: TwitchGetChannelFollowers.Opt, broadcaster_id: String) -> TwitchGetChannelFollowers.Response:
	var path = "/channels/followers?"
	var optionals: Dictionary[StringName, Variant] = {}
	if opt != null: optionals = opt.to_dict()
	if optionals.has("after"):
		path += "after=" + str(optionals.after) + "&"
	if optionals.has("first"):
		path += "first=" + str(optionals.first) + "&"
	if optionals.has("user_id"):
		path += "user_id=" + str(optionals.user_id) + "&"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_GET, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("get_channel_followers", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchGetChannelFollowers.Response = TwitchGetChannelFollowers.Response.from_json(result)
	parsed_result.response = response
	if parsed_result.pagination != null:
		var cursor: String = parsed_result.pagination.cursor
		if not opt: opt = TwitchGetChannelFollowers.Opt.new()
		opt.after = cursor
		parsed_result._next_page = get_channel_followers.bind(opt, broadcaster_id)

	return parsed_result


## Creates a Custom Reward in the broadcaster’s channel.
##
## broadcaster_id - The ID of the broadcaster to add the custom reward to. This ID must match the user ID found in the OAuth token.
##
## https://dev.twitch.tv/docs/api/reference#create-custom-rewards
func create_custom_rewards(body: TwitchCreateCustomRewards.Body, broadcaster_id: String) -> TwitchCreateCustomRewards.Response:
	var path = "/channel_points/custom_rewards?"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_POST, body, "application/json")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("create_custom_rewards", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchCreateCustomRewards.Response = TwitchCreateCustomRewards.Response.from_json(result)
	parsed_result.response = response

	return parsed_result


## Deletes a custom reward that the broadcaster created.
##
## broadcaster_id - The ID of the broadcaster that created the custom reward. This ID must match the user ID found in the OAuth token.
## id - The ID of the custom reward to delete.
##
## https://dev.twitch.tv/docs/api/reference#delete-custom-reward
func delete_custom_reward(id: String, broadcaster_id: String) -> BufferedHTTPClient.ResponseData:
	var path = "/channel_points/custom_rewards?"
	path += "id=" + str(id) + "&"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_DELETE, "", "")

	if response.response_code >= 400:
		_handle_error("delete_custom_reward", response)
	return response


## Gets a list of custom rewards that the specified broadcaster created.
##
## broadcaster_id - The ID of the broadcaster whose custom rewards you want to get. This ID must match the user ID found in the OAuth token.
##
## https://dev.twitch.tv/docs/api/reference#get-custom-reward
func get_custom_reward(opt: TwitchGetCustomReward.Opt, broadcaster_id: String) -> TwitchGetCustomReward.Response:
	var path = "/channel_points/custom_rewards?"
	var optionals: Dictionary[StringName, Variant] = {}
	if opt != null: optionals = opt.to_dict()
	if optionals.has("id"):

		for param in optionals.id:
			path += "id=" + str(param) + "&"
	if optionals.has("only_manageable_rewards"):
		path += "only_manageable_rewards=" + str(optionals.only_manageable_rewards) + "&"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_GET, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("get_custom_reward", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchGetCustomReward.Response = TwitchGetCustomReward.Response.from_json(result)
	parsed_result.response = response

	return parsed_result


## Updates a custom reward.
##
## broadcaster_id - The ID of the broadcaster that’s updating the reward. This ID must match the user ID found in the OAuth token.
## id - The ID of the reward to update.
##
## https://dev.twitch.tv/docs/api/reference#update-custom-reward
func update_custom_reward(body: TwitchUpdateCustomReward.Body, id: String, broadcaster_id: String) -> TwitchUpdateCustomReward.Response:
	var path = "/channel_points/custom_rewards?"
	path += "id=" + str(id) + "&"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_PATCH, body, "application/json")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("update_custom_reward", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchUpdateCustomReward.Response = TwitchUpdateCustomReward.Response.from_json(result)
	parsed_result.response = response

	return parsed_result


## Gets a list of redemptions for a custom reward.
##
## broadcaster_id - The ID of the broadcaster that owns the custom reward. This ID must match the user ID found in the user OAuth token.
## reward_id - The ID that identifies the custom reward whose redemptions you want to get.
##
## https://dev.twitch.tv/docs/api/reference#get-custom-reward-redemption
func get_custom_reward_redemption(opt: TwitchGetCustomRewardRedemption.Opt, reward_id: String, broadcaster_id: String) -> TwitchGetCustomRewardRedemption.Response:
	var path = "/channel_points/custom_rewards/redemptions?"
	var optionals: Dictionary[StringName, Variant] = {}
	if opt != null: optionals = opt.to_dict()
	path += "reward_id=" + str(reward_id) + "&"
	if optionals.has("after"):
		path += "after=" + str(optionals.after) + "&"
	if optionals.has("first"):
		path += "first=" + str(optionals.first) + "&"
	if optionals.has("id"):

		for param in optionals.id:
			path += "id=" + str(param) + "&"
	if optionals.has("sort"):
		path += "sort=" + str(optionals.sort) + "&"
	if optionals.has("status"):
		path += "status=" + str(optionals.status) + "&"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_GET, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("get_custom_reward_redemption", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchGetCustomRewardRedemption.Response = TwitchGetCustomRewardRedemption.Response.from_json(result)
	parsed_result.response = response
	if parsed_result.pagination != null:
		var cursor: String = parsed_result.pagination.cursor
		if not opt: opt = TwitchGetCustomRewardRedemption.Opt.new()
		opt.after = cursor
		parsed_result._next_page = get_custom_reward_redemption.bind(opt, reward_id, broadcaster_id)

	return parsed_result


## Updates a redemption’s status.
##
## id - A list of IDs that identify the redemptions to update. To specify more than one ID, include this parameter for each redemption you want to update. For example, `id=1234&id=5678`. You may specify a maximum of 50 IDs.
## broadcaster_id - The ID of the broadcaster that’s updating the redemption. This ID must match the user ID in the user access token.
## reward_id - The ID that identifies the reward that’s been redeemed.
##
## https://dev.twitch.tv/docs/api/reference#update-redemption-status
func update_redemption_status(body: TwitchUpdateRedemptionStatus.Body, id: Array[String], reward_id: String, broadcaster_id: String) -> TwitchUpdateRedemptionStatus.Response:
	var path = "/channel_points/custom_rewards/redemptions?"

	for param in id:
		path += "id=" + str(param) + "&"
	path += "reward_id=" + str(reward_id) + "&"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_PATCH, body, "application/json")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("update_redemption_status", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchUpdateRedemptionStatus.Response = TwitchUpdateRedemptionStatus.Response.from_json(result)
	parsed_result.response = response

	return parsed_result


## Gets information about the broadcaster’s active charity campaign.
##
## broadcaster_id - The ID of the broadcaster that’s currently running a charity campaign. This ID must match the user ID in the access token.
##
## https://dev.twitch.tv/docs/api/reference#get-charity-campaign
func get_charity_campaign(broadcaster_id: String) -> TwitchGetCharityCampaign.Response:
	var path = "/charity/campaigns?"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_GET, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("get_charity_campaign", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchGetCharityCampaign.Response = TwitchGetCharityCampaign.Response.from_json(result)
	parsed_result.response = response

	return parsed_result


## Gets the list of donations that users have made to the broadcaster’s active charity campaign.
##
## broadcaster_id - The ID of the broadcaster that’s currently running a charity campaign. This ID must match the user ID in the access token.
##
## https://dev.twitch.tv/docs/api/reference#get-charity-campaign-donations
func get_charity_campaign_donations(opt: TwitchGetCharityCampaignDonations.Opt, broadcaster_id: String) -> TwitchGetCharityCampaignDonations.Response:
	var path = "/charity/donations?"
	var optionals: Dictionary[StringName, Variant] = {}
	if opt != null: optionals = opt.to_dict()
	if optionals.has("after"):
		path += "after=" + str(optionals.after) + "&"
	if optionals.has("first"):
		path += "first=" + str(optionals.first) + "&"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_GET, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("get_charity_campaign_donations", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchGetCharityCampaignDonations.Response = TwitchGetCharityCampaignDonations.Response.from_json(result)
	parsed_result.response = response
	if parsed_result.pagination != null:
		var cursor: String = parsed_result.pagination.cursor
		if not opt: opt = TwitchGetCharityCampaignDonations.Opt.new()
		opt.after = cursor
		parsed_result._next_page = get_charity_campaign_donations.bind(opt, broadcaster_id)

	return parsed_result


## Gets the list of users that are connected to the broadcaster’s chat session.
##
## broadcaster_id - The ID of the broadcaster whose list of chatters you want to get.
## moderator_id - The ID of the broadcaster or one of the broadcaster’s moderators. This ID must match the user ID in the user access token.
##
## https://dev.twitch.tv/docs/api/reference#get-chatters
func get_chatters(opt: TwitchGetChatters.Opt, moderator_id: String, broadcaster_id: String) -> TwitchGetChatters.Response:
	var path = "/chat/chatters?"
	var optionals: Dictionary[StringName, Variant] = {}
	if opt != null: optionals = opt.to_dict()
	path += "moderator_id=" + str(moderator_id) + "&"
	if optionals.has("after"):
		path += "after=" + str(optionals.after) + "&"
	if optionals.has("first"):
		path += "first=" + str(optionals.first) + "&"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_GET, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("get_chatters", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchGetChatters.Response = TwitchGetChatters.Response.from_json(result)
	parsed_result.response = response
	if parsed_result.pagination != null:
		var cursor: String = parsed_result.pagination.cursor
		if not opt: opt = TwitchGetChatters.Opt.new()
		opt.after = cursor
		parsed_result._next_page = get_chatters.bind(opt, moderator_id, broadcaster_id)

	return parsed_result


## Gets the broadcaster’s list of custom emotes.
##
## broadcaster_id - An ID that identifies the broadcaster whose emotes you want to get.
##
## https://dev.twitch.tv/docs/api/reference#get-channel-emotes
func get_channel_emotes(broadcaster_id: String) -> TwitchGetChannelEmotes.Response:
	var path = "/chat/emotes?"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_GET, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("get_channel_emotes", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchGetChannelEmotes.Response = TwitchGetChannelEmotes.Response.from_json(result)
	parsed_result.response = response

	return parsed_result


## Gets all global emotes.
##
## [no required query parameters to describe]
##
## https://dev.twitch.tv/docs/api/reference#get-global-emotes
func get_global_emotes() -> TwitchGetGlobalEmotes.Response:
	var path = "/chat/emotes/global?"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_GET, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("get_global_emotes", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchGetGlobalEmotes.Response = TwitchGetGlobalEmotes.Response.from_json(result)
	parsed_result.response = response

	return parsed_result


## Gets emotes for one or more specified emote sets.
##
## emote_set_id - An ID that identifies the emote set to get. Include this parameter for each emote set you want to get. For example, `emote_set_id=1234&emote_set_id=5678`. You may specify a maximum of 25 IDs. The response contains only the IDs that were found and ignores duplicate IDs.
##
##    To get emote set IDs, use the [Get Channel Emotes](https://dev.twitch.tv/docs/api/reference#get-channel-emotes) API.
##
## https://dev.twitch.tv/docs/api/reference#get-emote-sets
func get_emote_sets(emote_set_id: Array[String]) -> TwitchGetEmoteSets.Response:
	var path = "/chat/emotes/set?"

	for param in emote_set_id:
		path += "emote_set_id=" + str(param) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_GET, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("get_emote_sets", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchGetEmoteSets.Response = TwitchGetEmoteSets.Response.from_json(result)
	parsed_result.response = response

	return parsed_result


## Gets the broadcaster’s list of custom chat badges.
##
## broadcaster_id - The ID of the broadcaster whose chat badges you want to get.
##
## https://dev.twitch.tv/docs/api/reference#get-channel-chat-badges
func get_channel_chat_badges(broadcaster_id: String) -> TwitchGetChannelChatBadges.Response:
	var path = "/chat/badges?"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_GET, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("get_channel_chat_badges", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchGetChannelChatBadges.Response = TwitchGetChannelChatBadges.Response.from_json(result)
	parsed_result.response = response

	return parsed_result


## Gets Twitch’s list of chat badges.
##
## [no required query parameters to describe]
##
## https://dev.twitch.tv/docs/api/reference#get-global-chat-badges
func get_global_chat_badges() -> TwitchGetGlobalChatBadges.Response:
	var path = "/chat/badges/global?"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_GET, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("get_global_chat_badges", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchGetGlobalChatBadges.Response = TwitchGetGlobalChatBadges.Response.from_json(result)
	parsed_result.response = response

	return parsed_result


## Gets the broadcaster’s chat settings.
##
## broadcaster_id - The ID of the broadcaster whose chat settings you want to get.
##
## https://dev.twitch.tv/docs/api/reference#get-chat-settings
func get_chat_settings(opt: TwitchGetChatSettings.Opt, broadcaster_id: String) -> TwitchGetChatSettings.Response:
	var path = "/chat/settings?"
	var optionals: Dictionary[StringName, Variant] = {}
	if opt != null: optionals = opt.to_dict()
	if optionals.has("moderator_id"):
		path += "moderator_id=" + str(optionals.moderator_id) + "&"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_GET, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("get_chat_settings", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchGetChatSettings.Response = TwitchGetChatSettings.Response.from_json(result)
	parsed_result.response = response

	return parsed_result


## Updates the broadcaster’s chat settings.
##
## broadcaster_id - The ID of the broadcaster whose chat settings you want to update.
## moderator_id - The ID of a user that has permission to moderate the broadcaster’s chat room, or the broadcaster’s ID if they’re making the update. This ID must match the user ID in the user access token.
##
## https://dev.twitch.tv/docs/api/reference#update-chat-settings
func update_chat_settings(body: TwitchUpdateChatSettings.Body, moderator_id: String, broadcaster_id: String) -> TwitchUpdateChatSettings.Response:
	var path = "/chat/settings?"
	path += "moderator_id=" + str(moderator_id) + "&"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_PATCH, body, "application/json")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("update_chat_settings", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchUpdateChatSettings.Response = TwitchUpdateChatSettings.Response.from_json(result)
	parsed_result.response = response

	return parsed_result


## NEW Retrieves the active shared chat session for a channel.
##
## broadcaster_id - The User ID of the channel broadcaster.
##
## https://dev.twitch.tv/docs/api/reference#get-shared-chat-session
func get_shared_chat_session(broadcaster_id: String) -> TwitchGetSharedChatSession.Response:
	var path = "/shared_chat/session?"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_GET, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("get_shared_chat_session", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchGetSharedChatSession.Response = TwitchGetSharedChatSession.Response.from_json(result)
	parsed_result.response = response

	return parsed_result


## NEW Retrieves emotes available to the user across all channels.
##
## user_id - The ID of the user. This ID must match the user ID in the user access token.
##
## https://dev.twitch.tv/docs/api/reference#get-user-emotes
func get_user_emotes(opt: TwitchGetUserEmotes.Opt, user_id: String) -> TwitchGetUserEmotes.Response:
	var path = "/chat/emotes/user?"
	var optionals: Dictionary[StringName, Variant] = {}
	if opt != null: optionals = opt.to_dict()
	path += "user_id=" + str(user_id) + "&"
	if optionals.has("after"):
		path += "after=" + str(optionals.after) + "&"
	if optionals.has("broadcaster_id"):
		path += "broadcaster_id=" + str(optionals.broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_GET, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("get_user_emotes", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchGetUserEmotes.Response = TwitchGetUserEmotes.Response.from_json(result)
	parsed_result.response = response
	if parsed_result.pagination != null:
		var cursor: String = parsed_result.pagination.cursor
		if not opt: opt = TwitchGetUserEmotes.Opt.new()
		opt.after = cursor
		parsed_result._next_page = get_user_emotes.bind(opt, user_id)

	return parsed_result


## Sends an announcement to the broadcaster’s chat room.
##
## broadcaster_id - The ID of the broadcaster that owns the chat room to send the announcement to.
## moderator_id - The ID of a user who has permission to moderate the broadcaster’s chat room, or the broadcaster’s ID if they’re sending the announcement. This ID must match the user ID in the user access token.
##
## https://dev.twitch.tv/docs/api/reference#send-chat-announcement
func send_chat_announcement(body: TwitchSendChatAnnouncement.Body, moderator_id: String, broadcaster_id: String) -> BufferedHTTPClient.ResponseData:
	var path = "/chat/announcements?"
	path += "moderator_id=" + str(moderator_id) + "&"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_POST, body, "application/json")

	if response.response_code >= 400:
		_handle_error("send_chat_announcement", response)
	return response


## Sends a Shoutout to the specified broadcaster.
##
## from_broadcaster_id - The ID of the broadcaster that’s sending the Shoutout.
## to_broadcaster_id - The ID of the broadcaster that’s receiving the Shoutout.
## moderator_id - The ID of the broadcaster or a user that is one of the broadcaster’s moderators. This ID must match the user ID in the access token.
##
## https://dev.twitch.tv/docs/api/reference#send-a-shoutout
func send_a_shoutout(from_broadcaster_id: String, moderator_id: String, to_broadcaster_id: String) -> BufferedHTTPClient.ResponseData:
	var path = "/chat/shoutouts?"
	path += "from_broadcaster_id=" + str(from_broadcaster_id) + "&"
	path += "moderator_id=" + str(moderator_id) + "&"
	path += "to_broadcaster_id=" + str(to_broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_POST, "", "")

	if response.response_code >= 400:
		_handle_error("send_a_shoutout", response)
	return response


## NEW Sends a message to the broadcaster’s chat room.
##
## [no required query parameters to describe]
##
## https://dev.twitch.tv/docs/api/reference#send-chat-message
func send_chat_message(body: TwitchSendChatMessage.Body) -> TwitchSendChatMessage.Response:
	var path = "/chat/messages?"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_POST, body, "application/json")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("send_chat_message", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchSendChatMessage.Response = TwitchSendChatMessage.Response.from_json(result)
	parsed_result.response = response

	return parsed_result


## Gets the color used for the user’s name in chat.
##
## user_id - The ID of the user whose username color you want to get. To specify more than one user, include the _user\_id_ parameter for each user to get. For example, `&user_id=1234&user_id=5678`. The maximum number of IDs that you may specify is 100.
##
##    The API ignores duplicate IDs and IDs that weren’t found.
##
## https://dev.twitch.tv/docs/api/reference#get-user-chat-color
func get_user_chat_color(user_id: Array[String]) -> TwitchGetUserChatColor.Response:
	var path = "/chat/color?"

	for param in user_id:
		path += "user_id=" + str(param) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_GET, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("get_user_chat_color", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchGetUserChatColor.Response = TwitchGetUserChatColor.Response.from_json(result)
	parsed_result.response = response

	return parsed_result


## Updates the color used for the user’s name in chat.
##
## user_id - The ID of the user whose chat color you want to update. This ID must match the user ID in the access token.
## color - The color to use for the user's name in chat. All users may specify one of the following named color values.
##
##    * blue
##    * blue\_violet
##    * cadet\_blue
##    * chocolate
##    * coral
##    * dodger\_blue
##    * firebrick
##    * golden\_rod
##    * green
##    * hot\_pink
##    * orange\_red
##    * red
##    * sea\_green
##    * spring\_green
##    * yellow\_green
##
##    Turbo and Prime users may specify a named color or a Hex color code like #9146FF. If you use a Hex color code, remember to URL encode it.
##
## https://dev.twitch.tv/docs/api/reference#update-user-chat-color
func update_user_chat_color(color: String, user_id: String) -> BufferedHTTPClient.ResponseData:
	var path = "/chat/color?"
	path += "color=" + str(color) + "&"
	path += "user_id=" + str(user_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_PUT, "", "")

	if response.response_code >= 400:
		_handle_error("update_user_chat_color", response)
	return response


## Creates a clip from the broadcaster’s stream.
##
## broadcaster_id - The ID of the broadcaster whose stream you want to create a clip from.
##
## https://dev.twitch.tv/docs/api/reference#create-clip
func create_clip(opt: TwitchCreateClip.Opt, broadcaster_id: String) -> TwitchCreateClip.Response:
	var path = "/clips?"
	var optionals: Dictionary[StringName, Variant] = {}
	if opt != null: optionals = opt.to_dict()
	if optionals.has("has_delay"):
		path += "has_delay=" + str(optionals.has_delay) + "&"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_POST, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("create_clip", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchCreateClip.Response = TwitchCreateClip.Response.from_json(result)
	parsed_result.response = response

	return parsed_result


## Gets one or more video clips.
##
## [no required query parameters to describe]
##
## https://dev.twitch.tv/docs/api/reference#get-clips
func get_clips(opt: TwitchGetClips.Opt) -> TwitchGetClips.Response:
	var path = "/clips?"
	var optionals: Dictionary[StringName, Variant] = {}
	if opt != null: optionals = opt.to_dict()
	if optionals.has("after"):
		path += "after=" + str(optionals.after) + "&"
	if optionals.has("before"):
		path += "before=" + str(optionals.before) + "&"
	if optionals.has("ended_at"):
		path += "ended_at=" + get_rfc_3339_date_format(optionals.ended_at) + "&"
	if optionals.has("first"):
		path += "first=" + str(optionals.first) + "&"
	if optionals.has("game_id"):
		path += "game_id=" + str(optionals.game_id) + "&"
	if optionals.has("id"):

		for param in optionals.id:
			path += "id=" + str(param) + "&"
	if optionals.has("is_featured"):
		path += "is_featured=" + str(optionals.is_featured) + "&"
	if optionals.has("started_at"):
		path += "started_at=" + get_rfc_3339_date_format(optionals.started_at) + "&"
	if optionals.has("broadcaster_id"):
		path += "broadcaster_id=" + str(optionals.broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_GET, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("get_clips", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchGetClips.Response = TwitchGetClips.Response.from_json(result)
	parsed_result.response = response
	if parsed_result.pagination != null:
		var cursor: String = parsed_result.pagination.cursor
		if not opt: opt = TwitchGetClips.Opt.new()
		opt.after = cursor
		parsed_result._next_page = get_clips.bind(opt)

	return parsed_result


## NEW  Gets the conduits for a client ID.
##
## [no required query parameters to describe]
##
## https://dev.twitch.tv/docs/api/reference#get-conduits
func get_conduits() -> TwitchGetConduits.Response:
	var path = "/eventsub/conduits?"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_GET, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("get_conduits", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchGetConduits.Response = TwitchGetConduits.Response.from_json(result)
	parsed_result.response = response

	return parsed_result


## NEW Creates a new conduit.
##
## [no required query parameters to describe]
##
## https://dev.twitch.tv/docs/api/reference#create-conduits
func create_conduits(body: TwitchCreateConduits.Body) -> TwitchCreateConduits.Response:
	var path = "/eventsub/conduits?"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_POST, body, "application/json")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("create_conduits", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchCreateConduits.Response = TwitchCreateConduits.Response.from_json(result)
	parsed_result.response = response

	return parsed_result


## NEW Updates a conduit’s shard count.
##
## [no required query parameters to describe]
##
## https://dev.twitch.tv/docs/api/reference#update-conduits
func update_conduits(body: TwitchUpdateConduits.Body) -> TwitchUpdateConduits.Response:
	var path = "/eventsub/conduits?"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_PATCH, body, "application/json")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("update_conduits", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchUpdateConduits.Response = TwitchUpdateConduits.Response.from_json(result)
	parsed_result.response = response

	return parsed_result


## NEW Deletes a specified conduit.
##
## id - Conduit ID.
##
## https://dev.twitch.tv/docs/api/reference#delete-conduit
func delete_conduit(id: String) -> BufferedHTTPClient.ResponseData:
	var path = "/eventsub/conduits?"
	path += "id=" + str(id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_DELETE, "", "")

	if response.response_code >= 400:
		_handle_error("delete_conduit", response)
	return response


## NEW Gets a lists of all shards for a conduit.
##
## conduit_id - Conduit ID.
##
## https://dev.twitch.tv/docs/api/reference#get-conduit-shards
func get_conduit_shards(opt: TwitchGetConduitShards.Opt, conduit_id: String) -> TwitchGetConduitShards.Response:
	var path = "/eventsub/conduits/shards?"
	var optionals: Dictionary[StringName, Variant] = {}
	if opt != null: optionals = opt.to_dict()
	path += "conduit_id=" + str(conduit_id) + "&"
	if optionals.has("after"):
		path += "after=" + str(optionals.after) + "&"
	if optionals.has("status"):
		path += "status=" + str(optionals.status) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_GET, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("get_conduit_shards", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchGetConduitShards.Response = TwitchGetConduitShards.Response.from_json(result)
	parsed_result.response = response
	if parsed_result.pagination != null:
		var cursor: String = parsed_result.pagination.cursor
		if not opt: opt = TwitchGetConduitShards.Opt.new()
		opt.after = cursor
		parsed_result._next_page = get_conduit_shards.bind(opt, conduit_id)

	return parsed_result


## NEW Updates shard(s) for a conduit.
##
## [no required query parameters to describe]
##
## https://dev.twitch.tv/docs/api/reference#update-conduit-shards
func update_conduit_shards(body: TwitchUpdateConduitShards.Body) -> TwitchUpdateConduitShards.Response:
	var path = "/eventsub/conduits/shards?"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_PATCH, body, "application/json")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("update_conduit_shards", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchUpdateConduitShards.Response = TwitchUpdateConduitShards.Response.from_json(result)
	parsed_result.response = response

	return parsed_result


## Gets information about Twitch content classification labels.
##
## [no required query parameters to describe]
##
## https://dev.twitch.tv/docs/api/reference#get-content-classification-labels
func get_content_classification_labels(opt: TwitchGetContentClassificationLabels.Opt) -> TwitchGetContentClassificationLabels.Response:
	var path = "/content_classification_labels?"
	var optionals: Dictionary[StringName, Variant] = {}
	if opt != null: optionals = opt.to_dict()
	if optionals.has("locale"):
		path += "locale=" + str(optionals.locale) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_GET, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("get_content_classification_labels", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchGetContentClassificationLabels.Response = TwitchGetContentClassificationLabels.Response.from_json(result)
	parsed_result.response = response

	return parsed_result


## Gets an organization’s list of entitlements that have been granted to a game, a user, or both.
##
## [no required query parameters to describe]
##
## https://dev.twitch.tv/docs/api/reference#get-drops-entitlements
func get_drops_entitlements(opt: TwitchGetDropsEntitlements.Opt) -> TwitchGetDropsEntitlements.Response:
	var path = "/entitlements/drops?"
	var optionals: Dictionary[StringName, Variant] = {}
	if opt != null: optionals = opt.to_dict()
	if optionals.has("after"):
		path += "after=" + str(optionals.after) + "&"
	if optionals.has("first"):
		path += "first=" + str(optionals.first) + "&"
	if optionals.has("fulfillment_status"):
		path += "fulfillment_status=" + str(optionals.fulfillment_status) + "&"
	if optionals.has("game_id"):
		path += "game_id=" + str(optionals.game_id) + "&"
	if optionals.has("id"):

		for param in optionals.id:
			path += "id=" + str(param) + "&"
	if optionals.has("user_id"):
		path += "user_id=" + str(optionals.user_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_GET, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("get_drops_entitlements", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchGetDropsEntitlements.Response = TwitchGetDropsEntitlements.Response.from_json(result)
	parsed_result.response = response
	if parsed_result.pagination != null:
		var cursor: String = parsed_result.pagination.cursor
		if not opt: opt = TwitchGetDropsEntitlements.Opt.new()
		opt.after = cursor
		parsed_result._next_page = get_drops_entitlements.bind(opt)

	return parsed_result


## Updates the Drop entitlement’s fulfillment status.
##
## [no required query parameters to describe]
##
## https://dev.twitch.tv/docs/api/reference#update-drops-entitlements
func update_drops_entitlements(body: TwitchUpdateDropsEntitlements.Body) -> TwitchUpdateDropsEntitlements.Response:
	var path = "/entitlements/drops?"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_PATCH, body, "application/json")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("update_drops_entitlements", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchUpdateDropsEntitlements.Response = TwitchUpdateDropsEntitlements.Response.from_json(result)
	parsed_result.response = response

	return parsed_result


## Gets the specified configuration segment from the specified extension.
##
## extension_id - The ID of the extension that contains the configuration segment you want to get.
## segment - The type of configuration segment to get. Possible case-sensitive values are:
##
##    * broadcaster
##    * developer
##    * global
##
##    You may specify one or more segments. To specify multiple segments, include the `segment` parameter for each segment to get. For example, `segment=broadcaster&segment=developer`. Ignores duplicate segments.
##
## https://dev.twitch.tv/docs/api/reference#get-extension-configuration-segment
func get_extension_configuration_segment(opt: TwitchGetExtensionConfigurationSegment.Opt, extension_id: String, segment: String) -> TwitchGetExtensionConfigurationSegment.Response:
	var path = "/extensions/configurations?"
	var optionals: Dictionary[StringName, Variant] = {}
	if opt != null: optionals = opt.to_dict()
	path += "extension_id=" + str(extension_id) + "&"
	path += "segment=" + str(segment) + "&"
	if optionals.has("broadcaster_id"):
		path += "broadcaster_id=" + str(optionals.broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_GET, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("get_extension_configuration_segment", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchGetExtensionConfigurationSegment.Response = TwitchGetExtensionConfigurationSegment.Response.from_json(result)
	parsed_result.response = response

	return parsed_result


## Updates a configuration segment.
##
## [no required query parameters to describe]
##
## https://dev.twitch.tv/docs/api/reference#set-extension-configuration-segment
func set_extension_configuration_segment(body: TwitchSetExtensionConfigurationSegment.Body) -> BufferedHTTPClient.ResponseData:
	var path = "/extensions/configurations?"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_PUT, body, "application/json")

	if response.response_code >= 400:
		_handle_error("set_extension_configuration_segment", response)
	return response


## Updates the extension’s required_configuration string.
##
## broadcaster_id - The ID of the broadcaster that installed the extension on their channel.
##
## https://dev.twitch.tv/docs/api/reference#set-extension-required-configuration
func set_extension_required_configuration(body: TwitchSetExtensionRequiredConfiguration.Body, broadcaster_id: String) -> BufferedHTTPClient.ResponseData:
	var path = "/extensions/required_configuration?"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_PUT, body, "application/json")

	if response.response_code >= 400:
		_handle_error("set_extension_required_configuration", response)
	return response


## Sends a message to one or more viewers.
##
## [no required query parameters to describe]
##
## https://dev.twitch.tv/docs/api/reference#send-extension-pubsub-message
func send_extension_pubsub_message(body: TwitchSendExtensionPubSubMessage.Body) -> BufferedHTTPClient.ResponseData:
	var path = "/extensions/pubsub?"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_POST, body, "application/json")

	if response.response_code >= 400:
		_handle_error("send_extension_pubsub_message", response)
	return response


## Gets a list of broadcasters that are streaming live and have installed or activated the extension.
##
## extension_id - The ID of the extension to get. Returns the list of broadcasters that are live and that have installed or activated this extension.
##
## https://dev.twitch.tv/docs/api/reference#get-extension-live-channels
func get_extension_live_channels(opt: TwitchGetExtensionLiveChannels.Opt, extension_id: String) -> TwitchGetExtensionLiveChannels.Response:
	var path = "/extensions/live?"
	var optionals: Dictionary[StringName, Variant] = {}
	if opt != null: optionals = opt.to_dict()
	path += "extension_id=" + str(extension_id) + "&"
	if optionals.has("after"):
		path += "after=" + str(optionals.after) + "&"
	if optionals.has("first"):
		path += "first=" + str(optionals.first) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_GET, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("get_extension_live_channels", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchGetExtensionLiveChannels.Response = TwitchGetExtensionLiveChannels.Response.from_json(result)
	parsed_result.response = response
	if parsed_result.pagination != null:
		var cursor: String = parsed_result.pagination
		if not opt: opt = TwitchGetExtensionLiveChannels.Opt.new()
		opt.after = cursor
		parsed_result._next_page = get_extension_live_channels.bind(opt, extension_id)

	return parsed_result


## Gets an extension’s list of shared secrets.
##
## [no required query parameters to describe]
##
## https://dev.twitch.tv/docs/api/reference#get-extension-secrets
func get_extension_secrets() -> TwitchGetExtensionSecrets.Response:
	var path = "/extensions/jwt/secrets?"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_GET, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("get_extension_secrets", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchGetExtensionSecrets.Response = TwitchGetExtensionSecrets.Response.from_json(result)
	parsed_result.response = response

	return parsed_result


## Creates a shared secret used to sign and verify JWT tokens.
##
## extension_id - The ID of the extension to apply the shared secret to.
##
## https://dev.twitch.tv/docs/api/reference#create-extension-secret
func create_extension_secret(opt: TwitchCreateExtensionSecret.Opt, extension_id: String) -> TwitchCreateExtensionSecret.Response:
	var path = "/extensions/jwt/secrets?"
	var optionals: Dictionary[StringName, Variant] = {}
	if opt != null: optionals = opt.to_dict()
	path += "extension_id=" + str(extension_id) + "&"
	if optionals.has("delay"):
		path += "delay=" + str(optionals.delay) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_POST, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("create_extension_secret", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchCreateExtensionSecret.Response = TwitchCreateExtensionSecret.Response.from_json(result)
	parsed_result.response = response

	return parsed_result


## Sends a message to the specified broadcaster’s chat room.
##
## broadcaster_id - The ID of the broadcaster that has activated the extension.
##
## https://dev.twitch.tv/docs/api/reference#send-extension-chat-message
func send_extension_chat_message(body: TwitchSendExtensionChatMessage.Body, broadcaster_id: String) -> BufferedHTTPClient.ResponseData:
	var path = "/extensions/chat?"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_POST, body, "application/json")

	if response.response_code >= 400:
		_handle_error("send_extension_chat_message", response)
	return response


## Gets information about an extension.
##
## extension_id - The ID of the extension to get.
##
## https://dev.twitch.tv/docs/api/reference#get-extensions
func get_extensions(opt: TwitchGetExtensions.Opt, extension_id: String) -> TwitchGetExtensions.Response:
	var path = "/extensions?"
	var optionals: Dictionary[StringName, Variant] = {}
	if opt != null: optionals = opt.to_dict()
	path += "extension_id=" + str(extension_id) + "&"
	if optionals.has("extension_version"):
		path += "extension_version=" + str(optionals.extension_version) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_GET, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("get_extensions", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchGetExtensions.Response = TwitchGetExtensions.Response.from_json(result)
	parsed_result.response = response

	return parsed_result


## Gets information about a released extension.
##
## extension_id - The ID of the extension to get.
##
## https://dev.twitch.tv/docs/api/reference#get-released-extensions
func get_released_extensions(opt: TwitchGetReleasedExtensions.Opt, extension_id: String) -> TwitchGetReleasedExtensions.Response:
	var path = "/extensions/released?"
	var optionals: Dictionary[StringName, Variant] = {}
	if opt != null: optionals = opt.to_dict()
	path += "extension_id=" + str(extension_id) + "&"
	if optionals.has("extension_version"):
		path += "extension_version=" + str(optionals.extension_version) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_GET, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("get_released_extensions", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchGetReleasedExtensions.Response = TwitchGetReleasedExtensions.Response.from_json(result)
	parsed_result.response = response

	return parsed_result


## Gets the list of Bits products that belongs to the extension.
##
## [no required query parameters to describe]
##
## https://dev.twitch.tv/docs/api/reference#get-extension-bits-products
func get_extension_bits_products(opt: TwitchGetExtensionBitsProducts.Opt) -> TwitchGetExtensionBitsProducts.Response:
	var path = "/bits/extensions?"
	var optionals: Dictionary[StringName, Variant] = {}
	if opt != null: optionals = opt.to_dict()
	if optionals.has("should_include_all"):
		path += "should_include_all=" + str(optionals.should_include_all) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_GET, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("get_extension_bits_products", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchGetExtensionBitsProducts.Response = TwitchGetExtensionBitsProducts.Response.from_json(result)
	parsed_result.response = response

	return parsed_result


## Adds or updates a Bits product that the extension created.
##
## [no required query parameters to describe]
##
## https://dev.twitch.tv/docs/api/reference#update-extension-bits-product
func update_extension_bits_product(body: TwitchUpdateExtensionBitsProduct.Body) -> TwitchUpdateExtensionBitsProduct.Response:
	var path = "/bits/extensions?"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_PUT, body, "application/json")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("update_extension_bits_product", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchUpdateExtensionBitsProduct.Response = TwitchUpdateExtensionBitsProduct.Response.from_json(result)
	parsed_result.response = response

	return parsed_result


## Creates an EventSub subscription.
##
## [no required query parameters to describe]
##
## https://dev.twitch.tv/docs/api/reference#create-eventsub-subscription
func create_eventsub_subscription(body: TwitchCreateEventSubSubscription.Body) -> TwitchCreateEventSubSubscription.Response:
	var path = "/eventsub/subscriptions?"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_POST, body, "application/json")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("create_eventsub_subscription", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchCreateEventSubSubscription.Response = TwitchCreateEventSubSubscription.Response.from_json(result)
	parsed_result.response = response

	return parsed_result


## Deletes an EventSub subscription.
##
## id - The ID of the subscription to delete.
##
## https://dev.twitch.tv/docs/api/reference#delete-eventsub-subscription
func delete_eventsub_subscription(id: String) -> BufferedHTTPClient.ResponseData:
	var path = "/eventsub/subscriptions?"
	path += "id=" + str(id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_DELETE, "", "")

	if response.response_code >= 400:
		_handle_error("delete_eventsub_subscription", response)
	return response


## Gets a list of EventSub subscriptions that the client in the access token created.
##
## [no required query parameters to describe]
##
## https://dev.twitch.tv/docs/api/reference#get-eventsub-subscriptions
func get_eventsub_subscriptions(opt: TwitchGetEventsubSubscriptions.Opt) -> TwitchGetEventSubSubscriptions.Response:
	var path = "/eventsub/subscriptions?"
	var optionals: Dictionary[StringName, Variant] = {}
	if opt != null: optionals = opt.to_dict()
	if optionals.has("after"):
		path += "after=" + str(optionals.after) + "&"
	if optionals.has("status"):
		path += "status=" + str(optionals.status) + "&"
	if optionals.has("subscription_id"):
		path += "subscription_id=" + str(optionals.subscription_id) + "&"
	if optionals.has("type"):
		path += "type=" + str(optionals.type) + "&"
	if optionals.has("user_id"):
		path += "user_id=" + str(optionals.user_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_GET, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("get_eventsub_subscriptions", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchGetEventSubSubscriptions.Response = TwitchGetEventSubSubscriptions.Response.from_json(result)
	parsed_result.response = response
	if parsed_result.pagination != null:
		var cursor: String = parsed_result.pagination.cursor
		if not opt: opt = TwitchGetEventsubSubscriptions.Opt.new()
		opt.after = cursor
		parsed_result._next_page = get_eventsub_subscriptions.bind(opt)

	return parsed_result


## Gets information about all broadcasts on Twitch.
##
## [no required query parameters to describe]
##
## https://dev.twitch.tv/docs/api/reference#get-top-games
func get_top_games(opt: TwitchGetTopGames.Opt) -> TwitchGetTopGames.Response:
	var path = "/games/top?"
	var optionals: Dictionary[StringName, Variant] = {}
	if opt != null: optionals = opt.to_dict()
	if optionals.has("after"):
		path += "after=" + str(optionals.after) + "&"
	if optionals.has("before"):
		path += "before=" + str(optionals.before) + "&"
	if optionals.has("first"):
		path += "first=" + str(optionals.first) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_GET, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("get_top_games", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchGetTopGames.Response = TwitchGetTopGames.Response.from_json(result)
	parsed_result.response = response
	if parsed_result.pagination != null:
		var cursor: String = parsed_result.pagination.cursor
		if not opt: opt = TwitchGetTopGames.Opt.new()
		opt.after = cursor
		parsed_result._next_page = get_top_games.bind(opt)

	return parsed_result


## Gets information about specified games.
##
## [no required query parameters to describe]
##
## https://dev.twitch.tv/docs/api/reference#get-games
func get_games(opt: TwitchGetGames.Opt) -> TwitchGetGames.Response:
	var path = "/games?"
	var optionals: Dictionary[StringName, Variant] = {}
	if opt != null: optionals = opt.to_dict()
	if optionals.has("id"):

		for param in optionals.id:
			path += "id=" + str(param) + "&"
	if optionals.has("igdb_id"):

		for param in optionals.igdb_id:
			path += "igdb_id=" + str(param) + "&"
	if optionals.has("name"):

		for param in optionals.name:
			path += "name=" + str(param) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_GET, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("get_games", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchGetGames.Response = TwitchGetGames.Response.from_json(result)
	parsed_result.response = response

	return parsed_result


## Gets the broadcaster’s list of active goals.
##
## broadcaster_id - The ID of the broadcaster that created the goals. This ID must match the user ID in the user access token.
##
## https://dev.twitch.tv/docs/api/reference#get-creator-goals
func get_creator_goals(broadcaster_id: String) -> TwitchGetCreatorGoals.Response:
	var path = "/goals?"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_GET, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("get_creator_goals", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchGetCreatorGoals.Response = TwitchGetCreatorGoals.Response.from_json(result)
	parsed_result.response = response

	return parsed_result


## BETA Gets the channel settings for configuration of the Guest Star feature for a particular host.
##
## broadcaster_id - The ID of the broadcaster you want to get guest star settings for.
## moderator_id - The ID of the broadcaster or a user that has permission to moderate the broadcaster’s chat room. This ID must match the user ID in the user access token.
##
## https://dev.twitch.tv/docs/api/reference#get-channel-guest-star-settings
func get_channel_guest_star_settings(moderator_id: String, broadcaster_id: String) -> TwitchGetChannelGuestStarSettings.Response:
	var path = "/guest_star/channel_settings?"
	path += "moderator_id=" + str(moderator_id) + "&"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_GET, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("get_channel_guest_star_settings", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchGetChannelGuestStarSettings.Response = TwitchGetChannelGuestStarSettings.Response.from_json(result)
	parsed_result.response = response

	return parsed_result


## BETA Mutates the channel settings for configuration of the Guest Star feature for a particular host.
##
## broadcaster_id - The ID of the broadcaster you want to update Guest Star settings for.
##
## https://dev.twitch.tv/docs/api/reference#update-channel-guest-star-settings
func update_channel_guest_star_settings(body: TwitchUpdateChannelGuestStarSettings.Body, broadcaster_id: String) -> BufferedHTTPClient.ResponseData:
	var path = "/guest_star/channel_settings?"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_PUT, body, "application/json")

	if response.response_code >= 400:
		_handle_error("update_channel_guest_star_settings", response)
	return response


## BETA Gets information about an ongoing Guest Star session for a particular channel.
##
## broadcaster_id - ID for the user hosting the Guest Star session.
## moderator_id - The ID of the broadcaster or a user that has permission to moderate the broadcaster’s chat room. This ID must match the user ID in the user access token.
##
## https://dev.twitch.tv/docs/api/reference#get-guest-star-session
func get_guest_star_session(moderator_id: String, broadcaster_id: String) -> TwitchGetGuestStarSession.Response:
	var path = "/guest_star/session?"
	path += "moderator_id=" + str(moderator_id) + "&"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_GET, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("get_guest_star_session", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchGetGuestStarSession.Response = TwitchGetGuestStarSession.Response.from_json(result)
	parsed_result.response = response

	return parsed_result


## BETA Programmatically creates a Guest Star session on behalf of the broadcaster.
##
## broadcaster_id - The ID of the broadcaster you want to create a Guest Star session for. Provided `broadcaster_id` must match the `user_id` in the auth token.
##
## https://dev.twitch.tv/docs/api/reference#create-guest-star-session
func create_guest_star_session(broadcaster_id: String) -> TwitchCreateGuestStarSession.Response:
	var path = "/guest_star/session?"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_POST, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("create_guest_star_session", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchCreateGuestStarSession.Response = TwitchCreateGuestStarSession.Response.from_json(result)
	parsed_result.response = response

	return parsed_result


## BETA Programmatically ends a Guest Star session on behalf of the broadcaster.
##
## broadcaster_id - The ID of the broadcaster you want to end a Guest Star session for. Provided `broadcaster_id` must match the `user_id` in the auth token.
## session_id - ID for the session to end on behalf of the broadcaster.
##
## https://dev.twitch.tv/docs/api/reference#end-guest-star-session
func end_guest_star_session(session_id: String, broadcaster_id: String) -> BufferedHTTPClient.ResponseData:
	var path = "/guest_star/session?"
	path += "session_id=" + str(session_id) + "&"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_DELETE, "", "")

	if response.response_code >= 400:
		_handle_error("end_guest_star_session", response)
	return response


## BETA Provides the caller with a list of pending invites to a Guest Star session.
##
## broadcaster_id - The ID of the broadcaster running the Guest Star session.
## moderator_id - The ID of the broadcaster or a user that has permission to moderate the broadcaster’s chat room. This ID must match the `user_id` in the user access token.
## session_id - The session ID to query for invite status.
##
## https://dev.twitch.tv/docs/api/reference#get-guest-star-invites
func get_guest_star_invites(moderator_id: String, session_id: String, broadcaster_id: String) -> TwitchGetGuestStarInvites.Response:
	var path = "/guest_star/invites?"
	path += "moderator_id=" + str(moderator_id) + "&"
	path += "session_id=" + str(session_id) + "&"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_GET, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("get_guest_star_invites", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchGetGuestStarInvites.Response = TwitchGetGuestStarInvites.Response.from_json(result)
	parsed_result.response = response

	return parsed_result


## BETA Sends an invite to a specified guest on behalf of the broadcaster for a Guest Star session in progress.
##
## broadcaster_id - The ID of the broadcaster running the Guest Star session.
## moderator_id - The ID of the broadcaster or a user that has permission to moderate the broadcaster’s chat room. This ID must match the `user_id` in the user access token.
## session_id - The session ID for the invite to be sent on behalf of the broadcaster.
## guest_id - Twitch User ID for the guest to invite to the Guest Star session.
##
## https://dev.twitch.tv/docs/api/reference#send-guest-star-invite
func send_guest_star_invite(guest_id: String, moderator_id: String, session_id: String, broadcaster_id: String) -> BufferedHTTPClient.ResponseData:
	var path = "/guest_star/invites?"
	path += "guest_id=" + str(guest_id) + "&"
	path += "moderator_id=" + str(moderator_id) + "&"
	path += "session_id=" + str(session_id) + "&"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_POST, "", "")

	if response.response_code >= 400:
		_handle_error("send_guest_star_invite", response)
	return response


## BETA Revokes a previously sent invite for a Guest Star session.
##
## broadcaster_id - The ID of the broadcaster running the Guest Star session.
## moderator_id - The ID of the broadcaster or a user that has permission to moderate the broadcaster’s chat room. This ID must match the `user_id` in the user access token.
## session_id - The ID of the session for the invite to be revoked on behalf of the broadcaster.
## guest_id - Twitch User ID for the guest to revoke the Guest Star session invite from.
##
## https://dev.twitch.tv/docs/api/reference#delete-guest-star-invite
func delete_guest_star_invite(guest_id: String, moderator_id: String, session_id: String, broadcaster_id: String) -> BufferedHTTPClient.ResponseData:
	var path = "/guest_star/invites?"
	path += "guest_id=" + str(guest_id) + "&"
	path += "moderator_id=" + str(moderator_id) + "&"
	path += "session_id=" + str(session_id) + "&"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_DELETE, "", "")

	if response.response_code >= 400:
		_handle_error("delete_guest_star_invite", response)
	return response


## BETA Allows a previously invited user to be assigned a slot within the active Guest Star session.
##
## broadcaster_id - The ID of the broadcaster running the Guest Star session.
## moderator_id - The ID of the broadcaster or a user that has permission to moderate the broadcaster’s chat room. This ID must match the `user_id` in the user access token.
## session_id - The ID of the Guest Star session in which to assign the slot.
## guest_id - The Twitch User ID corresponding to the guest to assign a slot in the session. This user must already have an invite to this session, and have indicated that they are ready to join.
## slot_id - The slot assignment to give to the user. Must be a numeric identifier between “1” and “N” where N is the max number of slots for the session. Max number of slots allowed for the session is reported by [Get Channel Guest Star Settings](https://dev.twitch.tv/docs/api/reference#get-channel-guest-star-settings).
##
## https://dev.twitch.tv/docs/api/reference#assign-guest-star-slot
func assign_guest_star_slot(guest_id: String, moderator_id: String, session_id: String, slot_id: String, broadcaster_id: String) -> BufferedHTTPClient.ResponseData:
	var path = "/guest_star/slot?"
	path += "guest_id=" + str(guest_id) + "&"
	path += "moderator_id=" + str(moderator_id) + "&"
	path += "session_id=" + str(session_id) + "&"
	path += "slot_id=" + str(slot_id) + "&"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_POST, "", "")

	if response.response_code >= 400:
		_handle_error("assign_guest_star_slot", response)
	return response


## BETA Allows a user to update the assigned slot for a particular user within the active Guest Star session.
##
## broadcaster_id - The ID of the broadcaster running the Guest Star session.
## moderator_id - The ID of the broadcaster or a user that has permission to moderate the broadcaster’s chat room. This ID must match the `user_id` in the user access token.
## session_id - The ID of the Guest Star session in which to update slot settings.
## source_slot_id - The slot assignment previously assigned to a user.
##
## https://dev.twitch.tv/docs/api/reference#update-guest-star-slot
func update_guest_star_slot(opt: TwitchUpdateGuestStarSlot.Opt, moderator_id: String, session_id: String, source_slot_id: String, broadcaster_id: String) -> BufferedHTTPClient.ResponseData:
	var path = "/guest_star/slot?"
	var optionals: Dictionary[StringName, Variant] = {}
	if opt != null: optionals = opt.to_dict()
	path += "moderator_id=" + str(moderator_id) + "&"
	path += "session_id=" + str(session_id) + "&"
	path += "source_slot_id=" + str(source_slot_id) + "&"
	if optionals.has("destination_slot_id"):
		path += "destination_slot_id=" + str(optionals.destination_slot_id) + "&"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_PATCH, "", "")

	if response.response_code >= 400:
		_handle_error("update_guest_star_slot", response)
	return response


## BETA Allows a caller to remove a slot assignment from a user participating in an active Guest Star session.
##
## broadcaster_id - The ID of the broadcaster running the Guest Star session.
## moderator_id - The ID of the broadcaster or a user that has permission to moderate the broadcaster’s chat room. This ID must match the user ID in the user access token.
## session_id - The ID of the Guest Star session in which to remove the slot assignment.
## guest_id - The Twitch User ID corresponding to the guest to remove from the session.
## slot_id - The slot ID representing the slot assignment to remove from the session.
##
## https://dev.twitch.tv/docs/api/reference#delete-guest-star-slot
func delete_guest_star_slot(opt: TwitchDeleteGuestStarSlot.Opt, guest_id: String, moderator_id: String, session_id: String, slot_id: String, broadcaster_id: String) -> BufferedHTTPClient.ResponseData:
	var path = "/guest_star/slot?"
	var optionals: Dictionary[StringName, Variant] = {}
	if opt != null: optionals = opt.to_dict()
	path += "guest_id=" + str(guest_id) + "&"
	path += "moderator_id=" + str(moderator_id) + "&"
	path += "session_id=" + str(session_id) + "&"
	path += "slot_id=" + str(slot_id) + "&"
	if optionals.has("should_reinvite_guest"):
		path += "should_reinvite_guest=" + str(optionals.should_reinvite_guest) + "&"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_DELETE, "", "")

	if response.response_code >= 400:
		_handle_error("delete_guest_star_slot", response)
	return response


## BETA Allows a user to update slot settings for a particular guest within a Guest Star session.
##
## broadcaster_id - The ID of the broadcaster running the Guest Star session.
## moderator_id - The ID of the broadcaster or a user that has permission to moderate the broadcaster’s chat room. This ID must match the user ID in the user access token.
## session_id - The ID of the Guest Star session in which to update a slot’s settings.
## slot_id - The slot assignment that has previously been assigned to a user.
##
## https://dev.twitch.tv/docs/api/reference#update-guest-star-slot-settings
func update_guest_star_slot_settings(opt: TwitchUpdateGuestStarSlotSettings.Opt, moderator_id: String, session_id: String, slot_id: String, broadcaster_id: String) -> BufferedHTTPClient.ResponseData:
	var path = "/guest_star/slot_settings?"
	var optionals: Dictionary[StringName, Variant] = {}
	if opt != null: optionals = opt.to_dict()
	path += "moderator_id=" + str(moderator_id) + "&"
	path += "session_id=" + str(session_id) + "&"
	path += "slot_id=" + str(slot_id) + "&"
	if optionals.has("is_audio_enabled"):
		path += "is_audio_enabled=" + str(optionals.is_audio_enabled) + "&"
	if optionals.has("is_live"):
		path += "is_live=" + str(optionals.is_live) + "&"
	if optionals.has("is_video_enabled"):
		path += "is_video_enabled=" + str(optionals.is_video_enabled) + "&"
	if optionals.has("volume"):
		path += "volume=" + str(optionals.volume) + "&"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_PATCH, "", "")

	if response.response_code >= 400:
		_handle_error("update_guest_star_slot_settings", response)
	return response


## DEPRECATED Gets information about the broadcaster’s current or most recent Hype Train event.
##
## broadcaster_id - The ID of the broadcaster that’s running the Hype Train. This ID must match the User ID in the user access token.
##
## https://dev.twitch.tv/docs/api/reference#get-hype-train-events
func get_hype_train_events(opt: TwitchGetHypeTrainEvents.Opt, broadcaster_id: String) -> TwitchGetHypeTrainEvents.Response:
	var path = "/hypetrain/events?"
	var optionals: Dictionary[StringName, Variant] = {}
	if opt != null: optionals = opt.to_dict()
	if optionals.has("after"):
		path += "after=" + str(optionals.after) + "&"
	if optionals.has("first"):
		path += "first=" + str(optionals.first) + "&"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_GET, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("get_hype_train_events", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchGetHypeTrainEvents.Response = TwitchGetHypeTrainEvents.Response.from_json(result)
	parsed_result.response = response
	if parsed_result.pagination != null:
		var cursor: String = parsed_result.pagination.cursor
		if not opt: opt = TwitchGetHypeTrainEvents.Opt.new()
		opt.after = cursor
		parsed_result._next_page = get_hype_train_events.bind(opt, broadcaster_id)

	return parsed_result


## NEW Gets the status of a Hype Train for the specified broadcaster.
##
## broadcaster_id - The User ID of the channel broadcaster.
##
## https://dev.twitch.tv/docs/api/reference#get-hype-train-status
func get_hype_train_status(broadcaster_id: String) -> TwitchGetHypeTrainStatus.Response:
	var path = "/hypetrain/status?"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_GET, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("get_hype_train_status", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchGetHypeTrainStatus.Response = TwitchGetHypeTrainStatus.Response.from_json(result)
	parsed_result.response = response

	return parsed_result


## Checks whether AutoMod would flag the specified message for review.
##
## broadcaster_id - The ID of the broadcaster whose AutoMod settings and list of blocked terms are used to check the message. This ID must match the user ID in the access token.
##
## https://dev.twitch.tv/docs/api/reference#check-automod-status
func check_automod_status(body: TwitchCheckAutoModStatus.Body, broadcaster_id: String) -> TwitchCheckAutoModStatus.Response:
	var path = "/moderation/enforcements/status?"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_POST, body, "application/json")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("check_automod_status", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchCheckAutoModStatus.Response = TwitchCheckAutoModStatus.Response.from_json(result)
	parsed_result.response = response

	return parsed_result


## Allow or deny the message that AutoMod flagged for review.
##
## [no required query parameters to describe]
##
## https://dev.twitch.tv/docs/api/reference#manage-held-automod-messages
func manage_held_automod_messages(body: TwitchManageHeldAutoModMessages.Body) -> BufferedHTTPClient.ResponseData:
	var path = "/moderation/automod/message?"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_POST, body, "application/json")

	if response.response_code >= 400:
		_handle_error("manage_held_automod_messages", response)
	return response


## Gets the broadcaster’s AutoMod settings.
##
## broadcaster_id - The ID of the broadcaster whose AutoMod settings you want to get.
## moderator_id - The ID of the broadcaster or a user that has permission to moderate the broadcaster’s chat room. This ID must match the user ID in the user access token.
##
## https://dev.twitch.tv/docs/api/reference#get-automod-settings
func get_automod_settings(moderator_id: String, broadcaster_id: String) -> TwitchGetAutoModSettings.Response:
	var path = "/moderation/automod/settings?"
	path += "moderator_id=" + str(moderator_id) + "&"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_GET, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("get_automod_settings", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchGetAutoModSettings.Response = TwitchGetAutoModSettings.Response.from_json(result)
	parsed_result.response = response

	return parsed_result


## Updates the broadcaster’s AutoMod settings.
##
## broadcaster_id - The ID of the broadcaster whose AutoMod settings you want to update.
## moderator_id - The ID of the broadcaster or a user that has permission to moderate the broadcaster’s chat room. This ID must match the user ID in the user access token.
##
## https://dev.twitch.tv/docs/api/reference#update-automod-settings
func update_automod_settings(body: TwitchUpdateAutoModSettings.Body, moderator_id: String, broadcaster_id: String) -> TwitchUpdateAutoModSettings.Response:
	var path = "/moderation/automod/settings?"
	path += "moderator_id=" + str(moderator_id) + "&"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_PUT, body, "application/json")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("update_automod_settings", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchUpdateAutoModSettings.Response = TwitchUpdateAutoModSettings.Response.from_json(result)
	parsed_result.response = response

	return parsed_result


## Gets all users that the broadcaster banned or put in a timeout.
##
## broadcaster_id - The ID of the broadcaster whose list of banned users you want to get. This ID must match the user ID in the access token.
##
## https://dev.twitch.tv/docs/api/reference#get-banned-users
func get_banned_users(opt: TwitchGetBannedUsers.Opt, broadcaster_id: String) -> TwitchGetBannedUsers.Response:
	var path = "/moderation/banned?"
	var optionals: Dictionary[StringName, Variant] = {}
	if opt != null: optionals = opt.to_dict()
	if optionals.has("after"):
		path += "after=" + str(optionals.after) + "&"
	if optionals.has("before"):
		path += "before=" + str(optionals.before) + "&"
	if optionals.has("first"):
		path += "first=" + str(optionals.first) + "&"
	if optionals.has("user_id"):

		for param in optionals.user_id:
			path += "user_id=" + str(param) + "&"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_GET, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("get_banned_users", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchGetBannedUsers.Response = TwitchGetBannedUsers.Response.from_json(result)
	parsed_result.response = response
	if parsed_result.pagination != null:
		var cursor: String = parsed_result.pagination.cursor
		if not opt: opt = TwitchGetBannedUsers.Opt.new()
		opt.after = cursor
		parsed_result._next_page = get_banned_users.bind(opt, broadcaster_id)

	return parsed_result


## Bans a user from participating in a broadcaster’s chat room or puts them in a timeout.
##
## broadcaster_id - The ID of the broadcaster whose chat room the user is being banned from.
## moderator_id - The ID of the broadcaster or a user that has permission to moderate the broadcaster’s chat room. This ID must match the user ID in the user access token.
##
## https://dev.twitch.tv/docs/api/reference#ban-user
func ban_user(body: TwitchBanUser.Body, moderator_id: String, broadcaster_id: String) -> TwitchBanUser.Response:
	var path = "/moderation/bans?"
	path += "moderator_id=" + str(moderator_id) + "&"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_POST, body, "application/json")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("ban_user", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchBanUser.Response = TwitchBanUser.Response.from_json(result)
	parsed_result.response = response

	return parsed_result


## Removes the ban or timeout that was placed on the specified user.
##
## broadcaster_id - The ID of the broadcaster whose chat room the user is banned from chatting in.
## moderator_id - The ID of the broadcaster or a user that has permission to moderate the broadcaster’s chat room. This ID must match the user ID in the user access token.
## user_id - The ID of the user to remove the ban or timeout from.
##
## https://dev.twitch.tv/docs/api/reference#unban-user
func unban_user(moderator_id: String, user_id: String, broadcaster_id: String) -> BufferedHTTPClient.ResponseData:
	var path = "/moderation/bans?"
	path += "moderator_id=" + str(moderator_id) + "&"
	path += "user_id=" + str(user_id) + "&"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_DELETE, "", "")

	if response.response_code >= 400:
		_handle_error("unban_user", response)
	return response


## NEW Gets a list of unban requests for a broadcaster’s channel.
##
## broadcaster_id - The ID of the broadcaster whose channel is receiving unban requests.
## moderator_id - The ID of the broadcaster or a user that has permission to moderate the broadcaster’s unban requests. This ID must match the user ID in the user access token.
## status - Filter by a status.
##
##    * pending
##    * approved
##    * denied
##    * acknowledged
##    * canceled
##
## https://dev.twitch.tv/docs/api/reference#get-unban-requests
func get_unban_requests(opt: TwitchGetUnbanRequests.Opt, moderator_id: String, status: String, broadcaster_id: String) -> TwitchGetUnbanRequests.Response:
	var path = "/moderation/unban_requests?"
	var optionals: Dictionary[StringName, Variant] = {}
	if opt != null: optionals = opt.to_dict()
	path += "moderator_id=" + str(moderator_id) + "&"
	path += "status=" + str(status) + "&"
	if optionals.has("after"):
		path += "after=" + str(optionals.after) + "&"
	if optionals.has("first"):
		path += "first=" + str(optionals.first) + "&"
	if optionals.has("user_id"):
		path += "user_id=" + str(optionals.user_id) + "&"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_GET, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("get_unban_requests", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchGetUnbanRequests.Response = TwitchGetUnbanRequests.Response.from_json(result)
	parsed_result.response = response
	if parsed_result.pagination != null:
		var cursor: String = parsed_result.pagination.cursor
		if not opt: opt = TwitchGetUnbanRequests.Opt.new()
		opt.after = cursor
		parsed_result._next_page = get_unban_requests.bind(opt, moderator_id, status, broadcaster_id)

	return parsed_result


## NEW Resolves an unban request by approving or denying it.
##
## broadcaster_id - The ID of the broadcaster whose channel is approving or denying the unban request.
## moderator_id - The ID of the broadcaster or a user that has permission to moderate the broadcaster’s unban requests. This ID must match the user ID in the user access token.
## unban_request_id - The ID of the broadcaster or a user that has permission to moderate the broadcaster’s unban requests. This ID must match the user ID in the user access token.
## status - Resolution status.
##
##    * approved
##    * denied
##
## https://dev.twitch.tv/docs/api/reference#resolve-unban-requests
func resolve_unban_requests(opt: TwitchResolveUnbanRequests.Opt, moderator_id: String, status: String, unban_request_id: String, broadcaster_id: String) -> TwitchResolveUnbanRequests.Response:
	var path = "/moderation/unban_requests?"
	var optionals: Dictionary[StringName, Variant] = {}
	if opt != null: optionals = opt.to_dict()
	path += "moderator_id=" + str(moderator_id) + "&"
	path += "status=" + str(status) + "&"
	path += "unban_request_id=" + str(unban_request_id) + "&"
	if optionals.has("resolution_text"):
		path += "resolution_text=" + str(optionals.resolution_text) + "&"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_PATCH, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("resolve_unban_requests", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchResolveUnbanRequests.Response = TwitchResolveUnbanRequests.Response.from_json(result)
	parsed_result.response = response

	return parsed_result


## Gets the broadcaster’s list of non-private, blocked words or phrases.
##
## broadcaster_id - The ID of the broadcaster whose blocked terms you’re getting.
## moderator_id - The ID of the broadcaster or a user that has permission to moderate the broadcaster’s chat room. This ID must match the user ID in the user access token.
##
## https://dev.twitch.tv/docs/api/reference#get-blocked-terms
func get_blocked_terms(opt: TwitchGetBlockedTerms.Opt, moderator_id: String, broadcaster_id: String) -> TwitchGetBlockedTerms.Response:
	var path = "/moderation/blocked_terms?"
	var optionals: Dictionary[StringName, Variant] = {}
	if opt != null: optionals = opt.to_dict()
	path += "moderator_id=" + str(moderator_id) + "&"
	if optionals.has("after"):
		path += "after=" + str(optionals.after) + "&"
	if optionals.has("first"):
		path += "first=" + str(optionals.first) + "&"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_GET, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("get_blocked_terms", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchGetBlockedTerms.Response = TwitchGetBlockedTerms.Response.from_json(result)
	parsed_result.response = response
	if parsed_result.pagination != null:
		var cursor: String = parsed_result.pagination.cursor
		if not opt: opt = TwitchGetBlockedTerms.Opt.new()
		opt.after = cursor
		parsed_result._next_page = get_blocked_terms.bind(opt, moderator_id, broadcaster_id)

	return parsed_result


## Adds a word or phrase to the broadcaster’s list of blocked terms.
##
## broadcaster_id - The ID of the broadcaster that owns the list of blocked terms.
## moderator_id - The ID of the broadcaster or a user that has permission to moderate the broadcaster’s chat room. This ID must match the user ID in the user access token.
##
## https://dev.twitch.tv/docs/api/reference#add-blocked-term
func add_blocked_term(body: TwitchAddBlockedTerm.Body, moderator_id: String, broadcaster_id: String) -> TwitchAddBlockedTerm.Response:
	var path = "/moderation/blocked_terms?"
	path += "moderator_id=" + str(moderator_id) + "&"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_POST, body, "application/json")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("add_blocked_term", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchAddBlockedTerm.Response = TwitchAddBlockedTerm.Response.from_json(result)
	parsed_result.response = response

	return parsed_result


## Removes the word or phrase from the broadcaster’s list of blocked terms.
##
## broadcaster_id - The ID of the broadcaster that owns the list of blocked terms.
## moderator_id - The ID of the broadcaster or a user that has permission to moderate the broadcaster’s chat room. This ID must match the user ID in the user access token.
## id - The ID of the blocked term to remove from the broadcaster’s list of blocked terms.
##
## https://dev.twitch.tv/docs/api/reference#remove-blocked-term
func remove_blocked_term(id: String, moderator_id: String, broadcaster_id: String) -> BufferedHTTPClient.ResponseData:
	var path = "/moderation/blocked_terms?"
	path += "id=" + str(id) + "&"
	path += "moderator_id=" + str(moderator_id) + "&"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_DELETE, "", "")

	if response.response_code >= 400:
		_handle_error("remove_blocked_term", response)
	return response


## Removes a single chat message or all chat messages from the broadcaster’s chat room.
##
## broadcaster_id - The ID of the broadcaster that owns the chat room to remove messages from.
## moderator_id - The ID of the broadcaster or a user that has permission to moderate the broadcaster’s chat room. This ID must match the user ID in the user access token.
##
## https://dev.twitch.tv/docs/api/reference#delete-chat-messages
func delete_chat_messages(opt: TwitchDeleteChatMessages.Opt, moderator_id: String, broadcaster_id: String) -> BufferedHTTPClient.ResponseData:
	var path = "/moderation/chat?"
	var optionals: Dictionary[StringName, Variant] = {}
	if opt != null: optionals = opt.to_dict()
	path += "moderator_id=" + str(moderator_id) + "&"
	if optionals.has("message_id"):
		path += "message_id=" + str(optionals.message_id) + "&"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_DELETE, "", "")

	if response.response_code >= 400:
		_handle_error("delete_chat_messages", response)
	return response


## Gets a list of channels that the specified user has moderator privileges in.
##
## user_id - A user’s ID. Returns the list of channels that this user has moderator privileges in. This ID must match the user ID in the user OAuth token
##
## https://dev.twitch.tv/docs/api/reference#get-moderated-channels
func get_moderated_channels(opt: TwitchGetModeratedChannels.Opt, user_id: String) -> TwitchGetModeratedChannels.Response:
	var path = "/moderation/channels?"
	var optionals: Dictionary[StringName, Variant] = {}
	if opt != null: optionals = opt.to_dict()
	path += "user_id=" + str(user_id) + "&"
	if optionals.has("after"):
		path += "after=" + str(optionals.after) + "&"
	if optionals.has("first"):
		path += "first=" + str(optionals.first) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_GET, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("get_moderated_channels", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchGetModeratedChannels.Response = TwitchGetModeratedChannels.Response.from_json(result)
	parsed_result.response = response
	if parsed_result.pagination != null:
		var cursor: String = parsed_result.pagination.cursor
		if not opt: opt = TwitchGetModeratedChannels.Opt.new()
		opt.after = cursor
		parsed_result._next_page = get_moderated_channels.bind(opt, user_id)

	return parsed_result


## Gets all users allowed to moderate the broadcaster’s chat room.
##
## broadcaster_id - The ID of the broadcaster whose list of moderators you want to get. This ID must match the user ID in the access token.
##
## https://dev.twitch.tv/docs/api/reference#get-moderators
func get_moderators(opt: TwitchGetModerators.Opt, broadcaster_id: String) -> TwitchGetModerators.Response:
	var path = "/moderation/moderators?"
	var optionals: Dictionary[StringName, Variant] = {}
	if opt != null: optionals = opt.to_dict()
	if optionals.has("after"):
		path += "after=" + str(optionals.after) + "&"
	if optionals.has("first"):
		path += "first=" + str(optionals.first) + "&"
	if optionals.has("user_id"):

		for param in optionals.user_id:
			path += "user_id=" + str(param) + "&"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_GET, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("get_moderators", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchGetModerators.Response = TwitchGetModerators.Response.from_json(result)
	parsed_result.response = response
	if parsed_result.pagination != null:
		var cursor: String = parsed_result.pagination.cursor
		if not opt: opt = TwitchGetModerators.Opt.new()
		opt.after = cursor
		parsed_result._next_page = get_moderators.bind(opt, broadcaster_id)

	return parsed_result


## Adds a moderator to the broadcaster’s chat room.
##
## broadcaster_id - The ID of the broadcaster that owns the chat room. This ID must match the user ID in the access token.
## user_id - The ID of the user to add as a moderator in the broadcaster’s chat room.
##
## https://dev.twitch.tv/docs/api/reference#add-channel-moderator
func add_channel_moderator(user_id: String, broadcaster_id: String) -> BufferedHTTPClient.ResponseData:
	var path = "/moderation/moderators?"
	path += "user_id=" + str(user_id) + "&"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_POST, "", "")

	if response.response_code >= 400:
		_handle_error("add_channel_moderator", response)
	return response


## Removes a moderator from the broadcaster’s chat room.
##
## broadcaster_id - The ID of the broadcaster that owns the chat room. This ID must match the user ID in the access token.
## user_id - The ID of the user to remove as a moderator from the broadcaster’s chat room.
##
## https://dev.twitch.tv/docs/api/reference#remove-channel-moderator
func remove_channel_moderator(user_id: String, broadcaster_id: String) -> BufferedHTTPClient.ResponseData:
	var path = "/moderation/moderators?"
	path += "user_id=" + str(user_id) + "&"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_DELETE, "", "")

	if response.response_code >= 400:
		_handle_error("remove_channel_moderator", response)
	return response


## Gets a list of the broadcaster’s VIPs.
##
## broadcaster_id - The ID of the broadcaster whose list of VIPs you want to get. This ID must match the user ID in the access token.
##
## https://dev.twitch.tv/docs/api/reference#get-vips
func get_vips(opt: TwitchGetVips.Opt, broadcaster_id: String) -> TwitchGetVIPs.Response:
	var path = "/channels/vips?"
	var optionals: Dictionary[StringName, Variant] = {}
	if opt != null: optionals = opt.to_dict()
	if optionals.has("after"):
		path += "after=" + str(optionals.after) + "&"
	if optionals.has("first"):
		path += "first=" + str(optionals.first) + "&"
	if optionals.has("user_id"):

		for param in optionals.user_id:
			path += "user_id=" + str(param) + "&"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_GET, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("get_vips", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchGetVIPs.Response = TwitchGetVIPs.Response.from_json(result)
	parsed_result.response = response
	if parsed_result.pagination != null:
		var cursor: String = parsed_result.pagination.cursor
		if not opt: opt = TwitchGetVips.Opt.new()
		opt.after = cursor
		parsed_result._next_page = get_vips.bind(opt, broadcaster_id)

	return parsed_result


## Adds the specified user as a VIP in the broadcaster’s channel.
##
## user_id - The ID of the user to give VIP status to.
## broadcaster_id - The ID of the broadcaster that’s adding the user as a VIP. This ID must match the user ID in the access token.
##
## https://dev.twitch.tv/docs/api/reference#add-channel-vip
func add_channel_vip(user_id: String, broadcaster_id: String) -> BufferedHTTPClient.ResponseData:
	var path = "/channels/vips?"
	path += "user_id=" + str(user_id) + "&"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_POST, "", "")

	if response.response_code >= 400:
		_handle_error("add_channel_vip", response)
	return response


## Removes the specified user as a VIP in the broadcaster’s channel.
##
## user_id - The ID of the user to remove VIP status from.
## broadcaster_id - The ID of the broadcaster who owns the channel where the user has VIP status.
##
## https://dev.twitch.tv/docs/api/reference#remove-channel-vip
func remove_channel_vip(user_id: String, broadcaster_id: String) -> BufferedHTTPClient.ResponseData:
	var path = "/channels/vips?"
	path += "user_id=" + str(user_id) + "&"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_DELETE, "", "")

	if response.response_code >= 400:
		_handle_error("remove_channel_vip", response)
	return response


## Activates or deactivates the broadcaster’s Shield Mode.
##
## broadcaster_id - The ID of the broadcaster whose Shield Mode you want to activate or deactivate.
## moderator_id - The ID of the broadcaster or a user that is one of the broadcaster’s moderators. This ID must match the user ID in the access token.
##
## https://dev.twitch.tv/docs/api/reference#update-shield-mode-status
func update_shield_mode_status(body: TwitchUpdateShieldModeStatus.Body, moderator_id: String, broadcaster_id: String) -> TwitchUpdateShieldModeStatus.Response:
	var path = "/moderation/shield_mode?"
	path += "moderator_id=" + str(moderator_id) + "&"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_PUT, body, "application/json")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("update_shield_mode_status", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchUpdateShieldModeStatus.Response = TwitchUpdateShieldModeStatus.Response.from_json(result)
	parsed_result.response = response

	return parsed_result


## Gets the broadcaster’s Shield Mode activation status.
##
## broadcaster_id - The ID of the broadcaster whose Shield Mode activation status you want to get.
## moderator_id - The ID of the broadcaster or a user that is one of the broadcaster’s moderators. This ID must match the user ID in the access token.
##
## https://dev.twitch.tv/docs/api/reference#get-shield-mode-status
func get_shield_mode_status(moderator_id: String, broadcaster_id: String) -> TwitchGetShieldModeStatus.Response:
	var path = "/moderation/shield_mode?"
	path += "moderator_id=" + str(moderator_id) + "&"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_GET, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("get_shield_mode_status", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchGetShieldModeStatus.Response = TwitchGetShieldModeStatus.Response.from_json(result)
	parsed_result.response = response

	return parsed_result


## NEW Warns a user in the specified broadcaster’s chat room, preventing them from chat interaction until the warning is acknowledged.
##
## broadcaster_id - The ID of the channel in which the warning will take effect.
## moderator_id - The ID of the twitch user who requested the warning.
##
## https://dev.twitch.tv/docs/api/reference#warn-chat-user
func warn_chat_user(body: TwitchWarnChatUser.Body, moderator_id: String, broadcaster_id: String) -> TwitchWarnChatUser.Response:
	var path = "/moderation/warnings?"
	path += "moderator_id=" + str(moderator_id) + "&"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_POST, body, "application/json")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("warn_chat_user", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchWarnChatUser.Response = TwitchWarnChatUser.Response.from_json(result)
	parsed_result.response = response

	return parsed_result


## Gets a list of polls that the broadcaster created.
##
## broadcaster_id - The ID of the broadcaster that created the polls. This ID must match the user ID in the user access token.
##
## https://dev.twitch.tv/docs/api/reference#get-polls
func get_polls(opt: TwitchGetPolls.Opt, broadcaster_id: String) -> TwitchGetPolls.Response:
	var path = "/polls?"
	var optionals: Dictionary[StringName, Variant] = {}
	if opt != null: optionals = opt.to_dict()
	if optionals.has("after"):
		path += "after=" + str(optionals.after) + "&"
	if optionals.has("first"):
		path += "first=" + str(optionals.first) + "&"
	if optionals.has("id"):

		for param in optionals.id:
			path += "id=" + str(param) + "&"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_GET, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("get_polls", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchGetPolls.Response = TwitchGetPolls.Response.from_json(result)
	parsed_result.response = response
	if parsed_result.pagination != null:
		var cursor: String = parsed_result.pagination.cursor
		if not opt: opt = TwitchGetPolls.Opt.new()
		opt.after = cursor
		parsed_result._next_page = get_polls.bind(opt, broadcaster_id)

	return parsed_result


## Creates a poll that viewers in the broadcaster’s channel can vote on.
##
## [no required query parameters to describe]
##
## https://dev.twitch.tv/docs/api/reference#create-poll
func create_poll(body: TwitchCreatePoll.Body) -> TwitchCreatePoll.Response:
	var path = "/polls?"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_POST, body, "application/json")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("create_poll", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchCreatePoll.Response = TwitchCreatePoll.Response.from_json(result)
	parsed_result.response = response

	return parsed_result


## End an active poll.
##
## [no required query parameters to describe]
##
## https://dev.twitch.tv/docs/api/reference#end-poll
func end_poll(body: TwitchEndPoll.Body) -> TwitchEndPoll.Response:
	var path = "/polls?"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_PATCH, body, "application/json")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("end_poll", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchEndPoll.Response = TwitchEndPoll.Response.from_json(result)
	parsed_result.response = response

	return parsed_result


## Gets a list of Channel Points Predictions that the broadcaster created.
##
## broadcaster_id - The ID of the broadcaster whose predictions you want to get. This ID must match the user ID in the user access token.
##
## https://dev.twitch.tv/docs/api/reference#get-predictions
func get_predictions(opt: TwitchGetPredictions.Opt, broadcaster_id: String) -> TwitchGetPredictions.Response:
	var path = "/predictions?"
	var optionals: Dictionary[StringName, Variant] = {}
	if opt != null: optionals = opt.to_dict()
	if optionals.has("after"):
		path += "after=" + str(optionals.after) + "&"
	if optionals.has("first"):
		path += "first=" + str(optionals.first) + "&"
	if optionals.has("id"):

		for param in optionals.id:
			path += "id=" + str(param) + "&"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_GET, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("get_predictions", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchGetPredictions.Response = TwitchGetPredictions.Response.from_json(result)
	parsed_result.response = response
	if parsed_result.pagination != null:
		var cursor: String = parsed_result.pagination.cursor
		if not opt: opt = TwitchGetPredictions.Opt.new()
		opt.after = cursor
		parsed_result._next_page = get_predictions.bind(opt, broadcaster_id)

	return parsed_result


## Create a Channel Points Prediction.
##
## [no required query parameters to describe]
##
## https://dev.twitch.tv/docs/api/reference#create-prediction
func create_prediction(body: TwitchCreatePrediction.Body) -> TwitchCreatePrediction.Response:
	var path = "/predictions?"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_POST, body, "application/json")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("create_prediction", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchCreatePrediction.Response = TwitchCreatePrediction.Response.from_json(result)
	parsed_result.response = response

	return parsed_result


## Locks, resolves, or cancels a Channel Points Prediction.
##
## [no required query parameters to describe]
##
## https://dev.twitch.tv/docs/api/reference#end-prediction
func end_prediction(body: TwitchEndPrediction.Body) -> TwitchEndPrediction.Response:
	var path = "/predictions?"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_PATCH, body, "application/json")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("end_prediction", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchEndPrediction.Response = TwitchEndPrediction.Response.from_json(result)
	parsed_result.response = response

	return parsed_result


## Raid another channel by sending the broadcaster’s viewers to the targeted channel.
##
## [no required query parameters to describe]
##
## https://dev.twitch.tv/docs/api/reference#start-a-raid
func start_a_raid(opt: TwitchStartARaid.Opt) -> TwitchStartRaid.Response:
	var path = "/raids?"
	var optionals: Dictionary[StringName, Variant] = {}
	if opt != null: optionals = opt.to_dict()
	if optionals.has("from_broadcaster_id"):
		path += "from_broadcaster_id=" + str(optionals.from_broadcaster_id) + "&"
	if optionals.has("to_broadcaster_id"):
		path += "to_broadcaster_id=" + str(optionals.to_broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_POST, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("start_a_raid", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchStartRaid.Response = TwitchStartRaid.Response.from_json(result)
	parsed_result.response = response

	return parsed_result


## Cancel a pending raid.
##
## broadcaster_id - The ID of the broadcaster that initiated the raid. This ID must match the user ID in the user access token.
##
## https://dev.twitch.tv/docs/api/reference#cancel-a-raid
func cancel_a_raid(broadcaster_id: String) -> BufferedHTTPClient.ResponseData:
	var path = "/raids?"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_DELETE, "", "")

	if response.response_code >= 400:
		_handle_error("cancel_a_raid", response)
	return response


## Gets the broadcaster’s streaming schedule.
##
## broadcaster_id - The ID of the broadcaster that owns the streaming schedule you want to get.
##
## https://dev.twitch.tv/docs/api/reference#get-channel-stream-schedule
func get_channel_stream_schedule(opt: TwitchGetChannelStreamSchedule.Opt, broadcaster_id: String) -> TwitchGetChannelStreamSchedule.Response:
	var path = "/schedule?"
	var optionals: Dictionary[StringName, Variant] = {}
	if opt != null: optionals = opt.to_dict()
	if optionals.has("after"):
		path += "after=" + str(optionals.after) + "&"
	if optionals.has("first"):
		path += "first=" + str(optionals.first) + "&"
	if optionals.has("id"):

		for param in optionals.id:
			path += "id=" + str(param) + "&"
	if optionals.has("start_time"):
		path += "start_time=" + get_rfc_3339_date_format(optionals.start_time) + "&"
	if optionals.has("utc_offset"):
		path += "utc_offset=" + str(optionals.utc_offset) + "&"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_GET, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("get_channel_stream_schedule", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchGetChannelStreamSchedule.Response = TwitchGetChannelStreamSchedule.Response.from_json(result)
	parsed_result.response = response

	if parsed_result.data.pagination != null:
		opt.after = parsed_result.data.pagination.cursor
		parsed_result.data._next_page = get_channel_stream_schedule.bind(opt, broadcaster_id)

	return parsed_result


## Gets the broadcaster’s streaming schedule as an iCalendar.
##
## broadcaster_id - The ID of the broadcaster that owns the streaming schedule you want to get.
##
## https://dev.twitch.tv/docs/api/reference#get-channel-icalendar
func get_channel_icalendar(broadcaster_id: String) -> BufferedHTTPClient.ResponseData:
	var path = "/schedule/icalendar?"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_GET, "", "")

	if response.response_code >= 400:
		_handle_error("get_channel_icalendar", response)
	return response


## Updates the broadcaster’s schedule settings, such as scheduling a vacation.
##
## broadcaster_id - The ID of the broadcaster whose schedule settings you want to update. The ID must match the user ID in the user access token.
##
## https://dev.twitch.tv/docs/api/reference#update-channel-stream-schedule
func update_channel_stream_schedule(opt: TwitchUpdateChannelStreamSchedule.Opt, broadcaster_id: String) -> BufferedHTTPClient.ResponseData:
	var path = "/schedule/settings?"
	var optionals: Dictionary[StringName, Variant] = {}
	if opt != null: optionals = opt.to_dict()
	if optionals.has("is_vacation_enabled"):
		path += "is_vacation_enabled=" + str(optionals.is_vacation_enabled) + "&"
	if optionals.has("timezone"):
		path += "timezone=" + str(optionals.timezone) + "&"
	if optionals.has("vacation_end_time"):
		path += "vacation_end_time=" + get_rfc_3339_date_format(optionals.vacation_end_time) + "&"
	if optionals.has("vacation_start_time"):
		path += "vacation_start_time=" + get_rfc_3339_date_format(optionals.vacation_start_time) + "&"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_PATCH, "", "")

	if response.response_code >= 400:
		_handle_error("update_channel_stream_schedule", response)
	return response


## Adds a single or recurring broadcast to the broadcaster’s streaming schedule.
##
## broadcaster_id - The ID of the broadcaster that owns the schedule to add the broadcast segment to. This ID must match the user ID in the user access token.
##
## https://dev.twitch.tv/docs/api/reference#create-channel-stream-schedule-segment
func create_channel_stream_schedule_segment(body: TwitchCreateChannelStreamScheduleSegment.Body, broadcaster_id: String) -> TwitchCreateChannelStreamScheduleSegment.Response:
	var path = "/schedule/segment?"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_POST, body, "application/json")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("create_channel_stream_schedule_segment", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchCreateChannelStreamScheduleSegment.Response = TwitchCreateChannelStreamScheduleSegment.Response.from_json(result)
	parsed_result.response = response

	return parsed_result


## Updates a scheduled broadcast segment.
##
## broadcaster_id - The ID of the broadcaster who owns the broadcast segment to update. This ID must match the user ID in the user access token.
## id - The ID of the broadcast segment to update.
##
## https://dev.twitch.tv/docs/api/reference#update-channel-stream-schedule-segment
func update_channel_stream_schedule_segment(body: TwitchUpdateChannelStreamScheduleSegment.Body, id: String, broadcaster_id: String) -> TwitchUpdateChannelStreamScheduleSegment.Response:
	var path = "/schedule/segment?"
	path += "id=" + str(id) + "&"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_PATCH, body, "application/json")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("update_channel_stream_schedule_segment", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchUpdateChannelStreamScheduleSegment.Response = TwitchUpdateChannelStreamScheduleSegment.Response.from_json(result)
	parsed_result.response = response

	return parsed_result


## Deletes a broadcast from the broadcaster’s streaming schedule.
##
## broadcaster_id - The ID of the broadcaster that owns the streaming schedule. This ID must match the user ID in the user access token.
## id - The ID of the broadcast segment to remove.
##
## https://dev.twitch.tv/docs/api/reference#delete-channel-stream-schedule-segment
func delete_channel_stream_schedule_segment(id: String, broadcaster_id: String) -> BufferedHTTPClient.ResponseData:
	var path = "/schedule/segment?"
	path += "id=" + str(id) + "&"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_DELETE, "", "")

	if response.response_code >= 400:
		_handle_error("delete_channel_stream_schedule_segment", response)
	return response


## Gets the games or categories that match the specified query.
##
## query - The URI-encoded search string. For example, encode _#archery_ as `%23archery` and search strings like _angel of death_ as `angel%20of%20death`.
##
## https://dev.twitch.tv/docs/api/reference#search-categories
func search_categories(opt: TwitchSearchCategories.Opt, query: String) -> TwitchSearchCategories.Response:
	var path = "/search/categories?"
	var optionals: Dictionary[StringName, Variant] = {}
	if opt != null: optionals = opt.to_dict()
	path += "query=" + str(query) + "&"
	if optionals.has("after"):
		path += "after=" + str(optionals.after) + "&"
	if optionals.has("first"):
		path += "first=" + str(optionals.first) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_GET, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("search_categories", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchSearchCategories.Response = TwitchSearchCategories.Response.from_json(result)
	parsed_result.response = response
	if parsed_result.pagination != null:
		var cursor: String = parsed_result.pagination.cursor
		if not opt: opt = TwitchSearchCategories.Opt.new()
		opt.after = cursor
		parsed_result._next_page = search_categories.bind(opt, query)

	return parsed_result


## Gets the channels that match the specified query and have streamed content within the past 6 months.
##
## query - The URI-encoded search string. For example, encode search strings like _angel of death_ as `angel%20of%20death`.
##
## https://dev.twitch.tv/docs/api/reference#search-channels
func search_channels(opt: TwitchSearchChannels.Opt, query: String) -> TwitchSearchChannels.Response:
	var path = "/search/channels?"
	var optionals: Dictionary[StringName, Variant] = {}
	if opt != null: optionals = opt.to_dict()
	path += "query=" + str(query) + "&"
	if optionals.has("after"):
		path += "after=" + str(optionals.after) + "&"
	if optionals.has("first"):
		path += "first=" + str(optionals.first) + "&"
	if optionals.has("live_only"):
		path += "live_only=" + str(optionals.live_only) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_GET, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("search_channels", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchSearchChannels.Response = TwitchSearchChannels.Response.from_json(result)
	parsed_result.response = response
	if parsed_result.pagination != null:
		var cursor: String = parsed_result.pagination.cursor
		if not opt: opt = TwitchSearchChannels.Opt.new()
		opt.after = cursor
		parsed_result._next_page = search_channels.bind(opt, query)

	return parsed_result


## Gets the channel’s stream key.
##
## broadcaster_id - The ID of the broadcaster that owns the channel. The ID must match the user ID in the access token.
##
## https://dev.twitch.tv/docs/api/reference#get-stream-key
func get_stream_key(broadcaster_id: String) -> TwitchGetStreamKey.Response:
	var path = "/streams/key?"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_GET, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("get_stream_key", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchGetStreamKey.Response = TwitchGetStreamKey.Response.from_json(result)
	parsed_result.response = response

	return parsed_result


## Gets a list of all streams.
##
## [no required query parameters to describe]
##
## https://dev.twitch.tv/docs/api/reference#get-streams
func get_streams(opt: TwitchGetStreams.Opt) -> TwitchGetStreams.Response:
	var path = "/streams?"
	var optionals: Dictionary[StringName, Variant] = {}
	if opt != null: optionals = opt.to_dict()
	if optionals.has("after"):
		path += "after=" + str(optionals.after) + "&"
	if optionals.has("before"):
		path += "before=" + str(optionals.before) + "&"
	if optionals.has("first"):
		path += "first=" + str(optionals.first) + "&"
	if optionals.has("game_id"):

		for param in optionals.game_id:
			path += "game_id=" + str(param) + "&"
	if optionals.has("language"):

		for param in optionals.language:
			path += "language=" + str(param) + "&"
	if optionals.has("type"):
		path += "type=" + str(optionals.type) + "&"
	if optionals.has("user_id"):

		for param in optionals.user_id:
			path += "user_id=" + str(param) + "&"
	if optionals.has("user_login"):

		for param in optionals.user_login:
			path += "user_login=" + str(param) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_GET, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("get_streams", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchGetStreams.Response = TwitchGetStreams.Response.from_json(result)
	parsed_result.response = response
	if parsed_result.pagination != null:
		var cursor: String = parsed_result.pagination.cursor
		if not opt: opt = TwitchGetStreams.Opt.new()
		opt.after = cursor
		parsed_result._next_page = get_streams.bind(opt)

	return parsed_result


## Gets the list of broadcasters that the user follows and that are streaming live.
##
## user_id - The ID of the user whose list of followed streams you want to get. This ID must match the user ID in the access token.
##
## https://dev.twitch.tv/docs/api/reference#get-followed-streams
func get_followed_streams(opt: TwitchGetFollowedStreams.Opt, user_id: String) -> TwitchGetFollowedStreams.Response:
	var path = "/streams/followed?"
	var optionals: Dictionary[StringName, Variant] = {}
	if opt != null: optionals = opt.to_dict()
	path += "user_id=" + str(user_id) + "&"
	if optionals.has("after"):
		path += "after=" + str(optionals.after) + "&"
	if optionals.has("first"):
		path += "first=" + str(optionals.first) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_GET, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("get_followed_streams", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchGetFollowedStreams.Response = TwitchGetFollowedStreams.Response.from_json(result)
	parsed_result.response = response
	if parsed_result.pagination != null:
		var cursor: String = parsed_result.pagination.cursor
		if not opt: opt = TwitchGetFollowedStreams.Opt.new()
		opt.after = cursor
		parsed_result._next_page = get_followed_streams.bind(opt, user_id)

	return parsed_result


## Adds a marker to a live stream.
##
## [no required query parameters to describe]
##
## https://dev.twitch.tv/docs/api/reference#create-stream-marker
func create_stream_marker(body: TwitchCreateStreamMarker.Body) -> TwitchCreateStreamMarker.Response:
	var path = "/streams/markers?"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_POST, body, "application/json")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("create_stream_marker", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchCreateStreamMarker.Response = TwitchCreateStreamMarker.Response.from_json(result)
	parsed_result.response = response

	return parsed_result


## Gets a list of markers from the user’s most recent stream or from the specified VOD/video.
##
## [no required query parameters to describe]
##
## https://dev.twitch.tv/docs/api/reference#get-stream-markers
func get_stream_markers(opt: TwitchGetStreamMarkers.Opt) -> TwitchGetStreamMarkers.Response:
	var path = "/streams/markers?"
	var optionals: Dictionary[StringName, Variant] = {}
	if opt != null: optionals = opt.to_dict()
	if optionals.has("after"):
		path += "after=" + str(optionals.after) + "&"
	if optionals.has("before"):
		path += "before=" + str(optionals.before) + "&"
	if optionals.has("first"):
		path += "first=" + str(optionals.first) + "&"
	if optionals.has("user_id"):
		path += "user_id=" + str(optionals.user_id) + "&"
	if optionals.has("video_id"):
		path += "video_id=" + str(optionals.video_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_GET, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("get_stream_markers", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchGetStreamMarkers.Response = TwitchGetStreamMarkers.Response.from_json(result)
	parsed_result.response = response
	if parsed_result.pagination != null:
		var cursor: String = parsed_result.pagination.cursor
		if not opt: opt = TwitchGetStreamMarkers.Opt.new()
		opt.after = cursor
		parsed_result._next_page = get_stream_markers.bind(opt)

	return parsed_result


## Gets a list of users that subscribe to the specified broadcaster.
##
## broadcaster_id - The broadcaster’s ID. This ID must match the user ID in the access token.
##
## https://dev.twitch.tv/docs/api/reference#get-broadcaster-subscriptions
func get_broadcaster_subscriptions(opt: TwitchGetBroadcasterSubscriptions.Opt, broadcaster_id: String) -> TwitchGetBroadcasterSubscriptions.Response:
	var path = "/subscriptions?"
	var optionals: Dictionary[StringName, Variant] = {}
	if opt != null: optionals = opt.to_dict()
	if optionals.has("after"):
		path += "after=" + str(optionals.after) + "&"
	if optionals.has("before"):
		path += "before=" + str(optionals.before) + "&"
	if optionals.has("first"):
		path += "first=" + str(optionals.first) + "&"
	if optionals.has("user_id"):

		for param in optionals.user_id:
			path += "user_id=" + str(param) + "&"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_GET, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("get_broadcaster_subscriptions", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchGetBroadcasterSubscriptions.Response = TwitchGetBroadcasterSubscriptions.Response.from_json(result)
	parsed_result.response = response
	if parsed_result.pagination != null:
		var cursor: String = parsed_result.pagination.cursor
		if not opt: opt = TwitchGetBroadcasterSubscriptions.Opt.new()
		opt.after = cursor
		parsed_result._next_page = get_broadcaster_subscriptions.bind(opt, broadcaster_id)

	return parsed_result


## Checks whether the user subscribes to the broadcaster’s channel.
##
## broadcaster_id - The ID of a partner or affiliate broadcaster.
## user_id - The ID of the user that you’re checking to see whether they subscribe to the broadcaster in _broadcaster\_id_. This ID must match the user ID in the access Token.
##
## https://dev.twitch.tv/docs/api/reference#check-user-subscription
func check_user_subscription(user_id: String, broadcaster_id: String) -> TwitchCheckUserSubscription.Response:
	var path = "/subscriptions/user?"
	path += "user_id=" + str(user_id) + "&"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_GET, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("check_user_subscription", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchCheckUserSubscription.Response = TwitchCheckUserSubscription.Response.from_json(result)
	parsed_result.response = response

	return parsed_result


## Gets the list of all stream tags that Twitch defines. You can also filter the list by one or more tag IDs.
##
## [no required query parameters to describe]
##
## https://dev.twitch.tv/docs/api/reference#get-all-stream-tags
func get_all_stream_tags(opt: TwitchGetAllStreamTags.Opt) -> TwitchGetAllStreamTags.Response:
	var path = "/tags/streams?"
	var optionals: Dictionary[StringName, Variant] = {}
	if opt != null: optionals = opt.to_dict()
	if optionals.has("after"):
		path += "after=" + str(optionals.after) + "&"
	if optionals.has("first"):
		path += "first=" + str(optionals.first) + "&"
	if optionals.has("tag_id"):

		for param in optionals.tag_id:
			path += "tag_id=" + str(param) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_GET, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("get_all_stream_tags", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchGetAllStreamTags.Response = TwitchGetAllStreamTags.Response.from_json(result)
	parsed_result.response = response
	if parsed_result.pagination != null:
		var cursor: String = parsed_result.pagination.cursor
		if not opt: opt = TwitchGetAllStreamTags.Opt.new()
		opt.after = cursor
		parsed_result._next_page = get_all_stream_tags.bind(opt)

	return parsed_result


## Gets the list of stream tags that the broadcaster or Twitch added to their channel.
##
## broadcaster_id - The ID of the broadcaster whose stream tags you want to get.
##
## https://dev.twitch.tv/docs/api/reference#get-stream-tags
func get_stream_tags(broadcaster_id: String) -> TwitchGetStreamTags.Response:
	var path = "/streams/tags?"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_GET, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("get_stream_tags", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchGetStreamTags.Response = TwitchGetStreamTags.Response.from_json(result)
	parsed_result.response = response

	return parsed_result


## Gets the list of Twitch teams that the broadcaster is a member of.
##
## broadcaster_id - The ID of the broadcaster whose teams you want to get.
##
## https://dev.twitch.tv/docs/api/reference#get-channel-teams
func get_channel_teams(broadcaster_id: String) -> TwitchGetChannelTeams.Response:
	var path = "/teams/channel?"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_GET, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("get_channel_teams", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchGetChannelTeams.Response = TwitchGetChannelTeams.Response.from_json(result)
	parsed_result.response = response

	return parsed_result


## Gets information about the specified Twitch team.
##
## [no required query parameters to describe]
##
## https://dev.twitch.tv/docs/api/reference#get-teams
func get_teams(opt: TwitchGetTeams.Opt) -> TwitchGetTeams.Response:
	var path = "/teams?"
	var optionals: Dictionary[StringName, Variant] = {}
	if opt != null: optionals = opt.to_dict()
	if optionals.has("id"):
		path += "id=" + str(optionals.id) + "&"
	if optionals.has("name"):
		path += "name=" + str(optionals.name) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_GET, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("get_teams", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchGetTeams.Response = TwitchGetTeams.Response.from_json(result)
	parsed_result.response = response

	return parsed_result


## Gets information about one or more users.
##
## [no required query parameters to describe]
##
## https://dev.twitch.tv/docs/api/reference#get-users
func get_users(opt: TwitchGetUsers.Opt) -> TwitchGetUsers.Response:
	var path = "/users?"
	var optionals: Dictionary[StringName, Variant] = {}
	if opt != null: optionals = opt.to_dict()
	if optionals.has("id"):

		for param in optionals.id:
			path += "id=" + str(param) + "&"
	if optionals.has("login"):

		for param in optionals.login:
			path += "login=" + str(param) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_GET, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("get_users", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchGetUsers.Response = TwitchGetUsers.Response.from_json(result)
	parsed_result.response = response

	return parsed_result


## Updates the user’s information.
##
## [no required query parameters to describe]
##
## https://dev.twitch.tv/docs/api/reference#update-user
func update_user(opt: TwitchUpdateUser.Opt) -> TwitchUpdateUser.Response:
	var path = "/users?"
	var optionals: Dictionary[StringName, Variant] = {}
	if opt != null: optionals = opt.to_dict()
	if optionals.has("description"):
		path += "description=" + str(optionals.description) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_PUT, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("update_user", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchUpdateUser.Response = TwitchUpdateUser.Response.from_json(result)
	parsed_result.response = response

	return parsed_result


## Gets the list of users that the broadcaster has blocked.
##
## broadcaster_id - The ID of the broadcaster whose list of blocked users you want to get.
##
## https://dev.twitch.tv/docs/api/reference#get-user-block-list
func get_user_block_list(opt: TwitchGetUserBlockList.Opt, broadcaster_id: String) -> TwitchGetUserBlockList.Response:
	var path = "/users/blocks?"
	var optionals: Dictionary[StringName, Variant] = {}
	if opt != null: optionals = opt.to_dict()
	if optionals.has("after"):
		path += "after=" + str(optionals.after) + "&"
	if optionals.has("first"):
		path += "first=" + str(optionals.first) + "&"
	path += "broadcaster_id=" + str(broadcaster_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_GET, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("get_user_block_list", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchGetUserBlockList.Response = TwitchGetUserBlockList.Response.from_json(result)
	parsed_result.response = response
	if parsed_result.pagination != null:
		var cursor: String = parsed_result.pagination.cursor
		if not opt: opt = TwitchGetUserBlockList.Opt.new()
		opt.after = cursor
		parsed_result._next_page = get_user_block_list.bind(opt, broadcaster_id)

	return parsed_result


## Blocks the specified user from interacting with or having contact with the broadcaster.
##
## target_user_id - The ID of the user to block. The API ignores the request if the broadcaster has already blocked the user.
##
## https://dev.twitch.tv/docs/api/reference#block-user
func block_user(opt: TwitchBlockUser.Opt, target_user_id: String) -> BufferedHTTPClient.ResponseData:
	var path = "/users/blocks?"
	var optionals: Dictionary[StringName, Variant] = {}
	if opt != null: optionals = opt.to_dict()
	path += "target_user_id=" + str(target_user_id) + "&"
	if optionals.has("reason"):
		path += "reason=" + str(optionals.reason) + "&"
	if optionals.has("source_context"):
		path += "source_context=" + str(optionals.source_context) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_PUT, "", "")

	if response.response_code >= 400:
		_handle_error("block_user", response)
	return response


## Removes the user from the broadcaster’s list of blocked users.
##
## target_user_id - The ID of the user to remove from the broadcaster’s list of blocked users. The API ignores the request if the broadcaster hasn’t blocked the user.
##
## https://dev.twitch.tv/docs/api/reference#unblock-user
func unblock_user(target_user_id: String) -> BufferedHTTPClient.ResponseData:
	var path = "/users/blocks?"
	path += "target_user_id=" + str(target_user_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_DELETE, "", "")

	if response.response_code >= 400:
		_handle_error("unblock_user", response)
	return response


## Gets a list of all extensions (both active and inactive) that the broadcaster has installed.
##
## [no required query parameters to describe]
##
## https://dev.twitch.tv/docs/api/reference#get-user-extensions
func get_user_extensions() -> TwitchGetUserExtensions.Response:
	var path = "/users/extensions/list?"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_GET, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("get_user_extensions", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchGetUserExtensions.Response = TwitchGetUserExtensions.Response.from_json(result)
	parsed_result.response = response

	return parsed_result


## Gets the active extensions that the broadcaster has installed for each configuration.
##
## [no required query parameters to describe]
##
## https://dev.twitch.tv/docs/api/reference#get-user-active-extensions
func get_user_active_extensions(opt: TwitchGetUserActiveExtensions.Opt) -> TwitchGetUserActiveExtensions.Response:
	var path = "/users/extensions?"
	var optionals: Dictionary[StringName, Variant] = {}
	if opt != null: optionals = opt.to_dict()
	if optionals.has("user_id"):
		path += "user_id=" + str(optionals.user_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_GET, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("get_user_active_extensions", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchGetUserActiveExtensions.Response = TwitchGetUserActiveExtensions.Response.from_json(result)
	parsed_result.response = response

	return parsed_result


## Updates an installed extension’s information.
##
## [no required query parameters to describe]
##
## https://dev.twitch.tv/docs/api/reference#update-user-extensions
func update_user_extensions(body: TwitchUpdateUserExtensions.Body) -> TwitchUpdateUserExtensions.Response:
	var path = "/users/extensions?"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_PUT, body, "application/json")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("update_user_extensions", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchUpdateUserExtensions.Response = TwitchUpdateUserExtensions.Response.from_json(result)
	parsed_result.response = response

	return parsed_result


## Gets information about one or more published videos.
##
## [no required query parameters to describe]
##
## https://dev.twitch.tv/docs/api/reference#get-videos
func get_videos(opt: TwitchGetVideos.Opt) -> TwitchGetVideos.Response:
	var path = "/videos?"
	var optionals: Dictionary[StringName, Variant] = {}
	if opt != null: optionals = opt.to_dict()
	if optionals.has("after"):
		path += "after=" + str(optionals.after) + "&"
	if optionals.has("before"):
		path += "before=" + str(optionals.before) + "&"
	if optionals.has("first"):
		path += "first=" + str(optionals.first) + "&"
	if optionals.has("game_id"):
		path += "game_id=" + str(optionals.game_id) + "&"
	if optionals.has("id"):

		for param in optionals.id:
			path += "id=" + str(param) + "&"
	if optionals.has("language"):
		path += "language=" + str(optionals.language) + "&"
	if optionals.has("period"):
		path += "period=" + str(optionals.period) + "&"
	if optionals.has("sort"):
		path += "sort=" + str(optionals.sort) + "&"
	if optionals.has("type"):
		path += "type=" + str(optionals.type) + "&"
	if optionals.has("user_id"):
		path += "user_id=" + str(optionals.user_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_GET, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("get_videos", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchGetVideos.Response = TwitchGetVideos.Response.from_json(result)
	parsed_result.response = response
	if parsed_result.pagination != null:
		var cursor: String = parsed_result.pagination.cursor
		if not opt: opt = TwitchGetVideos.Opt.new()
		opt.after = cursor
		parsed_result._next_page = get_videos.bind(opt)

	return parsed_result


## Deletes one or more videos.
##
## id - The list of videos to delete. To specify more than one video, include the _id_ parameter for each video to delete. For example, `id=1234&id=5678`. You can delete a maximum of 5 videos per request. Ignores invalid video IDs.
##
##    If the user doesn’t have permission to delete one of the videos in the list, none of the videos are deleted.
##
## https://dev.twitch.tv/docs/api/reference#delete-videos
func delete_videos(id: Array[String]) -> TwitchDeleteVideos.Response:
	var path = "/videos?"

	for param in id:
		path += "id=" + str(param) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_DELETE, "", "")

	var result: Variant = {}
	if response.response_code >= 400:
		_handle_error("delete_videos", response)
	else:
		result = JSON.parse_string(response.response_data.get_string_from_utf8())

	var parsed_result: TwitchDeleteVideos.Response = TwitchDeleteVideos.Response.from_json(result)
	parsed_result.response = response

	return parsed_result


## Sends a whisper message to the specified user.
##
## from_user_id - The ID of the user sending the whisper. This user must have a verified phone number. This ID must match the user ID in the user access token.
## to_user_id - The ID of the user to receive the whisper.
##
## https://dev.twitch.tv/docs/api/reference#send-whisper
func send_whisper(body: TwitchSendWhisper.Body, from_user_id: String, to_user_id: String) -> BufferedHTTPClient.ResponseData:
	var path = "/whispers?"
	path += "from_user_id=" + str(from_user_id) + "&"
	path += "to_user_id=" + str(to_user_id) + "&"

	var response: BufferedHTTPClient.ResponseData = await request(path, HTTPClient.METHOD_POST, body, "application/json")

	if response.response_code >= 400:
		_handle_error("send_whisper", response)
	return response
