-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.js
More file actions
160 lines (125 loc) · 5.43 KB
/
Copy pathindex.js
File metadata and controls
160 lines (125 loc) · 5.43 KB
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
/*
# Discord-Transcript-Viewer
# Copyright (c) 2026 Abilash Sanjayan
# IMPORTANT: Please read the following information before using the viewer.
- This viewer is designed to work with transcript files generated by the provided transcript generator bot. The viewer fetches the transcript file (HTML file) from Discord and displays its content in a web browser.
- Transcript files should be available in the discord to use this viewer. If you delete the original transcript file, the viewer will not work. The viewer will attempt to refresh the URL if it has expired, but if the original file is deleted, it will not be able to refresh and the viewer will not work.
- Please refer the licence file for more information about the usage and distribution of this viewer.
Developed by abilash.dev (https://github.com/abilash-dev)
*/
const fs = require("fs");
const https = require("https");
const express = require("express");
const Discord = require("discord.js-selfbot-v13");
const cors = require("cors");
const axios = require("axios");
const app = express();
// Update the paths to your SSL certificate and private key if you want to use HTTPS. If not, the server will fall back to HTTP.
const privateKeyPath = "/home/container/ssl/private.key";
const certificatePath = "/home/container/ssl/certificate.crt";
const token = ""; // Update your discord user account token here
const portNo = 20910; // Update the port number if needed
// SSL Setup
let server;
try {
const options = {
key: fs.readFileSync(privateKeyPath),
cert: fs.readFileSync(certificatePath),
};
server = https.createServer(options, app);
} catch (e) {
console.warn("SSL certs not found or invalid.");
server = require("http").createServer(app);
}
// Discord Setup
const client = new Discord.Client({
readyStatus: false,
checkUpdate: false,
});
client.on('ready', () => {
console.log(`Logged in as ${client.user.tag}`);
});
client.login(token);
app.use(cors({ origin: '*' }));
app.use(express.json());
async function getRefreshedUrl(originalUrl) {
try {
if (!client.isReady()) return null;
const refreshedUrls = await client.refreshAttachmentURL([originalUrl]);
return refreshedUrls[0]?.refreshed || null;
} catch (error) {
console.error("Failed to refresh URL:", error.message);
return null;
}
}
app.get('/view/:ch_id/:x_id/:a_name/:ex/:is_id/:hm', async (req, res) => {
const { ch_id, x_id, a_name, ex, is_id, hm } = req.params;
let targetUrl = `https://cdn.discordapp.com/attachments/${ch_id}/${x_id}/${a_name}?ex=${ex}&is=${is_id}&hm=${hm}&`;
try {
let response;
try {
response = await axios.get(targetUrl, { responseType: 'text' });
} catch (err) {
const newUrl = await getRefreshedUrl(targetUrl);
if (!newUrl) throw new Error("Failed to refresh URL");
response = await axios.get(newUrl, { responseType: 'text' });
}
let htmlContent = response.data;
const currentHost = `${req.protocol}://${req.get('host')}`;
const discordLinkRegex = /https:\/\/(media|cdn)\.discordapp\.(com|net)\/attachments\/(\d+)\/(\d+)\/([^?]+)\?ex=([^&]+)&is=([^&]+)&hm=([^&]+)&?/g;
const modifiedContent = htmlContent.replace(discordLinkRegex, (match, cdn, tld, ch, att, file, exParam, isParam, hmParam) => {
return `${currentHost}/attachment/${ch}/${att}/${file}/${exParam}/${isParam}/${hmParam}`;
});
res.set('Content-Type', 'text/html');
res.send(modifiedContent);
} catch (error) {
console.error(error.message);
res.status(404).send("Error loading file - Original file not found or internal error");
}
});
app.get('/attachment/:ch_id/:x_id/:a_name/:ex/:is_id/:hm', async (req, res) => {
const { ch_id, x_id, a_name, ex, is_id, hm } = req.params;
let targetUrl = `https://cdn.discordapp.com/attachments/${ch_id}/${x_id}/${a_name}?ex=${ex}&is=${is_id}&hm=${hm}&`;
try {
let response;
try {
response = await axios({
method: 'get',
url: targetUrl,
responseType: 'stream'
});
} catch (err) {
const newUrl = await getRefreshedUrl(targetUrl);
if (!newUrl) return res.status(404).send("Failed to refresh URL");
response = await axios({
method: 'get',
url: newUrl,
responseType: 'stream'
});
}
const contentType = response.headers['content-type'];
res.set('Content-Type', contentType);
if (contentType.startsWith('image/') || contentType.startsWith('application/pdf')) {
res.set('Content-Disposition', 'inline');
}
response.data.pipe(res);
} catch (error) {
console.error("Proxy error:", error.message);
res.status(404).send("Error fetching attachment");
}
});
app.post("/refresh-url", async (req, res) => {
const { url } = req.body;
const refreshed = await getRefreshedUrl(url);
if (refreshed) {
res.json({ original: url, refreshed: refreshed });
} else {
res.status(500).json({ error: "Error refreshing URL" });
}
});
app.get('/', (req, res) => {
res.send('Transcript viewer is running. Please use the appropriate URL format to view transcripts.');
});
server.listen(portNo, () => {
console.log(`Node.js server is running on port ${portNo}`);
});