mirror of
https://github.com/jakejarvis/sofa.git
synced 2026-08-29 06:15:39 -04:00
When a user finishes watching on their media server, a webhook fires and Sofa logs it as watched, triggering all existing auto-transitions. Each user configures their connection in settings and gets a unique webhook URL. - Add webhookConnections and webhookEventLog schema tables - Add TMDB findByExternalId for resolving IMDB/TVDB IDs - Add source parameter to tracking functions (plex/jellyfin) - Add webhook processing service with payload parsers, title resolution, and deduplication - Add public webhook receiver route (token-based auth) - Add authenticated settings API routes for managing connections - Add Media Servers section to settings UI with Plex/Jellyfin cards Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
134 lines
2.6 KiB
TypeScript
134 lines
2.6 KiB
TypeScript
export interface TmdbSearchResult {
|
|
id: number;
|
|
media_type: "movie" | "tv" | "person";
|
|
title?: string;
|
|
name?: string;
|
|
original_title?: string;
|
|
original_name?: string;
|
|
overview: string;
|
|
release_date?: string;
|
|
first_air_date?: string;
|
|
poster_path: string | null;
|
|
backdrop_path: string | null;
|
|
popularity: number;
|
|
vote_average: number;
|
|
vote_count: number;
|
|
}
|
|
|
|
export interface TmdbSearchResponse {
|
|
page: number;
|
|
results: TmdbSearchResult[];
|
|
total_pages: number;
|
|
total_results: number;
|
|
}
|
|
|
|
export interface TmdbMovieDetails {
|
|
id: number;
|
|
title: string;
|
|
original_title: string;
|
|
overview: string;
|
|
release_date: string;
|
|
poster_path: string | null;
|
|
backdrop_path: string | null;
|
|
popularity: number;
|
|
vote_average: number;
|
|
vote_count: number;
|
|
status: string;
|
|
}
|
|
|
|
export interface TmdbTvDetails {
|
|
id: number;
|
|
name: string;
|
|
original_name: string;
|
|
overview: string;
|
|
first_air_date: string;
|
|
poster_path: string | null;
|
|
backdrop_path: string | null;
|
|
popularity: number;
|
|
vote_average: number;
|
|
vote_count: number;
|
|
status: string;
|
|
number_of_seasons: number;
|
|
seasons: TmdbSeasonSummary[];
|
|
}
|
|
|
|
export interface TmdbSeasonSummary {
|
|
id: number;
|
|
season_number: number;
|
|
name: string;
|
|
overview: string;
|
|
poster_path: string | null;
|
|
air_date: string | null;
|
|
episode_count: number;
|
|
}
|
|
|
|
export interface TmdbSeasonDetails {
|
|
id: number;
|
|
season_number: number;
|
|
name: string;
|
|
overview: string;
|
|
poster_path: string | null;
|
|
air_date: string | null;
|
|
episodes: TmdbEpisode[];
|
|
}
|
|
|
|
export interface TmdbEpisode {
|
|
id: number;
|
|
episode_number: number;
|
|
name: string;
|
|
overview: string;
|
|
still_path: string | null;
|
|
air_date: string | null;
|
|
runtime: number | null;
|
|
}
|
|
|
|
export interface TmdbWatchProviderResponse {
|
|
id: number;
|
|
results: Record<
|
|
string,
|
|
{
|
|
link?: string;
|
|
flatrate?: TmdbProvider[];
|
|
rent?: TmdbProvider[];
|
|
buy?: TmdbProvider[];
|
|
free?: TmdbProvider[];
|
|
ads?: TmdbProvider[];
|
|
}
|
|
>;
|
|
}
|
|
|
|
export interface TmdbProvider {
|
|
provider_id: number;
|
|
provider_name: string;
|
|
logo_path: string;
|
|
display_priority: number;
|
|
}
|
|
|
|
export interface TmdbRecommendationResponse {
|
|
page: number;
|
|
results: TmdbSearchResult[];
|
|
total_pages: number;
|
|
total_results: number;
|
|
}
|
|
|
|
export interface TmdbFindResult {
|
|
movie_results: TmdbSearchResult[];
|
|
tv_results: TmdbSearchResult[];
|
|
tv_episode_results: {
|
|
id: number;
|
|
episode_number: number;
|
|
name: string;
|
|
season_number: number;
|
|
show_id: number;
|
|
}[];
|
|
}
|
|
|
|
export interface TmdbGenre {
|
|
id: number;
|
|
name: string;
|
|
}
|
|
|
|
export interface TmdbGenreListResponse {
|
|
genres: TmdbGenre[];
|
|
}
|