File size: 4,800 Bytes
d145b59
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
const {
  fileTypeFromBuffer
} = require("file-type");
const twit = require("../lib/twt")
const {
  ttt
} = require("../lib/skrep");
const {
  soundcloud
} = require("../lib/soundcloud");
const ig = require("../lib/ig");
const {
  spotifyTrack,
  spotifyPlaylist
} = require("../lib/spotify");
const yt = require("../lib/ytdl");
const kwaii = require("../lib/kuaishou");
const qq = require("../lib/qqm");
const fesnuk = require("../lib/fb");

const IGr = /^(https?:\/\/)?(www\.)?instagram\.com\/.*$/i;
const SCr = /^(https?:\/\/)?(www\.|m\.)?(on\.|)soundcloud\.com\/[^\s]+$/i;
const TTr = /https?:\/\/(www\.|v(t|m)\.|t\.)?tiktok\.com/i;
const Sr = /https?:\/\/open\.spotify\.com\/track\/([a-zA-Z0-9]+)(\?.*)?/i;
const Ser = /https?:\/\/open\.spotify\.com\/playlist\/([a-zA-Z0-9]+)(\?.*)?/i;
const YTr = /(?:http(?:s|):\/\/|)(?:(?:www\.|)?(?:music\.)?youtube(?:-nocookie|)\.com\/(?:shorts\/)?(?:watch\?.*(?:|&)v=|embed\/|v\/)?|youtu\.be\/)([-_0-9A-Za-z]{11})/i;
const Kr = /^https?:\/\/v\.kuaishou\.com\/[a-zA-Z0-9]+$/i;
const QQMr = /^https:\/\/c6\.y\.qq\.com\/base\/fcgi-bin\/u\?__=[a-zA-Z0-9]+$/;
const TwTr = /^https?:\/\/(www\.)?(twitter|x)\.com\/[^\/]+\/status\/\d+\/?$/i;
// Daftar domain yang diperbolehkan untuk Facebook
const allowX = [
  "x.com",
  "www.x.com",
  "twitter.com",
  "www.twitter.com"
  ]
const allowedFacebookHosts = [
  "facebook.com",
  "www.facebook.com",
  "m.facebook.com",
  "fb.com"
];

/**
 * @param {string} response
 * @returns {Promise<{ success: boolean, challenge_ts: string, hostname: string, score: number, action: string, "error-codes": ("missing-input-secret"|"invalid-input-secret"|"missing-input-response"|"invalid-input-response"|"bad-request"|"timeout-or-duplicate")[] }>}
 */
async function checkCaptcha(response) {
  const url = new URL("https://www.google.com/recaptcha/api/siteverify");
  url.searchParams.set("secret", "6Ldr6_cqAAAAAApmQtOImEUOVLq8cAIFUZuuRSrM");
  url.searchParams.set("response", response);

  const res = await fetch(url, {
    method: "POST"
  });

  return await res.json();
}

/** @type {Map<string, any>} */
const yt_info = new Map();
module.exports = async function(req, res) {
  const {
    url
  } = req.body;
  //const ip = req._ip;
  if(!url) {
    return res.status(400).json({
      error: "URL diperlukan."
    });
  }

  let parsedUrl;
  try {
    parsedUrl = new URL(url);
  } catch (error) {
    return res.status(400).json({ error: "URL tidak valid." });
  }

 /*const authHeader = req.headers.authorization;
  if (!authHeader || !authHeader.startsWith("Bearer ")) {
  return res.status(401).json({ message: "Unauthorized: Token is missing or invalid" });
  }

 const token = authHeader.split(" ")[1];
 const { success: isValid, "error-codes": errors } = await checkCaptcha(token);

 if (!isValid) {
   return res.status(400).send({ message: "Invalid captcha", errors });
  }*/

  console.log(parsedUrl);
  let ress;
  try {
    if(IGr.test(url)) {
      ress = await ig(url);
      ress.type = "instagram";
    } else if(SCr.test(url)) {
      ress = await soundcloud(url);
      ress.type = "soundcloud";
    } else if(Ser.test(url)) {
      ress = await spotifyPlaylist(url);
      ress.type = "spotifyPlaylist";
    } else if(TTr.test(url)) {
      ress = await ttt(url);
      ress.type = "tiktok";
    } else if(Sr.test(url)) {
      ress = await spotifyTrack(url);
      ress.type = "spotify";
    } else if(QQMr.test(url)) {
      ress = await qq(url);
      ress.type = "qq";
    } else if(allowedFacebookHosts.includes(parsedUrl.hostname)) {
      ress = await fesnuk(url);
      ress.type = "facebook"
    } else if(allowX.includes(parsedUrl.hostname)) {
      ress = await twit(url);
      ress.type = "twitter"
    } else if(YTr.test(url)) {
      const format = String(
        req.headers["x-selected-format"] ||
        ""
      ).trim();
      const [, id] = YTr.exec(url);

      if(!format) {
        ress = (
          yt_info.has(id)
            ? yt_info.get(id)
            : await yt.getInfo(url)
        );
        yt_info.set(id, ress);
        ress.type = "yt_info";
      } else {
        const type = (
          format === "audio"
            ? "Audio"
            : "Video"
        );
        ress = await yt[`get${type}`](url, format);
      }
    } else if(Kr.test(url)) {
      ress = await kwaii(url);
      ress.type = "kwaii";
    } else {
      ress = {
        status: 400,
        message: "failed request"
      };
    }
  } catch (e) {
    console.log(e);
    ress = {
      status: 404,
      message: e.message
    };
  }

  if(Buffer.isBuffer(ress)) {
    const { mime } = await fileTypeFromBuffer(ress);
    res.setHeader("Content-Type", mime);
    res.setHeader("Content-Length", ress.length);
  }
  return res.status(ress.status || 200).send(ress.data || ress);
};