-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbotgit.js
More file actions
214 lines (187 loc) · 8.01 KB
/
Copy pathbotgit.js
File metadata and controls
214 lines (187 loc) · 8.01 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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
const TelegramBot = require('node-telegram-bot-api');
const { Octokit } = require('@octokit/rest');
const express = require('express');
const multer = require('multer');
const fs = require('fs');
const path = require('path');
// ENV
const TELEGRAM_TOKEN = process.env.TELEGRAM_TOKEN; // Isi token dari BotFather
const GITHUB_CLIENT_ID = process.env.GITHUB_CLIENT_ID;
const GITHUB_CLIENT_SECRET = process.env.GITHUB_CLIENT_SECRET;
const BASE_URL = process.env.BASE_URL || 'https://your-server.com';
const PORT = process.env.PORT || 3000;
// In-memory session (ganti ke database untuk produksi)
const userSessions = {}; // userId: { githubToken, ... }
// 1. Setup Telegram Bot
const bot = new TelegramBot(TELEGRAM_TOKEN, { polling: true });
// 2. Setup Express untuk OAuth & upload
const app = express();
const upload = multer({ dest: 'uploads/' });
/* ------------- EXPRESS GITHUB OAUTH FLOW ------------- */
app.get('/login', (req, res) => {
// Redirect ke GitHub OAuth
const telegramId = req.query.tid;
const state = `${telegramId}_${Date.now()}`;
res.redirect(`https://github.com/login/oauth/authorize?client_id=${GITHUB_CLIENT_ID}&scope=repo&state=${state}`);
});
app.get('/oauth-callback', async (req, res) => {
const code = req.query.code;
const state = req.query.state;
const telegramId = state.split('_')[0];
// Exchange code for token
const resp = await fetch('https://github.com/login/oauth/access_token', {
method: 'POST',
headers: { Accept: 'application/json' },
body: new URLSearchParams({
client_id: GITHUB_CLIENT_ID,
client_secret: GITHUB_CLIENT_SECRET,
code,
}),
});
const data = await resp.json();
const token = data.access_token;
if (token) {
userSessions[telegramId] = { githubToken: token };
bot.sendMessage(telegramId, '✅ Berhasil login ke GitHub! Silakan pilih fitur di menu.');
res.send('Login berhasil. Silakan kembali ke Telegram!');
} else {
res.send('Login gagal.');
}
});
/* ------------- TELEGRAM BOT LOGIC ------------- */
// Start command
bot.onText(/\/start/, (msg) => {
const keyboard = {
inline_keyboard: [
[{ text: '🔑 Login GitHub', url: `${BASE_URL}/login?tid=${msg.from.id}` }],
[{ text: '📂 List Repository', callback_data: 'list_repo' }],
[{ text: '🔗 List Domain', callback_data: 'list_domain' }],
[{ text: '❌ Logout', callback_data: 'logout' }],
],
};
bot.sendMessage(msg.chat.id,
`👋 *Selamat datang di GitHub Manager Bot!*\n\n` +
`Fitur:\n` +
`• List, hapus, dan kelola repo\n` +
`• Hubungkan repo ke domain\n` +
`• List domain terhubung\n` +
`• Upload file/folder ke repo\n`,
{ parse_mode: 'Markdown', reply_markup: keyboard }
);
});
// Handler tombol inline
bot.on('callback_query', async (query) => {
const userId = query.from.id.toString();
const session = userSessions[userId];
if (!session || !session.githubToken) {
return bot.answerCallbackQuery(query.id, { text: 'Silakan login GitHub dulu!', show_alert: true });
}
const octokit = new Octokit({ auth: session.githubToken });
if (query.data === 'list_repo') {
const repos = await octokit.repos.listForAuthenticatedUser();
const keyboard = repos.data.map(repo => [
{ text: `🌐 ${repo.name}`, callback_data: `repo_${repo.owner.login}/${repo.name}` }
]);
bot.sendMessage(query.message.chat.id, '*Daftar Repository Anda*:', {
parse_mode: 'Markdown',
reply_markup: { inline_keyboard: keyboard }
});
} else if (query.data.startsWith('repo_')) {
// Menu untuk repo tertarget
const repoFull = query.data.replace('repo_', '');
const keyboard = [
[{ text: '🗑️ Hapus Repo', callback_data: `delete_${repoFull}` }],
[{ text: '🌐 Hubungkan Domain', callback_data: `domain_${repoFull}` }],
[{ text: '⬆️ Upload File/Folder', callback_data: `upload_${repoFull}` }]
];
bot.sendMessage(query.message.chat.id, `*Kelola Repo: ${repoFull}*`, {
parse_mode: 'Markdown', reply_markup: { inline_keyboard: keyboard }
});
} else if (query.data.startsWith('delete_')) {
// Hapus repo
const repoFull = query.data.replace('delete_', '');
await octokit.repos.delete({ owner: repoFull.split('/')[0], repo: repoFull.split('/')[1] });
bot.sendMessage(query.message.chat.id, `✅ Repo *${repoFull}* berhasil dihapus.`, { parse_mode: 'Markdown' });
} else if (query.data.startsWith('domain_')) {
// Minta input domain user
const repoFull = query.data.replace('domain_', '');
session.waitingDomainFor = repoFull;
bot.sendMessage(query.message.chat.id, `Masukkan domain yang ingin dihubungkan ke repo *${repoFull}* (hanya domain, tanpa http)`, { parse_mode: 'Markdown' });
} else if (query.data === 'list_domain') {
// Cek semua repo, tampilkan yang punya file CNAME
const repos = await octokit.repos.listForAuthenticatedUser();
let response = '🔗 *List Domain Custom di Repo Anda:*\n\n';
for (const repo of repos.data) {
try {
const cname = await octokit.repos.getContent({
owner: repo.owner.login, repo: repo.name, path: 'CNAME'
});
const domain = Buffer.from(cname.data.content, 'base64').toString('utf8');
response += `• *${repo.name}*: ${domain}\n`;
} catch (e) { /* skip repo tanpa CNAME */ }
}
bot.sendMessage(query.message.chat.id, response, { parse_mode: 'Markdown' });
} else if (query.data.startsWith('upload_')) {
// Minta file dari user
const repoFull = query.data.replace('upload_', '');
session.waitingUploadFor = repoFull;
bot.sendMessage(query.message.chat.id, `Silakan upload file atau ZIP folder untuk diunggah ke repo *${repoFull}*`, { parse_mode: 'Markdown' });
} else if (query.data === 'logout') {
delete userSessions[userId];
bot.sendMessage(query.message.chat.id, '❌ Anda telah logout dari GitHub.');
}
bot.answerCallbackQuery(query.id);
});
// Input domain (setelah tombol domain)
bot.on('message', async (msg) => {
const userId = msg.from.id.toString();
const session = userSessions[userId];
if (!session || !session.githubToken) return;
// Hubungkan domain ke repo
if (session.waitingDomainFor) {
const repoFull = session.waitingDomainFor;
const octokit = new Octokit({ auth: session.githubToken });
const domain = msg.text.trim();
await octokit.repos.createOrUpdateFileContents({
owner: repoFull.split('/')[0],
repo: repoFull.split('/')[1],
path: 'CNAME',
message: `Set custom domain via Telegram Bot`,
content: Buffer.from(domain).toString('base64'),
});
bot.sendMessage(msg.chat.id, `🌐 Domain *${domain}* berhasil dihubungkan ke repo *${repoFull}*`, { parse_mode: 'Markdown' });
delete session.waitingDomainFor;
}
});
/* ------------- FILE UPLOAD VIA TELEGRAM ------------- */
bot.on('document', async (msg) => {
const userId = msg.from.id.toString();
const session = userSessions[userId];
if (!session || !session.githubToken || !session.waitingUploadFor) return;
const doc = msg.document;
const fileId = doc.file_id;
const repoFull = session.waitingUploadFor;
// Download file dari Telegram
const fileLink = await bot.getFileLink(fileId);
const filePath = path.join(__dirname, 'uploads', doc.file_name);
const res = await fetch(fileLink.href);
const fileBuffer = await res.arrayBuffer();
fs.writeFileSync(filePath, Buffer.from(fileBuffer));
// Upload file ke repo GitHub
const octokit = new Octokit({ auth: session.githubToken });
const content = fs.readFileSync(filePath).toString('base64');
await octokit.repos.createOrUpdateFileContents({
owner: repoFull.split('/')[0],
repo: repoFull.split('/')[1],
path: doc.file_name,
message: `Upload ${doc.file_name} via Telegram`,
content,
});
bot.sendMessage(msg.chat.id, `✅ File *${doc.file_name}* berhasil diupload ke repo *${repoFull}*`, { parse_mode: 'Markdown' });
fs.unlinkSync(filePath);
delete session.waitingUploadFor;
});
/* ------------- START EXPRESS SERVER ------------- */
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});