-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathindex.js
161 lines (145 loc) · 4.5 KB
/
index.js
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
const fetch = require("node-fetch");
const chalk = require("chalk");
const inquirer = require("inquirer");
const cheerio = require("cheerio");
const fs = require("fs");
const getChoice = () => new Promise((resolve, reject) => {
inquirer.prompt([
{
type: "list",
name: "choice",
message: "Choose a option",
choices: ["Feed", "TV", "Reels", "Story", "Highlights", "Exit"]
}
])
.then(res => resolve(res))
.catch(err => reject(err));
});
const getInput = (teks) => new Promise((resolve, reject) => {
inquirer.prompt([
{
name: "input",
message: teks
}
])
.then(res => {
resolve(res)
})
.catch(err => reject(err));
});
const urlChecker = (url) => {
const reg = new RegExp("(https:\/\/www\.instagram\.com\/(?:p|reel|tv)\/[a-zA-Z0-9_-]{11}\/)");
const match = url.match(reg);
return match;
}
const downloadMediaFromUrl = (urls) => new Promise((resolve, reject) => {
console.log(chalk.blue("[*] Processing..."));
urls.forEach((url) => {
const fileName = new URL(url).pathname.split("/").pop();
const res = fetch(url);
res.then(res => {
const folder = `downloads/`;
const file = fs.createWriteStream(folder+fileName);
res.body.pipe(file);
file.on("finish", () => {
file.close();
})
file.on("error", (err) => {
reject(err);
});
})
.catch(err => reject(err));
});
resolve();
});
const scrapeHtmlFromUrl = async (url) => {
const matching = await urlChecker(url);
if(!matching){
console.log(chalk.red("[X] URL not valid"));
return;
}
const urlApi = `${matching[0]}embed/`;
const res = await fetch(urlApi);
const html = await res.text();
return html;
}
const getJsonFromHtml = async (html) => {
var json = null;
const $ = cheerio.load(html);
$("script").each((i, el) => {
const script = $(el).html();
const reg = new RegExp("window\\.__additionalDataLoaded\\((.*)\\)");
const match = script.match(reg);
if(match){
const res = match[1].replace("'extra',", "");
json = JSON.parse(res);
}
});
return json;
}
const getUrlFromHtml = async (html) => {
const $ = cheerio.load(html);
const url = $(".EmbeddedMediaImage").attr("src");
return [url];
}
const getUrlFromJson = async (json) => {
const data = json.shortcode_media;
const isSingle = (data.edge_sidecar_to_children) ? false : true;
if (isSingle) {
if(data.is_video){
return [data.video_url];
} else{
return [data.display_url];
}
} else{
const urls = [];
data.edge_sidecar_to_children.edges.forEach(edge => {
if(edge.node.is_video){
urls.push(edge.node.video_url);
} else{
urls.push(edge.node.display_url);
}
});
return urls;
}
}
(async () => {
console.log(chalk.magenta("Starting Instagram Downloader..."));
const choice = await getChoice();
if(choice.choice == "Exit"){
console.log(chalk.red("Exiting..."));
return;
}
if(choice.choice == "Feed" || choice.choice == "TV" || choice.choice == "Reels"){
const getInputUrl = await getInput("Enter the URL of the post: ");
const inputUrl = getInputUrl.input;
if (!inputUrl) {
console.log(chalk.red("[x] URL is required"));
return;
}
const html = await scrapeHtmlFromUrl(inputUrl)
const json = await getJsonFromHtml(html);
var urls = [];
if(json){
// console.log(chalk.green("[*] Found JSON"));
urls = await getUrlFromJson(json);
} else{
// console.log(chalk.green("[*] Found HTML"));
urls = await getUrlFromHtml(html);
}
if(urls.length > 0){
console.log(chalk.green(`[!] ${urls.length} media found`));
downloadMediaFromUrl(urls)
.then(() => {
console.log(chalk.green(`[+] Successfully downloaded ${urls.length} media`));
})
.catch(err => {
console.log(chalk.red(`[x] ${err}`));
});
} else{
console.log(chalk.red("[X] Error getting URL"));
}
} else{
console.log(chalk.yellow("[!] Coming soon..."));
}
})();