<commit_before>import { TwitchApiCallType } from 'twitch-api-call';
import type { UserIdResolvable } from '../../../Toolkit/UserTools';
import { extractUserId } from '../../../Toolkit/UserTools';
import { BaseApi } from '../../BaseApi';
import { HelixPaginatedRequestWithTotal } from '../HelixPaginatedRequestWithTotal';
import type { HelixWebHookSubscriptionData } from './HelixWebHookSubscription';
import { HelixWebHookSubscription } from './HelixWebHookSubscription';

/**
 * The properties describing where and how long a WebHook notification is sent, and how it is signed.
 */
export interface HelixWebHookHubRequestOptions {
	/**
	 * The URL to send notifications to.
	 */
	callbackUrl: string;

	/**
	 * The number of seconds the subscription is valid for. Defaults to 3600 (1 hour). Can be at most 864000 (10 days).
	 */
	validityInSeconds?: number;

	/**
	 * The secret to sign the notification payloads with.
	 */
	secret?: string;
}

/**
 * The properties describing the WebHook to create or remove.
 *
 * @inheritDoc
 */
export interface HelixWebHookHubRequest extends HelixWebHookHubRequestOptions {
	/**
	 * Whether to subscribe or unsubscribe from notifications.
	 */
	mode: HubMode;

	/**
	 * What topic URL to subscribe to or unsubscribe from.
	 */
	topicUrl: string;

	/**
	 * The OAuth scope necessary to subscribe to or unsubscribe from the given topic.
	 */
	scope?: string;
}

/**
 * Whether to subscribe or unsubscribe from notifications.
 */
export type HubMode = 'subscribe' | 'unsubscribe';

/**
 * The API methods that deal with WebHooks.
 *
 * Can be accessed using `client.helix.webHooks` on an {@ApiClient} instance.
 *
 * ## Before using these methods...
 *
 * All of the methods in this class assume that you are already running a working WebHook listener at the given callback URL.
 *
 * If you don't already have one, we recommend use of the `twitch-webhooks` library, which handles subscribing and unsubscribing to these topics automatically.
 *
 * ## Example
 * ```ts
 * const client = new ApiClient(new StaticAuthProvider(clientId, accessToken));
 * const accepted = await client.helix.webHooks.subscribeToUserFollowsTo('125328655', { callbackUrl: 'https://example.com' });
 * ```
 */
export class HelixWebHooksApi extends BaseApi {
	// TODO rename to getSubscriptionsPaginated and make sync
	/**
	 * Retrieves the current WebHook subscriptions for the current client.
	 *
	 * Requires an app access token to work; does not work with user tokens.
	 */
	async getSubscriptions(): Promise<
		HelixPaginatedRequestWithTotal<HelixWebHookSubscriptionData, HelixWebHookSubscription>
	> {
		return new HelixPaginatedRequestWithTotal(
			{
				url: 'webhooks/subscriptions'
			},
			this._client,
			(data: HelixWebHookSubscriptionData) => new HelixWebHookSubscription(data, this._client)
		);
	}

	/**
	 * Sends an arbitrary request to subscribe to or unsubscribe from an event.
	 *
	 * @expandParams
	 */
	async sendHubRequest(options: HelixWebHookHubRequest): Promise<void> {
		const { mode, callbackUrl, topicUrl, validityInSeconds = 3600, secret, scope } = options;
		await this._client.callApi({
			url: 'webhooks/hub',
			type: TwitchApiCallType.Helix,
			method: 'POST',
			scope,
			jsonBody: {
				'hub.mode': mode,
				'hub.topic': topicUrl,
				'hub.callback': callbackUrl,
				'hub.lease_seconds': mode === 'subscribe' ? validityInSeconds.toString() : undefined,
				'hub.secret': secret
			}
		});
	}

	/**
	 * Subscribes to events representing a user following other users.
	 *
	 * @expandParams
	 *
	 * @param user The user for which to get notifications about the users they will follow.
	 * @param options
	 */
	async subscribeToUserFollowsFrom(user: UserIdResolvable, options: HelixWebHookHubRequestOptions): Promise<void> {
		return this._sendUserFollowsHubRequest('subscribe', 'from', user, options);
	}

	/**
	 * Subscribes to events representing a user being followed by other users.
	 *
	 * @expandParams
	 *
	 * @param user The user for which to get notifications about the users they will be followed by.
	 * @param options
	 */
	async subscribeToUserFollowsTo(user: UserIdResolvable, options: HelixWebHookHubRequestOptions): Promise<void> {
		return this._sendUserFollowsHubRequest('subscribe', 'to', user, options);
	}

	/**
	 * Unsubscribes from events representing a user following other users.
	 *
	 * @expandParams
	 *
	 * @param user The user for which to not get any more notifications about the users they will follow.
	 * @param options
	 */
	async unsubscribeFromUserFollowsFrom(
		user: UserIdResolvable,
		options: HelixWebHookHubRequestOptions
	): Promise<void> {
		return this._sendUserFollowsHubRequest('unsubscribe', 'from', user, options);
	}

	/**
	 * Subscribes to events representing a hypetrain progressing.
	 *
	 * @expandParams
	 *
	 * @param broadcasterId The broadcaster / channel for which to get notifications about hypetrain events.
	 * @param options
	 */
	async subscribeToHypeTrainEvents(broadcasterId: UserIdResolvable, options: HelixWebHookHubRequestOptions) {
		return this._sendHypeTrainEventHubRequest('subscribe', broadcasterId, options);
	}

	/**
	 * Unsubscribes from events representing a user following other users.
	 *
	 * @expandParams
	 *
	 * @param user The user for which to not get any more notifications about the users they will follow.
	 * @param options
	 */
	async unsubscribeFromHypeTrainEvents(broadcasterId: UserIdResolvable, options: HelixWebHookHubRequestOptions) {
		return this._sendUserFollowsHubRequest('unsubscribe', 'from', broadcasterId, options);
	}

	/**
	 * Unsubscribes from events representing a user being followed by other users.<commit_msg>Update HelixWebHooksApi.ts<commit_after>import { TwitchApiCallType } from 'twitch-api-call';
import type { UserIdResolvable } from '../../../Toolkit/UserTools';
import { extractUserId } from '../../../Toolkit/UserTools';
import { BaseApi } from '../../BaseApi';
import { HelixPaginatedRequestWithTotal } from '../HelixPaginatedRequestWithTotal';
import type { HelixWebHookSubscriptionData } from './HelixWebHookSubscription';
import { HelixWebHookSubscription } from './HelixWebHookSubscription';

/**
 * The properties describing where and how long a WebHook notification is sent, and how it is signed.
 */
export interface HelixWebHookHubRequestOptions {
	/**
	 * The URL to send notifications to.
	 */
	callbackUrl: string;

	/**
	 * The number of seconds the subscription is valid for. Defaults to 3600 (1 hour). Can be at most 864000 (10 days).
	 */
	validityInSeconds?: number;

	/**
	 * The secret to sign the notification payloads with.
	 */
	secret?: string;
}

/**
 * The properties describing the WebHook to create or remove.
 *
 * @inheritDoc
 */
export interface HelixWebHookHubRequest extends HelixWebHookHubRequestOptions {
	/**
	 * Whether to subscribe or unsubscribe from notifications.
	 */
	mode: HubMode;

	/**
	 * What topic URL to subscribe to or unsubscribe from.
	 */
	topicUrl: string;

	/**
	 * The OAuth scope necessary to subscribe to or unsubscribe from the given topic.
	 */
	scope?: string;
}

/**
 * Whether to subscribe or unsubscribe from notifications.
 */
export type HubMode = 'subscribe' | 'unsubscribe';

/**
 * The API methods that deal with WebHooks.
 *
 * Can be accessed using `client.helix.webHooks` on an {@ApiClient} instance.
 *
 * ## Before using these methods...
 *
 * All of the methods in this class assume that you are already running a working WebHook listener at the given callback URL.
 *
 * If you don't already have one, we recommend use of the `twitch-webhooks` library, which handles subscribing and unsubscribing to these topics automatically.
 *
 * ## Example
 * ```ts
 * const client = new ApiClient(new StaticAuthProvider(clientId, accessToken));
 * const accepted = await client.helix.webHooks.subscribeToUserFollowsTo('125328655', { callbackUrl: 'https://example.com' });
 * ```
 */
export class HelixWebHooksApi extends BaseApi {
	// TODO rename to getSubscriptionsPaginated and make sync
	/**
	 * Retrieves the current WebHook subscriptions for the current client.
	 *
	 * Requires an app access token to work; does not work with user tokens.
	 */
	async getSubscriptions(): Promise<
		HelixPaginatedRequestWithTotal<HelixWebHookSubscriptionData, HelixWebHookSubscription>
	> {
		return new HelixPaginatedRequestWithTotal(
			{
				url: 'webhooks/subscriptions'
			},
			this._client,
			(data: HelixWebHookSubscriptionData) => new HelixWebHookSubscription(data, this._client)
		);
	}

	/**
	 * Sends an arbitrary request to subscribe to or unsubscribe from an event.
	 *
	 * @expandParams
	 */
	async sendHubRequest(options: HelixWebHookHubRequest): Promise<void> {
		const { mode, callbackUrl, topicUrl, validityInSeconds = 3600, secret, scope } = options;
		await this._client.callApi({
			url: 'webhooks/hub',
			type: TwitchApiCallType.Helix,
			method: 'POST',
			scope,
			jsonBody: {
				'hub.mode': mode,
				'hub.topic': topicUrl,
				'hub.callback': callbackUrl,
				'hub.lease_seconds': mode === 'subscribe' ? validityInSeconds.toString() : undefined,
				'hub.secret': secret
			}
		});
	}

	/**
	 * Subscribes to events representing a user following other users.
	 *
	 * @expandParams
	 *
	 * @param user The user for which to get notifications about the users they will follow.
	 * @param options
	 */
	async subscribeToUserFollowsFrom(user: UserIdResolvable, options: HelixWebHookHubRequestOptions): Promise<void> {
		return this._sendUserFollowsHubRequest('subscribe', 'from', user, options);
	}

	/**
	 * Subscribes to events representing a user being followed by other users.
	 *
	 * @expandParams
	 *
	 * @param user The user for which to get notifications about the users they will be followed by.
	 * @param options
	 */
	async subscribeToUserFollowsTo(user: UserIdResolvable, options: HelixWebHookHubRequestOptions): Promise<void> {
		return this._sendUserFollowsHubRequest('subscribe', 'to', user, options);
	}

	/**
	 * Unsubscribes from events representing a user following other users.
	 *
	 * @expandParams
	 *
	 * @param user The user for which to not get any more notifications about the users they will follow.
	 * @param options
	 */
	async unsubscribeFromUserFollowsFrom(
		user: UserIdResolvable,
		options: HelixWebHookHubRequestOptions
	): Promise<void> {
		return this._sendUserFollowsHubRequest('unsubscribe', 'from', user, options);
	}

	/**
	 * Subscribes to events representing a hypetrain progressing.
	 *
	 * @expandParams
	 *
	 * @param broadcasterId The broadcaster / channel for which to get notifications about hypetrain events.
	 * @param options
	 */
	async subscribeToHypeTrainEvents(broadcasterId: UserIdResolvable, options: HelixWebHookHubRequestOptions) {
		return this._sendHypeTrainEventHubRequest('subscribe', broadcasterId, options);
	}

	/**
	 * Unsubscribes from events representing a hypetrain progressing.
	 *
	 * @expandParams
	 *
	 * @param boradcasterId The broadcaster / channel for which to get notifications about hypetrain events.
	 * @param options
	 */
	async unsubscribeFromHypeTrainEvents(broadcasterId: UserIdResolvable, options: HelixWebHookHubRequestOptions) {
		return this._sendUserFollowsHubRequest('unsubscribe', 'from', broadcasterId, options);
	}

	/**
	 * Unsubscribes from events representing a user being followed by other users.
{'fraction_non_alphanumeric': 0.09886333597673803, 'fraction_numerical': 0.004581901489117984, 'mean_word_length': 4.201649862511458, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 17, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4151237', 'n_tokens_mistral': 3461, 'n_tokens_neox': 3171, 'n_words': 1063}