Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
375 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
49 changes: 49 additions & 0 deletions
49
packages/twitch/src/API/Helix/Schedule/HelixPaginatedScheduleSegmentRequest.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import type { TwitchApiCallOptions } from 'twitch-api-call'; | ||
import type { UserIdResolvable } from 'twitch-common'; | ||
import { extractUserId } from 'twitch-common'; | ||
import type { ApiClient } from '../../../ApiClient'; | ||
import { HelixPaginatedRequest } from '../HelixPaginatedRequest'; | ||
import type { HelixPaginatedResponse } from '../HelixResponse'; | ||
import type { HelixScheduleResponse } from './HelixSchedule'; | ||
import type { HelixScheduleFilter } from './HelixScheduleApi'; | ||
import type { HelixScheduleSegmentData } from './HelixScheduleSegment'; | ||
import { HelixScheduleSegment } from './HelixScheduleSegment'; | ||
|
||
/** | ||
* A paginator specifically for schedule segments. | ||
*/ | ||
export class HelixPaginatedScheduleSegmentRequest extends HelixPaginatedRequest< | ||
HelixScheduleSegmentData, | ||
HelixScheduleSegment | ||
> { | ||
/** @private */ | ||
constructor(broadcaster: UserIdResolvable, client: ApiClient, filter?: HelixScheduleFilter) { | ||
super( | ||
{ | ||
url: 'schedule', | ||
query: { | ||
broadcaster_id: extractUserId(broadcaster), | ||
start_time: filter?.startDate, | ||
utc_offset: filter?.utcOffset?.toString() | ||
} | ||
}, | ||
client, | ||
data => new HelixScheduleSegment(data, client), | ||
25 | ||
); | ||
} | ||
|
||
// sadly, this hack is necessary to work around the weird data model of schedules | ||
// while still keeping the pagination code as generic as possible | ||
/** @private */ | ||
protected async _fetchData( | ||
additionalOptions: Partial<TwitchApiCallOptions> = {} | ||
): Promise<HelixPaginatedResponse<HelixScheduleSegmentData>> { | ||
const origData = ((await super._fetchData(additionalOptions)) as unknown) as HelixScheduleResponse; | ||
|
||
return { | ||
data: origData.data.segments, | ||
pagination: origData.pagination | ||
}; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
import { Enumerable } from '@d-fischer/shared-utils'; | ||
import type { ApiClient } from '../../../ApiClient'; | ||
import type { HelixUser } from '../User/HelixUser'; | ||
import type { HelixScheduleSegmentData } from './HelixScheduleSegment'; | ||
import { HelixScheduleSegment } from './HelixScheduleSegment'; | ||
|
||
/** @private */ | ||
export interface HelixScheduleVacationData { | ||
start_time: string; | ||
end_time: string; | ||
} | ||
|
||
/** @private */ | ||
export interface HelixScheduleData { | ||
segments: HelixScheduleSegmentData[]; | ||
broadcaster_id: string; | ||
broadcaster_name: string; | ||
broadcaster_login: string; | ||
vacation: HelixScheduleVacationData | null; | ||
} | ||
|
||
/** @private */ | ||
export interface HelixScheduleResponse { | ||
data: HelixScheduleData; | ||
pagination: { | ||
cursor?: string; | ||
}; | ||
} | ||
|
||
/** | ||
* A schedule of a channel. | ||
*/ | ||
export class HelixSchedule { | ||
@Enumerable(false) private readonly _data: HelixScheduleData; | ||
@Enumerable(false) private readonly _client: ApiClient; | ||
|
||
/** @private */ | ||
constructor(data: HelixScheduleData, client: ApiClient) { | ||
this._data = data; | ||
this._client = client; | ||
} | ||
|
||
/** | ||
* The segments of the schedule. | ||
*/ | ||
get segments(): HelixScheduleSegment[] { | ||
return this._data.segments.map(data => new HelixScheduleSegment(data, this._client)); | ||
} | ||
|
||
/** | ||
* The ID of the broadcaster. | ||
*/ | ||
get broadcasterId(): string { | ||
return this._data.broadcaster_id; | ||
} | ||
|
||
/** | ||
* The name of the broadcaster. | ||
*/ | ||
get broadcasterName(): string { | ||
return this._data.broadcaster_login; | ||
} | ||
|
||
/** | ||
* The display name of the broadcaster. | ||
*/ | ||
get broadcasterDisplayName(): string { | ||
return this._data.broadcaster_name; | ||
} | ||
|
||
/** | ||
* Retrieves more information about the broadcaster. | ||
*/ | ||
async getBroadcaster(): Promise<HelixUser> { | ||
return (await this._client.helix.users.getUserById(this._data.broadcaster_id))!; | ||
} | ||
|
||
/** | ||
* The date when the current vacation started, or null if the schedule is not in vacation mode. | ||
*/ | ||
get vacationStartDate(): Date | null { | ||
const timestamp = this._data.vacation?.start_time; | ||
|
||
return timestamp ? new Date(timestamp) : null; | ||
} | ||
|
||
/** | ||
* The date when the current vacation ends, or null if the schedule is not in vacation mode. | ||
*/ | ||
get vacationEndDate(): Date | null { | ||
const timestamp = this._data.vacation?.end_time; | ||
|
||
return timestamp ? new Date(timestamp) : null; | ||
} | ||
} |
125 changes: 125 additions & 0 deletions
125
packages/twitch/src/API/Helix/Schedule/HelixScheduleApi.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
import { TwitchApiCallType } from 'twitch-api-call'; | ||
import type { UserIdResolvable } from 'twitch-common'; | ||
import { extractUserId } from 'twitch-common'; | ||
import { BaseApi } from '../../BaseApi'; | ||
import type { HelixForwardPagination } from '../HelixPagination'; | ||
import { makePaginationQuery } from '../HelixPagination'; | ||
import { HelixPaginatedScheduleSegmentRequest } from './HelixPaginatedScheduleSegmentRequest'; | ||
import type { HelixScheduleResponse } from './HelixSchedule'; | ||
import { HelixSchedule } from './HelixSchedule'; | ||
import { HelixScheduleSegment } from './HelixScheduleSegment'; | ||
|
||
/** | ||
* Filters for the schedule request. | ||
*/ | ||
export interface HelixScheduleFilter { | ||
/** | ||
* The earliest date to find schedule segments for. | ||
*/ | ||
startDate?: string; | ||
|
||
/** | ||
* The offset from UTC you request for, to ensure everything goes to the correct day. | ||
*/ | ||
utcOffset?: number; | ||
} | ||
|
||
/** | ||
* @inheritDoc | ||
*/ | ||
export interface HelixPaginatedScheduleFilter extends HelixScheduleFilter, HelixForwardPagination {} | ||
|
||
/** | ||
* The result of a schedule request. | ||
*/ | ||
export interface HelixPaginatedScheduleResult { | ||
/** | ||
* The actual schedule object. | ||
*/ | ||
data: HelixSchedule; | ||
|
||
/** | ||
* The pagination cursor. | ||
*/ | ||
cursor?: string; | ||
} | ||
|
||
/** | ||
* The Helix API methods that deal with schedules. | ||
*/ | ||
export class HelixScheduleApi extends BaseApi { | ||
/** | ||
* Retrieves the schedule for a given broadcaster. | ||
* | ||
* @param broadcaster The broadcaster to get the schedule of. | ||
* @param filter | ||
* | ||
* @expandParams | ||
*/ | ||
async getSchedule( | ||
broadcaster: UserIdResolvable, | ||
filter?: HelixPaginatedScheduleFilter | ||
): Promise<HelixPaginatedScheduleResult> { | ||
const result = await this._client.callApi<HelixScheduleResponse>({ | ||
type: TwitchApiCallType.Helix, | ||
url: 'schedule', | ||
query: { | ||
broadcaster_id: extractUserId(broadcaster), | ||
start_time: filter?.startDate, | ||
utc_offset: filter?.utcOffset?.toString(), | ||
...makePaginationQuery(filter) | ||
} | ||
}); | ||
|
||
return { | ||
data: new HelixSchedule(result.data, this._client), | ||
cursor: result.pagination.cursor | ||
}; | ||
} | ||
|
||
/** | ||
* Creates a paginator for schedule segments for a given broadcaster. | ||
* | ||
* @param broadcaster The broadcaster to get the schedule segments of. | ||
* @param filter | ||
* | ||
* @expandParams | ||
*/ | ||
getScheduleSegmentsPaginated( | ||
broadcaster: UserIdResolvable, | ||
filter?: HelixScheduleFilter | ||
): HelixPaginatedScheduleSegmentRequest { | ||
return new HelixPaginatedScheduleSegmentRequest(broadcaster, this._client, filter); | ||
} | ||
|
||
/** | ||
* Retrieves a set of schedule segments by IDs. | ||
* | ||
* @param broadcaster The broadcaster to get schedule segments of. | ||
* @param ids The IDs of the schedule segments. | ||
*/ | ||
async getScheduleSegmentsByIds(broadcaster: UserIdResolvable, ids: string[]): Promise<HelixScheduleSegment[]> { | ||
const result = await this._client.callApi<HelixScheduleResponse>({ | ||
type: TwitchApiCallType.Helix, | ||
url: 'schedule', | ||
query: { | ||
broadcaster_id: extractUserId(broadcaster), | ||
id: ids | ||
} | ||
}); | ||
|
||
return result.data.segments.map(data => new HelixScheduleSegment(data, this._client)); | ||
} | ||
|
||
/** | ||
* Retrieves a single schedule segment by ID. | ||
* | ||
* @param broadcaster The broadcaster to get a schedule segment of. | ||
* @param id The ID of the schedule segment. | ||
*/ | ||
async getScheduleSegmentById(broadcaster: UserIdResolvable, id: string): Promise<HelixScheduleSegment | null> { | ||
const segments = await this.getScheduleSegmentsByIds(broadcaster, [id]); | ||
|
||
return segments.length ? segments[0] : null; | ||
} | ||
} |
Oops, something went wrong.