From 0f2258a8d56aca485d67759c70ce8740b6be7a05 Mon Sep 17 00:00:00 2001 From: Shinei Nouzen <157171073+Shineii86@users.noreply.github.com> Date: Tue, 13 Oct 2026 07:00:21 +0530 Subject: [PATCH] =?UTF-8?q?feat:=20v2.5.1=20=E2=80=94=20domain=20sync,=20s?= =?UTF-8?q?potlight=20fix,=20embed=20providers,=20info=20IDs,=20latest-epi?= =?UTF-8?q?sode=20checker,=20full=20docs=20pass?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Sync mirror domains with official hub (anikoto.site): replace dead anikoto.se with official anikototv.se (dataUrl.js, render.yaml, README) - Fix redesigned #hotest spotlight carousel selectors in homeInfo and spotlight extractors (dual-selector fallback for old layout) - New GET /api/stream/embeds: iframe-ready Megavid/AniXo/MegaPlay URLs that bypass Cloudflare; ?slug= auto-resolves MAL/AniList IDs (cached), or pass ?mal=/?anilist= directly with zero scraping - GET /api/info now returns externalIds { animeId, malId, anilistId } for direct feed into /api/stream/embeds (best-effort, 60min cache) - New GET /api/episodes/latest?slug=: newest-episode checker for bot polling — latest episode + counts only (10min cache), registered before /episodes/:id so the literal path wins - Top rankings ?sort=day|week|month verified already supported (docs) - Full repo-style documentation on all new modules (box headers, FEATURE markers, NOTE/TIP inline notes, JSDoc, footers) - Diagnostic sweep: all counts synced to 40 endpoints / 30 handlers / 29 scrapers, stale badges and sample responses fixed, render.yaml EOF, Dockerfile node:18-alpine (EOL) -> node:22-alpine - Tests: 38 passed / 0 failed / 2 optional skips; 77 JS files syntax-OK --- .gitignore | 3 +- CHANGELOG.md | 39 ++++ Dockerfile | 2 +- README.md | 37 +-- docs/architecture.md | 19 +- docs/endpoints.md | 95 +++++++- docs/index.md | 18 +- docs/streaming.md | 53 ++++- package-lock.json | 4 +- package.json | 2 +- public/index.html | 22 +- render.yaml | 2 +- src/configs/dataUrl.js | 3 +- src/configs/embedProviders.config.js | 81 +++++++ src/controllers/animeInfo.controller.js | 16 ++ src/controllers/embedProviders.controller.js | 109 +++++++++ src/controllers/episodeLatest.controller.js | 105 +++++++++ src/extractors/embedProviders.extractor.js | 228 +++++++++++++++++++ src/extractors/homeInfo.extractor.js | 40 +++- src/extractors/spotlight.extractor.js | 39 +++- src/helper/cache.helper.js | 1 + src/routes/apiRoutes.js | 26 ++- test.js | 4 + 23 files changed, 870 insertions(+), 78 deletions(-) create mode 100644 src/configs/embedProviders.config.js create mode 100644 src/controllers/embedProviders.controller.js create mode 100644 src/controllers/episodeLatest.controller.js create mode 100644 src/extractors/embedProviders.extractor.js diff --git a/.gitignore b/.gitignore index f48416b..1223355 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ node_modules/ .env .DS_Store -*.log \ No newline at end of file +*.log +*.pid diff --git a/CHANGELOG.md b/CHANGELOG.md index e3de49b..fee16b4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,45 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [2.5.1] - 2026-10-13 + +### Added +- **Direct Embed Providers**: New `GET /api/stream/embeds` endpoint returning iframe-ready player URLs for **Megavid** (megavid.buzz), **AniXo** (anixo.buzz) and **MegaPlay** (megaplay.buzz) — bypasses Cloudflare entirely since playback happens in the provider's own iframe, no source-site AJAX scraping needed at watch time +- **Provider Config**: New `src/configs/embedProviders.config.js` — provider registry with URL builders (patterns verified against aluukill/AniCult's provider registry) +- **Embed Extractor**: New `src/extractors/embedProviders.extractor.js` — resolves MAL ID from the site's episode list (`data-mal`), looks up AniList ID via the public AniList GraphQL API (cached 60min), builds provider URLs +- **Embed Controller**: New `src/controllers/embedProviders.controller.js` — supports `?slug=`, `?mal=`, `?anilist=` (direct IDs skip slug scraping entirely), `?ep=`, `?lang=sub|dub`, `?provider=` comma filter, with 400 errors for unknown providers +- **IDs Cache TTL**: New `TTL.ids` (60min) for MAL/AniList ID mappings — these never change per anime +- **OpenAPI**: Registered `/stream/embeds` in the spec +- **Info External IDs**: `GET /api/info` responses now include `externalIds: { animeId, malId, anilistId }` — resolved server-side via the episode-list + AniList lookups (60min cache), best-effort (failed resolution returns nulls, never breaks the response); lets clients feed IDs straight into `/api/stream/embeds` +- **Latest-Episode Checker**: New `GET /api/episodes/latest?slug=` endpoint (new `episodeLatest.controller.js`) — returns only `latest: { episode_no, title, id, server_ids, mal_id, ... }` plus `animeId`/`totalEpisodes`, built for bot polling (10min cache, registered before `/episodes/:id` so the literal path wins) +- **Tests**: Added `Embed Providers`, `Embed (direct MAL)`, `Info External IDs` and `Latest Episode` cases to test.js + +### Fixed +- **Spotlight Carousel Selectors (BREAKING drift)**: Source site redesigned the `#hotest` carousel — updated `homeInfo.extractor.js` and `spotlight.extractor.js` for the new markup (`swiper-slide` without `.item`, `a.btn.btn-primary` instead of `a.play`, `.cover img` instead of `.image div[style]`, `h2.ak-title` instead of `h2.title`, `.ak-desc` instead of `.desc`, type/date/rating packed into `.ak-detail span.it`). Old-layout selectors kept as fallbacks (dual-selector). Spotlight was returning 0 items before this fix; now returns 9. +- **Spotlight Rating**: New layout packs rating into the `.ak-detail` list alongside year/date — numeric-with-decimal matching prevents the year (e.g. 2026) from being mistaken for the rating (e.g. 7.84) +- **Diagnostic Sweep Fixes**: Full-repo deep scan caught stale counts — README endpoints badge, docs/index.md badge/table/tree/sample counts (38→39 endpoints, 28→29 scrapers/handlers), docs/endpoints.md sample `/stats` response, public/index.html animated stat counter, docs/architecture.md extractor count and Episode & Stream category now list `embedProviders` (39 reached at that sweep, then 40 with the info-ID and latest-episode additions) +- **render.yaml**: Added missing trailing newline (EOF) + +### Changed +- **Version**: Bumped to 2.5.1 (single release consolidating domain sync, embed providers, docs pass and diagnostic sweep) +- **Mirror Domains Synced**: Verified all mirror domains against the official AniKoto domain hub (https://anikoto.site/#domains) — live check confirmed all 5 official domains return HTTP 200; replaced dead `anikoto.se` with official `anikototv.se` in `dataUrl.js` ALT_DOMAINS, `render.yaml` and README domain tables +- **Documentation Style**: Full repo-style pass on embed modules — inline `NOTE`/`TIP` markers for cache-first lookups, MAL-ID dedup, failure-tolerant AniList resolution, direct-ID fast path, input sanitization, cache-key composition; corrected JSDoc examples to current AniList ID values +- **Docs Sync**: `/api/stream/embeds` in docs/streaming.md (Direct Embed Providers section + TOC) and README streaming status table; project trees in README.md and docs/architecture.md list the new modules; `/episodes/latest` documented in docs/endpoints.md; all endpoint counts synced to 40 (README badge/highlights/checklist, landing-page metas and stat counter, docs/index.md badge/tables, docs/architecture.md controller counts, `/api/stats`); top-rankings `?sort=day|week|month` confirmed already supported — docs matched, no code change needed +- **Dockerfile**: Base image `node:18-alpine` → `node:22-alpine` — Node 18 is EOL (Sept 2025); aligns with README's Node 20+ guidance and current LTS + +### Example +``` +GET /api/stream/embeds?slug=one-piece-odmau&ep=1150 +GET /api/stream/embeds?mal=21&ep=1&lang=dub&provider=megavid,megaplay +``` + +### Verified +- All 77 JS files pass `node --check`; all relative imports resolve +- Official domains (all HTTP 200): `anikototv.to` (primary), `anikoto.cz`, `anikoto.me`, `anikoto.net`, `anikototv.se`; dead `anikoto.se` confirmed offline +- All 3 embed provider URLs live-verified HTTP 200 (Megavid serves embed-only page by design) +- Live smoke test 9/9 extractors passed; full API suite 38 passed / 0 failed / 2 optional skips (upstream AJAX blocks, documented) +- No secrets tracked in git + ## [2.4.1] - 2026-08-27 ### Security diff --git a/Dockerfile b/Dockerfile index d9f967c..9f12415 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM node:18-alpine +FROM node:22-alpine WORKDIR /app diff --git a/README.md b/README.md index d9e12eb..a88d9f1 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ Vercel License Version - Endpoints + Endpoints Anime Database Maintenance

@@ -88,7 +88,7 @@ ### Why AniKotoAPI? -- 🎬 **38 Endpoints** — Complete coverage of anikototv.to data +- 🎬 **40 Endpoints** — Complete coverage of anikototv.to data - 🔍 **Full-Text Search** — Search anime by keyword with suggestions - 📺 **Episode Lists** — AJAX-loaded episode data with server info - 🎯 **Smart Filtering** — Genre, type, status, rating, sort, season, year @@ -133,6 +133,8 @@ flowchart TD > **Streaming endpoints (`/api/servers`, `/api/stream`, `/api/stream/resolve`) return errors when anikototv.to blocks AJAX requests from server-side IPs.** > > This is expected behavior when scraping from datacenter IPs (including Vercel's). AniKoto's bot protection blocks non-browser requests to their AJAX endpoints. Metadata endpoints (home, search, info, trending, etc.) work perfectly — only streaming is affected. +> +> **✅ Alternative: `/api/stream/embeds` never touches AniKoto's AJAX layer** — it returns iframe-ready player URLs for Megavid/AniXo/MegaPlay built from MAL/AniList IDs, so playback works from any environment with zero Cloudflare friction. | What Works | What's Blocked | |:---|:---| @@ -164,7 +166,8 @@ FLARESOLVERR_URL=http://your-flaresolverr-host:8191 ### ⚡ Core - **Real-time scraping** from anikototv.to - **Smart caching** with LRU and configurable TTL per endpoint -- **38 RESTful endpoints** covering all data +- **40 RESTful endpoints** covering all data +- **Direct embed providers** (Megavid/AniXo/MegaPlay) — Cloudflare-free iframe playback - **AJAX episode loading** for accurate data - **Mapper API integration** for extra servers - **Graceful error handling** per endpoint @@ -215,7 +218,7 @@ FLARESOLVERR_URL=http://your-flaresolverr-host:8191 | Feature | Description | Status | |:---|:---|:---:| -| 🎬 38 API Endpoints | Complete coverage of anime data | ✅ | +| 🎬 40 API Endpoints | Complete coverage of anime data | ✅ | | 🔍 Full-Text Search | Keyword search with pagination | ✅ | | 📺 Episode Lists | AJAX-loaded episode data | ✅ | | 🎯 Advanced Filtering | Genre, type, status, rating, sort, season | ✅ | @@ -240,7 +243,7 @@ FLARESOLVERR_URL=http://your-flaresolverr-host:8191 | **AniKoto** | `anikoto.cz` | ✅ Active | Mirror domain | | **AniKoto** | `anikoto.me` | ✅ Active | Mirror domain | | **AniKoto** | `anikoto.net` | ✅ Active | Mirror domain | -| **AniKoto** | `anikoto.se` | ✅ Active | Mirror domain | +| **AniKoto** | `anikototv.se` | ✅ Active | Mirror domain | ### Data Available @@ -333,7 +336,7 @@ AniKotoAPI/ │ │ │ ├── 📂 docs/ # 📚 API documentation │ │ ├── 📄 index.md # Overview, quick start -│ │ ├── 📄 endpoints.md # Full API reference (38 endpoints) +│ │ ├── 📄 endpoints.md # Full API reference (40 endpoints) │ │ ├── 📄 streaming.md # Streaming flow guide + proxy │ │ ├── 📄 examples.md # Code examples (cURL, JS, Python) │ │ ├── 📄 architecture.md # Project structure, tech stack @@ -344,32 +347,36 @@ AniKotoAPI/ │ ├── 📂 configs/ # 🔧 Configuration files │ │ ├── 📄 dataUrl.js # 🌐 URL patterns for anikototv.to │ │ ├── 📄 header.config.js # 📋 Request headers -│ │ └── 📄 ids.config.js # 🏷️ Genre/Type/Status/Source/Season ID mappings +│ │ ├── 📄 ids.config.js # 🏷️ Genre/Type/Status/Source/Season ID mappings +│ │ └── 📄 embedProviders.config.js # 🆕 Direct embed provider registry (Megavid/AniXo/MegaPlay) │ │ -│ ├── 📂 controllers/ # 🎮 Route handlers (28 files) +│ ├── 📂 controllers/ # 🎮 Route handlers (30 files) │ │ ├── 📄 homeInfo.controller.js │ │ ├── 📄 animeInfo.controller.js │ │ ├── 📄 search.controller.js │ │ ├── 📄 episodeList.controller.js +│ │ ├── 📄 episodeLatest.controller.js # 🆕 Latest-episode checker (bots) │ │ ├── 📄 episodeListAjax.controller.js │ │ ├── 📄 streamInfo.controller.js │ │ ├── 📄 streamResolver.controller.js # 🆕 Stream URL resolution + quality detection +│ │ ├── 📄 embedProviders.controller.js # 🆕 Direct embed provider URLs │ │ ├── 📄 filter.controller.js │ │ ├── 📄 watchPage.controller.js -│ │ └── 📄 ... (15 more) +│ │ └── 📄 ... (17 more) │ │ -│ ├── 📂 extractors/ # 🔍 HTML scrapers (28 files) +│ ├── 📂 extractors/ # 🔍 HTML scrapers (29 files) │ │ ├── 📄 homeInfo.extractor.js # 🏠 Home page data │ │ ├── 📄 search.extractor.js # 🔍 Search results │ │ ├── 📄 animeInfo.extractor.js # 📺 Anime details │ │ ├── 📄 streamInfo.extractor.js # 📡 Streaming servers │ │ ├── 📄 streamResolver.extractor.js # 🔗 Stream URL resolution, M3U8 parser +│ │ ├── 📄 embedProviders.extractor.js # 🆕 MAL/AniList ID resolution + embed URLs │ │ ├── 📄 filter.extractor.js # 🎯 Filtered results │ │ ├── 📄 watchPage.extractor.js # ▶️ Watch page data │ │ ├── 📄 seasons.extractor.js # 📅 Season info from watch page │ │ ├── 📄 watchOrder.extractor.js # 📋 Watch order from sidebar │ │ ├── 📄 episodeList.extractor.js # 📋 Episode lists -│ │ └── 📄 ... (16 more) +│ │ └── 📄 ... (17 more) │ │ │ ├── 📂 helper/ # 🛠️ Utility functions │ │ ├── 📄 cache.helper.js # 💾 In-memory caching @@ -384,7 +391,7 @@ AniKotoAPI/ │ │ └── 📄 creatorInfo.js # ✍️ Creator attribution injection │ │ │ └── 📂 routes/ # 🛤️ Express routes -│ ├── 📄 apiRoutes.js # 🌐 Main API routes (38 endpoints) +│ ├── 📄 apiRoutes.js # 🌐 Main API routes (40 endpoints) │ └── 📄 category.route.js # 🏷️ Category routes │ ├── 📄 server.js # 🚀 Express server entry point @@ -2344,6 +2351,7 @@ CMD ["node", "server.js"] | Version | Date | Key Changes | |:---|:---|:---| +| **2.5.1** | 2026-10-13 | Domain sync vs official hub, spotlight carousel fix, direct embed providers (`/api/stream/embeds`), info `externalIds` + latest-episode checker, full docs pass, diagnostic sweep, Dockerfile Node 22 | | **2.4.1** | 2026-08-27 | Security: fixed SSRF in stream proxies, dotenv load order fix, SECURITY.md | | **2.2.0** | 2026-07-28 | Streaming resolver, M3U8/TS proxy, 5 new endpoints, bug fixes, full diagnostic sweep | | **1.7.2** | 2026-06-08 | Full rebrand AniKotoAPI → AniKotoAPI, docs folder with real data, streaming fix | @@ -2457,7 +2465,7 @@ The API can access 10,000+ anime titles from anikototv.to. The most-popular endp ### ✅ Completed -- [x] 🎬 38 API endpoints covering all data +- [x] 🎬 40 API endpoints covering all data - [x] 🔍 Full-text search with pagination - [x] 📺 Episode lists via AJAX loading - [x] 🎯 Advanced filtering (genre, type, status, rating, sort, season, year) @@ -2560,7 +2568,8 @@ git push origin feature/amazing-feature | [AniKoto CZ](https://anikoto.cz) | Mirror domain | | [AniKoto ME](https://anikoto.me) | Mirror domain | | [AniKoto NET](https://anikoto.net) | Mirror domain | -| [AniKoto SE](https://anikoto.se) | Mirror domain | +| [AniKoto SE](https://anikototv.se) | Mirror domain | +| [AniKoto Hub](https://anikoto.site) | Official domain verification hub | ### 🛠️ Technologies diff --git a/docs/architecture.md b/docs/architecture.md index 0b2e11f..e1fe611 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -67,13 +67,13 @@ * │ │ │ │ │ * │ │ ▼ │ │ * │ │ ┌──────────────────────────────────────────────────────────┐ │ │ - * │ │ │ CONTROLLER LAYER (28 controllers) │ │ │ + * │ │ │ CONTROLLER LAYER (30 controllers) │ │ │ * │ │ │ Validation · Parameter parsing · Response formatting │ │ │ * │ │ └──────────────────────┬───────────────────────────────────┘ │ │ * │ │ │ │ │ * │ │ ▼ │ │ * │ │ ┌──────────────────────────────────────────────────────────┐ │ │ - * │ │ │ EXTRACTOR / SCRAPER LAYER (28 extractors) │ │ │ + * │ │ │ EXTRACTOR / SCRAPER LAYER (29 extractors) │ │ │ * │ │ │ HTML fetching · Cheerio parsing · Data transformation │ │ │ * │ │ └──────────────────────┬───────────────────────────────────┘ │ │ * │ │ │ │ │ @@ -180,15 +180,18 @@ * ├── src/ * │ ├── configs/ * │ │ ├── header.config.js # Default HTTP headers for upstream requests - * │ │ └── ids.config.js # Genre / Type / Status numeric ID mappings - * │ ├── controllers/ # 28 route handlers (one per endpoint) + * │ │ ├── ids.config.js # Genre / Type / Status numeric ID mappings + * │ │ └── embedProviders.config.js # Direct embed provider registry (Megavid/AniXo/MegaPlay) + * │ ├── controllers/ # 30 route handlers (one per endpoint) * │ │ ├── homeInfo.controller.js * │ │ ├── animeInfo.controller.js * │ │ ├── search.controller.js * │ │ ├── episodeList.controller.js + * │ │ ├── episodeLatest.controller.js * │ │ ├── episodeListAjax.controller.js * │ │ ├── streamInfo.controller.js * │ │ ├── streamResolver.controller.js + * │ │ ├── embedProviders.controller.js * │ │ ├── schedule.controller.js * │ │ ├── spotlight.controller.js * │ │ ├── trending.controller.js @@ -210,7 +213,7 @@ * │ │ ├── recentlyUpdatedTabs.controller.js * │ │ ├── completedAnime.controller.js * │ │ └── category.controller.js - * │ ├── extractors/ # 28 HTML scrapers (one per data source) + * │ ├── extractors/ # 29 HTML scrapers (one per data source) * │ │ ├── homeInfo.extractor.js * │ │ ├── animeInfo.extractor.js * │ │ ├── search.extractor.js @@ -218,6 +221,7 @@ * │ │ ├── episodeListAjax.extractor.js * │ │ ├── streamInfo.extractor.js * │ │ ├── streamResolver.extractor.js + * │ │ ├── embedProviders.extractor.js * │ │ ├── schedule.extractor.js * │ │ ├── spotlight.extractor.js * │ │ ├── trending.extractor.js @@ -308,7 +312,7 @@ * └────────────────────────────────────────────────────────────────────────┘ * * ┌────────────────────────────────────────────────────────────────────────┐ - * │ Extractors (28 scrapers) │ + * │ Extractors (29 scrapers) │ * ├────────────────────────────────────────────────────────────────────────┤ * │ One extractor per data source on the target site. Responsibilities: │ * │ • Build the upstream URL (via mirror.helper) │ @@ -861,7 +865,8 @@ * │ Search & Filter │ search, filter, azList, category │ * │ Anime Detail │ animeInfo, watchPage, status │ * │ Episode & Stream │ episodeList, episodeListAjax, │ - * │ │ streamInfo, streamResolver, download │ + * │ │ streamInfo, streamResolver, download,│ + * │ │ embedProviders │ * │ Lists │ newRelease, trendingSidebar, │ * │ │ topAnimeRankings, recentlyUpdated, │ * │ │ completedAnime, upcomingAnime │ diff --git a/docs/endpoints.md b/docs/endpoints.md index 32b8447..2febe49 100644 --- a/docs/endpoints.md +++ b/docs/endpoints.md @@ -164,7 +164,7 @@ curl "https://anikototvapi.vercel.app/api/search?keyword=naruto" ## GET /info -Get detailed info about an anime. +Get detailed info about an anime. Includes `externalIds` (MAL/AniList IDs) that can be passed directly to `/stream/embeds`. | Param | Type | Required | Description | |-------|------|----------|-------------| @@ -172,6 +172,8 @@ Get detailed info about an anime. > **Important:** Slugs now include random hashes (e.g., `one-piece-odmau`). Get valid slugs from `/search` or `/most-popular` results. +> **Note:** `externalIds` is resolved server-side (cached 60 min) and is best-effort — if ID resolution fails it comes back as `null` values, the rest of the response is unaffected. + **Request:** ```bash @@ -203,7 +205,12 @@ curl "https://anikototvapi.vercel.app/api/info?id=naruto-shippuuden-movie-6-road "producers": ["TV Tokyo", "Shueisha"], "genres": ["Action", "Comedy", "Supernatural"], "rating": "PG-13", - "reviewCount": "0" + "reviewCount": "0", + "externalIds": { + "animeId": 1642, + "malId": "21", + "anilistId": "21" + } } } ``` @@ -254,6 +261,46 @@ curl "https://anikototvapi.vercel.app/api/episodes/958" --- +## GET /episodes/latest + +Latest-episode checker — returns only the newest episode plus summary counts. Built for bots and notification jobs ("is there a new episode?") that shouldn't download the full episode list. + +| Param | Type | Required | Description | +|-------|------|----------|-------------| +| `slug` | string | Yes | Anime slug or animeId | + +**Request:** + +```bash +curl "https://anikototvapi.vercel.app/api/episodes/latest?slug=one-piece-odmau" +``` + +**Response:** + +```json +{ + "success": true, + "results": { + "slug": "one-piece-odmau", + "animeId": 1642, + "totalEpisodes": 1165, + "latest": { + "episode_no": 1165, + "title": "", + "id": "50167", + "slug": "1165", + "href": "#", + "server_ids": "dXNCT3hNQzk3THhSTW8ySnM5...", + "mal_id": "21" + } + } +} +``` + +> **Tip:** Poll this endpoint, compare `results.latest.episode_no` with your stored value, and call `/servers?ids=results.latest.server_ids` only when it changes. Responses are cached for 10 minutes. + +--- + ## GET /servers Get available servers for an episode. @@ -835,6 +882,48 @@ Returns array of quality objects with url, quality label, resolution, bandwidth, --- +## GET /stream/embeds + +Direct embed provider URLs (Megavid / AniXo / MegaPlay) — iframe-ready players that bypass Cloudflare entirely. Playback happens inside the provider's own iframe; no source-site AJAX scraping at watch time. + +| Param | Type | Required | Description | +|-------|------|----------|-------------| +| `slug` | string | One of* | Anime slug — MAL/AniList IDs resolved automatically | +| `mal` | string | One of* | Direct MAL ID (skips slug lookup) | +| `anilist` | string | One of* | Direct AniList ID (skips slug lookup) | +| `ep` | number | No | Episode number (default 1) | +| `lang` | string | No | `sub` or `dub` (default `sub`) | +| `provider` | string | No | Comma-separated filter: `megaplay`, `anixo`, `megavid` | + +\* Provide at least one of `slug`, `mal`, or `anilist`. + +```bash +curl "https://anikototvapi.vercel.app/api/stream/embeds?slug=one-piece-odmau&ep=1" +curl "https://anikototvapi.vercel.app/api/stream/embeds?mal=21&ep=1&lang=dub&provider=megavid" +``` + +Returns resolved IDs plus iframe-ready URLs per provider: + +```json +{ + "success": true, + "results": { + "slug": "one-piece-odmau", + "episode": 1, + "lang": "sub", + "ids": { "animeId": 1642, "malId": "21", "anilistId": "21" }, + "providers": [ + { "id": "megaplay", "name": "MegaPlay", "url": "https://megaplay.buzz/stream/mal/21/1/sub", "iframeReady": true }, + { "id": "anixo", "name": "AniXo", "url": "https://anixo.buzz/embed/ani/21/1/sub?color=%23e63946", "iframeReady": true }, + { "id": "megavid", "name": "Megavid", "url": "https://megavid.buzz/mal/21/1/sub?color=%23e63946&autoplay=true", "iframeReady": true } + ], + "unavailable": [] + } +} +``` + +--- + ## GET /stream/proxy M3U8 playlist proxy — rewrites relative URLs to proxy endpoints for CORS-free playback. @@ -924,7 +1013,7 @@ curl "https://anikototvapi.vercel.app/api/stats" "ttl": "5 minutes", "description": "Map-based cache with TTL expiration" }, - "endpoints": 38, + "endpoints": 40, "timestamp": "2026-07-30T02:20:46.205Z" } } diff --git a/docs/index.md b/docs/index.md index a6b5c7e..6e3dd56 100644 --- a/docs/index.md +++ b/docs/index.md @@ -7,7 +7,7 @@ ![AniKotoAPI](https://img.shields.io/badge/AniKotoAPI-v2.4.1-blue) ![License](https://img.shields.io/badge/License-MIT-green) -![Endpoints](https://img.shields.io/badge/Endpoints-38+-orange) +![Endpoints](https://img.shields.io/badge/Endpoints-40+-orange) ![Node.js](https://img.shields.io/badge/Node.js-18+-brightgreen) > A fast, free REST API that scrapes anime data from **anikototv.to**. @@ -70,9 +70,9 @@ That's it. No API keys required. | Feature | Description | |---|---| -| **38+ Endpoints** | Full coverage of anime data, streaming, and discovery | -| **28 HTML Scrapers** | Cheerio-based scrapers for robust data extraction | -| **28 Route Handlers** | Organized controllers with clean separation of concerns | +| **40+ Endpoints** | Full coverage of anime data, streaming, and discovery | +| **29 HTML Scrapers** | Cheerio-based scrapers for robust data extraction | +| **30 Route Handlers** | Organized controllers with clean separation of concerns | | **5 Mirror Domains** | Automatic failover across multiple source domains | | **LRU Cache** | Per-endpoint TTL caching for performance | | **Rate Limiting** | 100 requests per 15 minutes per IP | @@ -194,12 +194,12 @@ AniKotoAPI/ │ ├── info.js # Anime info │ ├── search.js # Search │ ├── stream.js # Streaming -│ └── ... # 38+ route handlers +│ └── ... # 40 route handlers ├── scrapers/ # Cheerio HTML scrapers │ ├── home.js │ ├── info.js │ ├── search.js -│ └── ... # 28 scrapers +│ └── ... # 29 scrapers ├── utils/ # Shared utilities │ ├── cache.js # LRU cache with TTL │ ├── rateLimit.js # IP-based rate limiter @@ -218,8 +218,8 @@ AniKotoAPI/ ### Key Design Patterns -- **Scraping Layer**: 28 Cheerio-based scrapers parse HTML from anikototv.to, isolating page-specific logic from route handlers. -- **Controller Layer**: 28 route handlers map HTTP requests to scraper calls, handle validation, and format responses. +- **Scraping Layer**: 29 Cheerio-based scrapers parse HTML from anikototv.to, isolating page-specific logic from route handlers. +- **Controller Layer**: 30 route handlers map HTTP requests to scraper calls, handle validation, and format responses. - **Cache Layer**: LRU cache with per-endpoint TTL reduces redundant scraping. Hot endpoints cache for 2–5 minutes; cold endpoints for 10+ minutes. - **Mirror Layer**: 5 source domains with automatic failover. If one domain is slow or down, requests transparently fall back to the next mirror. - **Rate Limiter**: Token bucket algorithm, 100 requests per 15-minute window per client IP. @@ -350,7 +350,7 @@ All errors return JSON with a consistent structure: | File | Description | |------|-------------| -| [endpoints.md](./endpoints.md) | Full API reference for all 38+ endpoints | +| [endpoints.md](./endpoints.md) | Full API reference for all 40+ endpoints | | [streaming.md](./streaming.md) | Complete streaming workflow guide | | [examples.md](./examples.md) | Working code examples in cURL, JS, Python | | [architecture.md](./architecture.md) | Project structure and design patterns | diff --git a/docs/streaming.md b/docs/streaming.md index edfe796..8b4eb5f 100644 --- a/docs/streaming.md +++ b/docs/streaming.md @@ -15,6 +15,8 @@ This document covers the complete streaming workflow for AniKotoAPI — from sea ## ⚠️ Streaming Status > **Streaming endpoints (`/api/servers`, `/api/stream`, `/api/stream/resolve`) return errors when anikototv.to blocks AJAX requests from server-side IPs.** +> +> **✅ Alternative: `/api/stream/embeds` never touches AniKoto's AJAX layer** — see [Direct Embed Providers](#direct-embed-providers). | What Works | What's Blocked | |:---|:---| @@ -24,6 +26,7 @@ This document covers the complete streaming workflow for AniKotoAPI — from sea | Top 10, most popular, new release | `/api/mapper-servers` — gogoanime servers | | AZ list, random, genre list | All AJAX-dependent endpoints | | All HTML-scraped endpoints | | +| **`/api/stream/embeds` — direct provider iframes** | | **To fix streaming**, set one of these environment variables: @@ -35,17 +38,55 @@ SCRAPER_API_KEY=your_scraperapi_key FLARESOLVERR_URL=http://your-flaresolverr-host:8191 ``` +Or use the Cloudflare-free embed providers below — no proxy needed. + +--- + +## Direct Embed Providers + +`GET /api/stream/embeds` builds iframe-ready player URLs for three third-party providers. Playback happens inside the provider's own iframe, so nothing ever requests AniKoto's Cloudflare-protected AJAX endpoints at watch time. + +| Provider | URL pattern | Requires | +|:---|:---|:---| +| **MegaPlay** | `megaplay.buzz/stream/mal\|ani/{id}/{ep}/{lang}` | MAL or AniList ID | +| **AniXo** | `anixo.buzz/embed/ani/{anilistId}/{ep}/{lang}` | AniList ID | +| **Megavid** | `megavid.buzz/{mal\|ani}/{id}/{ep}/{lang}` | MAL or AniList ID | + +```bash +# From an AniKoto slug (MAL/AniList IDs resolved automatically, cached 60min) +curl ".../api/stream/embeds?slug=one-piece-odmau&ep=1" + +# From direct IDs — zero scraping, instant response +curl ".../api/stream/embeds?mal=21&ep=1&lang=dub&provider=megavid,megaplay" +``` + +```json +{ + "results": { + "ids": { "animeId": 1642, "malId": "21", "anilistId": "21" }, + "providers": [ + { "id": "megaplay", "url": "https://megaplay.buzz/stream/mal/21/1/sub", "iframeReady": true }, + { "id": "anixo", "url": "https://anixo.buzz/embed/ani/21/1/sub?color=%23e63946", "iframeReady": true }, + { "id": "megavid", "url": "https://megavid.buzz/mal/21/1/sub?color=%23e63946&autoplay=true", "iframeReady": true } + ] + } +} +``` + +Drop any `url` straight into an `