mirror of
https://github.com/shafat-96/anicrush-api.git
synced 2026-04-17 15:51:44 +00:00
257 lines
7.3 KiB
JavaScript
257 lines
7.3 KiB
JavaScript
const express = require('express');
|
|
const axios = require('axios');
|
|
const cors = require('cors');
|
|
const { mapAniListToAnicrush, getCommonHeaders } = require('./mapper');
|
|
const { getHlsLink } = require('./hls');
|
|
require('dotenv').config();
|
|
|
|
const app = express();
|
|
|
|
// Remove explicit port for Vercel
|
|
const PORT = process.env.PORT || 3000;
|
|
|
|
// CORS configuration for Vercel
|
|
app.use(cors({
|
|
origin: '*',
|
|
methods: ['GET', 'POST', 'OPTIONS'],
|
|
allowedHeaders: ['Content-Type', 'Authorization']
|
|
}));
|
|
|
|
app.use(express.json());
|
|
|
|
// Endpoint to map AniList ID to anicrush
|
|
app.get('/api/mapper/:anilistId', async (req, res) => {
|
|
try {
|
|
const { anilistId } = req.params;
|
|
|
|
if (!anilistId) {
|
|
return res.status(400).json({ error: 'AniList ID is required' });
|
|
}
|
|
|
|
const mappedData = await mapAniListToAnicrush(anilistId);
|
|
res.json(mappedData);
|
|
} catch (error) {
|
|
console.error('Error in mapper:', error);
|
|
res.status(500).json({
|
|
error: 'Failed to map AniList ID',
|
|
message: error.message
|
|
});
|
|
}
|
|
});
|
|
|
|
// Endpoint to search for anime
|
|
app.get('/api/anime/search', async (req, res) => {
|
|
try {
|
|
const { keyword, page = 1, limit = 24 } = req.query;
|
|
|
|
if (!keyword) {
|
|
return res.status(400).json({ error: 'Search keyword is required' });
|
|
}
|
|
|
|
const headers = getCommonHeaders();
|
|
|
|
const response = await axios({
|
|
method: 'GET',
|
|
url: `https://api.anicrush.to/shared/v2/movie/list`,
|
|
params: {
|
|
keyword,
|
|
page,
|
|
limit
|
|
},
|
|
headers
|
|
});
|
|
|
|
res.json(response.data);
|
|
} catch (error) {
|
|
console.error('Error searching anime:', error);
|
|
res.status(500).json({
|
|
error: 'Failed to search anime',
|
|
message: error.message
|
|
});
|
|
}
|
|
});
|
|
|
|
// Endpoint to fetch episode list
|
|
app.get('/api/anime/episodes', async (req, res) => {
|
|
try {
|
|
const { movieId } = req.query;
|
|
|
|
if (!movieId) {
|
|
return res.status(400).json({ error: 'Movie ID is required' });
|
|
}
|
|
|
|
const headers = getCommonHeaders();
|
|
|
|
const response = await axios({
|
|
method: 'GET',
|
|
url: `https://api.anicrush.to/shared/v2/episode/list`,
|
|
params: {
|
|
_movieId: movieId
|
|
},
|
|
headers
|
|
});
|
|
|
|
res.json(response.data);
|
|
} catch (error) {
|
|
console.error('Error fetching episode list:', error);
|
|
res.status(500).json({
|
|
error: 'Failed to fetch episode list',
|
|
message: error.message
|
|
});
|
|
}
|
|
});
|
|
|
|
// Endpoint to fetch servers for an episode
|
|
app.get('/api/anime/servers/:movieId', async (req, res) => {
|
|
try {
|
|
const { movieId } = req.params;
|
|
const { episode } = req.query;
|
|
|
|
if (!movieId) {
|
|
return res.status(400).json({ error: 'Movie ID is required' });
|
|
}
|
|
|
|
const headers = getCommonHeaders();
|
|
|
|
const response = await axios({
|
|
method: 'GET',
|
|
url: `https://api.anicrush.to/shared/v2/episode/servers`,
|
|
params: {
|
|
_movieId: movieId,
|
|
ep: episode || 1
|
|
},
|
|
headers
|
|
});
|
|
|
|
res.json(response.data);
|
|
} catch (error) {
|
|
console.error('Error fetching servers:', error);
|
|
res.status(500).json({
|
|
error: 'Failed to fetch servers',
|
|
message: error.message
|
|
});
|
|
}
|
|
});
|
|
|
|
// Main endpoint to fetch anime sources
|
|
app.get('/api/anime/sources', async (req, res) => {
|
|
try {
|
|
const { movieId, episode, server, subOrDub } = req.query;
|
|
|
|
if (!movieId) {
|
|
return res.status(400).json({ error: 'Movie ID is required' });
|
|
}
|
|
|
|
const headers = getCommonHeaders();
|
|
|
|
// First, check if the episode list exists
|
|
const episodeListResponse = await axios({
|
|
method: 'GET',
|
|
url: `https://api.anicrush.to/shared/v2/episode/list`,
|
|
params: {
|
|
_movieId: movieId
|
|
},
|
|
headers
|
|
});
|
|
|
|
if (!episodeListResponse.data || episodeListResponse.data.status === false) {
|
|
return res.status(404).json({ error: 'Episode list not found' });
|
|
}
|
|
|
|
// Then, get the servers for the episode
|
|
const serversResponse = await axios({
|
|
method: 'GET',
|
|
url: `https://api.anicrush.to/shared/v2/episode/servers`,
|
|
params: {
|
|
_movieId: movieId,
|
|
ep: episode || 1
|
|
},
|
|
headers
|
|
});
|
|
|
|
if (!serversResponse.data || serversResponse.data.status === false) {
|
|
return res.status(404).json({ error: 'Servers not found' });
|
|
}
|
|
|
|
// Finally, get the sources
|
|
const sourcesResponse = await axios({
|
|
method: 'GET',
|
|
url: `https://api.anicrush.to/shared/v2/episode/sources`,
|
|
params: {
|
|
_movieId: movieId,
|
|
ep: episode || 1,
|
|
sv: server || 4,
|
|
sc: subOrDub || 'sub'
|
|
},
|
|
headers
|
|
});
|
|
|
|
res.json(sourcesResponse.data);
|
|
} catch (error) {
|
|
console.error('Error fetching anime sources:', error);
|
|
res.status(500).json({
|
|
error: 'Failed to fetch anime sources',
|
|
message: error.message
|
|
});
|
|
}
|
|
});
|
|
|
|
// Endpoint to get HLS link
|
|
app.get('/api/anime/hls/:movieId', async (req, res) => {
|
|
try {
|
|
const { movieId } = req.params;
|
|
const { episode = 1, server = 4, subOrDub = 'sub' } = req.query;
|
|
|
|
if (!movieId) {
|
|
return res.status(400).json({ error: 'Movie ID is required' });
|
|
}
|
|
|
|
const headers = getCommonHeaders();
|
|
|
|
// First get the embed link
|
|
const embedResponse = await axios({
|
|
method: 'GET',
|
|
url: `https://api.anicrush.to/shared/v2/episode/sources`,
|
|
params: {
|
|
_movieId: movieId,
|
|
ep: episode,
|
|
sv: server,
|
|
sc: subOrDub
|
|
},
|
|
headers
|
|
});
|
|
|
|
if (!embedResponse.data || embedResponse.data.status === false) {
|
|
return res.status(404).json({ error: 'Embed link not found' });
|
|
}
|
|
|
|
const embedUrl = embedResponse.data.result.link;
|
|
|
|
// Get HLS link from embed URL
|
|
const hlsData = await getHlsLink(embedUrl);
|
|
res.json(hlsData);
|
|
|
|
} catch (error) {
|
|
console.error('Error fetching HLS link:', error);
|
|
res.status(500).json({
|
|
error: 'Failed to fetch HLS link',
|
|
message: error.message
|
|
});
|
|
}
|
|
});
|
|
|
|
// Health check endpoint
|
|
app.get('/health', (req, res) => {
|
|
res.json({ status: 'OK' });
|
|
});
|
|
|
|
// Only start the server if not in Vercel environment
|
|
if (process.env.VERCEL !== '1') {
|
|
app.listen(PORT, () => {
|
|
console.log(`Server is running on port ${PORT}`);
|
|
});
|
|
}
|
|
|
|
// Export the Express app for Vercel
|
|
module.exports = app;
|