├── Aptfile ├── creds └── .gitkeep ├── stoparia.sh ├── .gitignore ├── Procfile ├── start.sh ├── heroku.yml ├── documents └── file_0.torrent ├── Dockerfile ├── config.js ├── utils ├── istorrent.js ├── disk.js ├── zipper.js └── utils.js ├── credentials.json ├── app.json ├── aria ├── sizechecker.js ├── add.js ├── ariacancel.js ├── ariaupload.js ├── ariahandler.js └── status.js ├── telegram ├── command.js └── msgutils.js ├── package.json ├── README.md ├── test.js ├── drive ├── AuthUrl.js ├── token.js └── classupload.js ├── database ├── userdb.js └── dbtoken.js ├── aria.sh └── index.js /Aptfile: -------------------------------------------------------------------------------- 1 | aria2 -------------------------------------------------------------------------------- /creds/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /stoparia.sh: -------------------------------------------------------------------------------- 1 | pkill -e aria2c 2 | echo service stopped -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/* 2 | downloads/* 3 | .idea/* 4 | -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | worker: chmod +x ./start.sh && bash ./start.sh && npm start 2 | -------------------------------------------------------------------------------- /start.sh: -------------------------------------------------------------------------------- 1 | npm install && chmod +x ./aria.sh && bash ./aria.sh && node index.js -------------------------------------------------------------------------------- /heroku.yml: -------------------------------------------------------------------------------- 1 | build: 2 | docker: 3 | worker: Dockerfile 4 | run: 5 | worker: bash start.sh && npm start 6 | -------------------------------------------------------------------------------- /documents/file_0.torrent: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aryanvikash/Torrent-DriveLeecher-Bot/HEAD/documents/file_0.torrent -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:3.10.2 2 | 3 | 4 | RUN apk add --no-cache ca-certificates 5 | 6 | RUN apk add --no-cache --update \ 7 | git \ 8 | bash \ 9 | nodejs-current \ 10 | npm \ 11 | aria2 \ 12 | coreutils 13 | 14 | 15 | 16 | RUN mkdir /bot 17 | RUN chmod 777 /bot 18 | WORKDIR /bot 19 | 20 | COPY . /bot 21 | 22 | RUN chmod -R 777 /bot 23 | 24 | CMD ["bash","start.sh"] 25 | -------------------------------------------------------------------------------- /config.js: -------------------------------------------------------------------------------- 1 | // const tgToken = "894269743:AAH3OAtoNulAMPwJg-Cp4zAGBxGazTlzn38"; //aryantestbot 2 | const tgToken = "1237067579:AAGIFKPpyPk9FGD55SpKN6CgZaiW8iEj2Io"; //gtorrent 3 | const downloadFolder = "downloads"; 4 | const mongoUrl = "mongodb+srv://aryanvikash:vikash12@cluster0-mp4rw.mongodb.net/test?retryWrites=true&w=majority" 5 | // const maxSize = 10; 6 | 7 | module.exports = { tgToken, downloadFolder, mongoUrl }; 8 | -------------------------------------------------------------------------------- /utils/istorrent.js: -------------------------------------------------------------------------------- 1 | const axios = require('axios'); 2 | 3 | 4 | async function isTorrent(url) { 5 | try { 6 | var response = await axios.get(url) 7 | if (response.headers["content-type"] === "application/x-bittorrent") { 8 | return true 9 | } 10 | else { 11 | return false 12 | } 13 | } 14 | catch (e) { 15 | 16 | } 17 | 18 | } 19 | 20 | module.exports = isTorrent 21 | -------------------------------------------------------------------------------- /credentials.json: -------------------------------------------------------------------------------- 1 | { 2 | "installed": { 3 | "client_id": "306263492937.googleusercontent.com", 4 | "project_id": "xyz", 5 | "auth_uri": "https://accounts.google.com/o/oauth2/auth", 6 | "token_uri": "https://oauth2.googleapis.com/token", 7 | "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", 8 | "client_secret": "454tretrte", 9 | "redirect_uris": ["urn:ietf:wg:oauth:2.0:oob", "http://localhost"] 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "G Torr bot", 3 | "description": "This is a telegram bot writen in Nodejs To mirror file in Google Drive.", 4 | "logo": "https://telegra.ph/file/6c67d32196700f6712af7.jpg", 5 | "keywords": [ 6 | "telegram", 7 | "mirror", 8 | "googledrive" 9 | ], 10 | "repository": "https://github.com/aryanvikash/webtorretbot", 11 | "success_url": "https://telegram.dog/torrentdrive_bot", 12 | "website": "https://github.com/aryanvikash/webtorretbot", 13 | "env": { 14 | 15 | }, 16 | "stack": "container" 17 | } 18 | -------------------------------------------------------------------------------- /aria/sizechecker.js: -------------------------------------------------------------------------------- 1 | const { humanbytes } = require("../utils/utils") 2 | 3 | // const maxSize = 20737418240; 4 | const maxSize = 10000000000 5 | 6 | async function crossedSizeLimit(gid, aria2) { 7 | 8 | const r = await aria2.call("tellStatus", gid); 9 | 10 | console.log(r.totalLength) 11 | 12 | if (r.totalLength > maxSize) { 13 | console.log("size exceed:", humanbytes(r.totalLength)) 14 | return r.totalLength 15 | } 16 | else { 17 | console.log("Under Size", humanbytes(r.totalLength)) 18 | return false 19 | } 20 | 21 | } 22 | 23 | 24 | 25 | module.exports = crossedSizeLimit 26 | 27 | -------------------------------------------------------------------------------- /telegram/command.js: -------------------------------------------------------------------------------- 1 | class command { 2 | constructor() { 3 | this.start = /^\/start/; 4 | this.test = /\/test/; 5 | this.server = /\/disk/; 6 | this.zip = /\/zip (.+)/ 7 | this.cancel = /\/cancel (.+)/ 8 | // this.magnet = /\/up (.+)/; 9 | this.setTD = /\/addtd (.+)/ 10 | this.removeTD = /\/rmtd/ 11 | this.magnet = /^(magnet:\?xt.+)|^(https?:\/\/.+)/; 12 | this.doc = /\/up/; 13 | this.doczip = /\/zip/; 14 | this.help = /\/help/; 15 | this.login = /\/login/; 16 | this.token = /^[\d]\/(.{55})/; 17 | this.logout = /\/logout/; 18 | } 19 | } 20 | 21 | module.exports = command; 22 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "webtorretbot", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "node index.js", 8 | "dev": "nodemon index.js" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "git+https://github.com/aryanvikash/webtorretbot.git" 13 | }, 14 | "keywords": [], 15 | "author": "", 16 | "license": "ISC", 17 | "bugs": { 18 | "url": "https://github.com/aryanvikash/webtorretbot/issues" 19 | }, 20 | "homepage": "https://github.com/aryanvikash/webtorretbot#readme", 21 | "dependencies": { 22 | "archiver": "^5.0.0", 23 | "aria2": "^4.1.0", 24 | "axios": "^0.19.2", 25 | "fs-extra": "^9.0.0", 26 | "googleapis": "^49.0.0", 27 | "mkdirp": "^1.0.4", 28 | "mongodb": "^3.5.7", 29 | "node-telegram-bot-api": "0.40.0", 30 | "rimraf": "^3.0.2" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /utils/disk.js: -------------------------------------------------------------------------------- 1 | 2 | const { sendmsg } = require("../telegram/msgutils") 3 | const { exec } = require('child_process'); 4 | 5 | const diskinfo = async (uptime, m, b) => { 6 | let path = "/" 7 | try { 8 | 9 | 10 | 11 | exec(`df --output="size,used,avail" -h "${path}" | tail -n1`, 12 | (err, res) => { 13 | if (!err) { 14 | 15 | const disk = res.trim().split(/\s+/); 16 | let msg = `Total: ${disk[0]}B\n` 17 | msg += `Used: ${disk[1]}B \n` 18 | msg += `Available: ${disk[2]}\n\n` 19 | msg += `Bot UpTime : ${uptime}\n` 20 | 21 | sendmsg(msg, m, b) 22 | } 23 | 24 | } 25 | ); 26 | 27 | 28 | } 29 | catch (e) { 30 | console.log(e); 31 | return e.message; 32 | } 33 | }; 34 | 35 | module.exports = diskinfo; 36 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Torrent to Private google Drive bot Based on Aria2 2 | 3 | Nothing special just making opensource old projects. 4 | No Time to update 5 | 6 | # Requirements 7 | 8 | ``` 9 | Operating system - linux 10 | install aria2 11 | ``` 12 | 13 | ## Start Bot 14 | 15 | $ `chmod +x ./start.sh && bash ./start.sh && npm start` 16 | 17 | # Config [`config.js`] 18 | 19 | ``` 20 | tgToken = "1237067579:AAGIFKPpyPk9FGD55" 21 | downloadFolder = "downloads"; 22 | mongoUrl = "mongodb+srv://" 23 | ``` 24 | 25 | ## Google drive Setup 26 | 27 | Update credentials.json file and keep your google drive client id and secret and you are good to go. 28 | 29 | ## Avaliable Commands 30 | 31 | ``` 32 | start - start 33 | test - i dont rememeber 34 | disk - current disk space 35 | zip - zip torrent or Telegram file 36 | cancel - cancel current download 37 | up - upload file 38 | addtd - Add Teamdrive 39 | rmtd - Remove Teamdrive 40 | help - Maybe help 41 | login -Login to google drive 42 | logout - Logout fro google Drive 43 | ``` 44 | -------------------------------------------------------------------------------- /utils/zipper.js: -------------------------------------------------------------------------------- 1 | const path = require("path") 2 | const fs = require("fs-extra") 3 | const archiver = require('archiver'); 4 | const {cleanup} = require("./utils"); 5 | 6 | 7 | //TODO check filesize before zipping it causing server crash 8 | const zipIt = dir_path => { 9 | 10 | const archive = archiver('zip',{zlib:{level:9}}) 11 | zip_path = path.join(path.dirname(dir_path),`${path.basename(dir_path)}.zip`) 12 | return new Promise((resolve, reject)=>{ 13 | const stream = fs.createWriteStream(zip_path); 14 | 15 | 16 | archive.on('error', function(err) { 17 | console.error(err.message) 18 | 19 | }); 20 | 21 | stream.on("close",()=>{ 22 | console.log("Zipping complete") 23 | cleanup(dir_path) 24 | resolve(zip_path) 25 | }) 26 | 27 | stream.on("error",(error) => { 28 | console.error(error.message) 29 | reject(error) 30 | }) 31 | 32 | archive.directory(dir_path,path.basename(dir_path)) 33 | archive.pipe(stream) 34 | archive.finalize() 35 | 36 | }) 37 | }; 38 | 39 | 40 | 41 | 42 | module.exports = { zipIt }; 43 | -------------------------------------------------------------------------------- /telegram/msgutils.js: -------------------------------------------------------------------------------- 1 | 2 | const {dlDetails } = require("../utils/utils") 3 | 4 | 5 | async function sendmsg(text, msg, bot) { 6 | // const chatId = msg.chat.id; 7 | const res = await bot.sendMessage(msg.chat.id, text, { parse_mode: "HTML" }); 8 | return res; 9 | } 10 | 11 | async function edit(text, sentm, bot, opts = null) { 12 | if (!opts) { 13 | await bot.editMessageText(text, { 14 | chat_id: sentm.chat.id, 15 | message_id: sentm.message_id, 16 | parse_mode: "HTML", 17 | }); 18 | } 19 | else { 20 | await bot.editMessageText(text, opts); 21 | } 22 | } 23 | 24 | 25 | 26 | 27 | async function gidSendmsg(text, gid, bot) { 28 | console.log(dlDetails[gid]) 29 | const chatId = dlDetails[gid].chatId 30 | return await bot.sendMessage(chatId, text, {parse_mode: "HTML"}); 31 | } 32 | 33 | 34 | async function gidEditmsg(text, gid, bot) { 35 | 36 | try { 37 | await bot.editMessageText(text, { 38 | chat_id: dlDetails[gid].chatId, 39 | message_id: dlDetails[gid].msgId, 40 | parse_mode: "HTML", 41 | }); 42 | } 43 | catch (e) { 44 | console.log(e.message)} 45 | } 46 | 47 | // exports 48 | 49 | module.exports = { sendmsg, edit, gidSendmsg, gidEditmsg }; 50 | -------------------------------------------------------------------------------- /aria/add.js: -------------------------------------------------------------------------------- 1 | const path = require("path") 2 | 3 | const { sendmsg, edit } = require("../telegram/msgutils") 4 | 5 | const { humanbytes, DownloadList, dlDetails, addUser, removeUser } = require("../utils/utils") 6 | 7 | const sendStatus = require("./status") 8 | 9 | 10 | 11 | 12 | 13 | async function ariaAdd(aria2, magnet, msg, bot, is_zip = false) { 14 | 15 | let userId = msg.from.id.toString() 16 | 17 | try { 18 | const gid = await aria2.call("addUri", [magnet], { dir: path.join(__dirname, `../downloads/${msg.from.id.toString()}`) }); 19 | 20 | // DownloadList.push(msg.from.id) 21 | addUser(msg, gid, is_zip) 22 | DownloadList[msg.from.id] = true 23 | let sentm = await sendmsg(`Preparing MetaData ...!!\n`, msg, bot) 24 | await sendStatus(gid, aria2, sentm, bot) 25 | 26 | 27 | } 28 | catch (e) { 29 | await sendmsg(e.message, msg, bot) 30 | DownloadList[msg.from.id] = false 31 | console.error(e.message); 32 | 33 | return 34 | } 35 | // consoles.log(await aria2.listMethods()); 36 | 37 | 38 | // await sendStatus(gid, aria2, sentm, bot) 39 | 40 | 41 | } 42 | 43 | 44 | module.exports = ariaAdd 45 | -------------------------------------------------------------------------------- /aria/ariacancel.js: -------------------------------------------------------------------------------- 1 | const {sendmsg, edit, gidEditmsg} = require("../telegram/msgutils") 2 | const {deleteFile, deleteFolder, DownloadList} = require("../utils/utils") 3 | const fs = require('fs-extra') 4 | const path = require("path") 5 | 6 | async function cancelgid(aria2, gid, msg, bot, opts = null) { 7 | 8 | DownloadList[msg.from.id] = false 9 | 10 | try { 11 | var res = await aria2.call("tellStatus", gid, ['status', 'bittorrent']) 12 | var name = res.bittorrent.info.name 13 | await aria2.call("remove", gid); 14 | await bot.deleteMessage(opts.chat_id, opts.message_id) 15 | await bot.sendMessage(opts.chat_id, `${name} Cancelled !!`, {parse_mode: "HTML"}); 16 | console.log(`Cancellled: ${name} gid: ${gid}`,) 17 | 18 | 19 | } catch (e) { 20 | console.log(e.message) 21 | await sendmsg("Make Sure Your Download Is Active", msg, bot) 22 | } 23 | 24 | try { 25 | await deletePath(path.join(__dirname, `../downloads/${msg.from.id.toString()}/${name}`)) 26 | } catch (e) { 27 | console.log(e.message) 28 | } 29 | 30 | 31 | } 32 | 33 | 34 | async function deletePath(downloadPath) { 35 | let stats = fs.statSync(downloadPath); 36 | if (stats.isDirectory()) { 37 | deleteFolder(downloadPath) 38 | } else { 39 | deleteFile(downloadPath) 40 | } 41 | } 42 | 43 | 44 | module.exports = {cancelgid} 45 | -------------------------------------------------------------------------------- /test.js: -------------------------------------------------------------------------------- 1 | // const {gdriveClient} = require("./drive/classupload"); 2 | // const fs = require("fs") 3 | // const path = require("path") 4 | // const archiver = require('archiver'); 5 | // const archive = archiver('zip',{zlib:{level:9}}) 6 | // 7 | // dir_path = "/home/aryanvikash/Projects/nodejs/webtorretbot/test/" 8 | // 9 | // function zipper(dir_path){ 10 | // 11 | // zip_path = path.join(path.dirname(dir_path),`${path.basename(dir_path)}.zip`) 12 | // return new Promise((resolve, reject)=>{ 13 | // const stream = fs.createWriteStream(zip_path); 14 | // 15 | // 16 | // archive.on('error', function(err) { 17 | // console.error(err.message) 18 | // 19 | // }); 20 | // 21 | // stream.on("close",()=>{ 22 | // console.log("Zipping complete") 23 | // resolve(zip_path) 24 | // }) 25 | // 26 | // stream.on("error",(error) => { 27 | // console.error(error.message) 28 | // reject(error) 29 | // }) 30 | // 31 | // archive.directory(dir_path,path.basename(dir_path)) 32 | // archive.pipe(stream) 33 | // archive.finalize() 34 | // 35 | // }) 36 | // } 37 | // 38 | // // console.log(zipper(dir_path)) 39 | // 40 | // 41 | // // (async ()=>{ 42 | // // 43 | // // let drive = await new gdriveClient("985378987") 44 | // // console.log( await drive.upload_handler(await zipper(dir_path))) 45 | // // })(); -------------------------------------------------------------------------------- /drive/AuthUrl.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs"); 2 | const path = require("path"); 3 | const { google } = require("googleapis"); 4 | const { sendmsg } = require("../telegram/msgutils"); 5 | const SCOPES = ["https://www.googleapis.com/auth/drive.file"]; 6 | 7 | const cred = path.join("dsds", "../credentials.json"); 8 | 9 | oAuth2Client = null; 10 | 11 | async function getAuthurl(msg, bot) { 12 | 13 | 14 | fs.readFile(cred, async(err, content) => { 15 | if (err) { 16 | console.log("Make Sure You Have Your clint secret file in path:", err); 17 | return; 18 | } 19 | const credentials = JSON.parse(content); 20 | 21 | const { client_secret, client_id, redirect_uris } = credentials.installed; 22 | var oAuth2Client = new google.auth.OAuth2( 23 | client_id, 24 | client_secret, 25 | redirect_uris[0] 26 | ); 27 | //Generate Auth Url 28 | const authUrl = oAuth2Client.generateAuthUrl({ 29 | access_type: "offline", 30 | scope: SCOPES, 31 | }); 32 | // send It to bot For Auth It 33 | const opts = { 34 | reply_markup: { 35 | inline_keyboard: [ 36 | [{ text: "Visit Me", url: authUrl }] 37 | ] 38 | } 39 | }; 40 | await bot.sendMessage(msg.chat.id, 'Generate Auth Token and Send It Here', opts); 41 | // sendmsg(authUrl, msg, bot); 42 | // console.log(authUrl); 43 | }); 44 | } //getauthUrl 45 | 46 | // getAuthurl(); 47 | 48 | module.exports = { getAuthurl }; 49 | -------------------------------------------------------------------------------- /drive/token.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs"); 2 | const { sendmsg, edit } = require("../telegram/msgutils"); 3 | const path = require("path"); 4 | const { google } = require("googleapis"); 5 | 6 | const SCOPES = [ 7 | "https://www.googleapis.com/auth/drive.file" 8 | ]; 9 | 10 | var cred = path.join(__dirname, "../credentials.json"); 11 | var oAuth2Client = null; 12 | 13 | function CreateToken(code, msg, bot) { 14 | fs.readFile(cred, (err, content) => { 15 | if (err) { 16 | console.log("Make Sure You Have Your client secret file in path:", err); 17 | return; 18 | } 19 | const credentials = JSON.parse(content); 20 | 21 | const { client_secret, client_id, redirect_uris } = credentials.installed; 22 | oAuth2Client = new google.auth.OAuth2( 23 | client_id, 24 | client_secret, 25 | redirect_uris[0] 26 | ); 27 | 28 | // Create token 29 | token(code, msg, bot); 30 | }); 31 | } //getauthUrl 32 | 33 | function token(code, msg, bot) { 34 | const userId = msg.from.id.toString(); 35 | const TOKEN_PATH = path.join(__dirname, `../creds/${userId}.json`); 36 | oAuth2Client.getToken(code, (err, token) => { 37 | if (err) { 38 | sendmsg("Check Your Auth Token And Try Again !!", msg, bot); 39 | console.error("Not A valid Access Token"); 40 | return; 41 | } 42 | oAuth2Client.setCredentials(token); 43 | // Store the token to disk for later program executions 44 | fs.writeFile(TOKEN_PATH, JSON.stringify(token), (err) => { 45 | console.log("writing Token File.."); 46 | 47 | if (err) { 48 | sendmsg("Token Write Error report @aryanvikash", msg, bot); 49 | return console.error(err); 50 | } 51 | console.log("Token stored to", TOKEN_PATH); 52 | sendmsg("Successful Authorized 🎉", msg, bot); 53 | }); 54 | 55 | // callback(oAuth2Client); 56 | }); 57 | } 58 | 59 | module.exports = { CreateToken }; 60 | -------------------------------------------------------------------------------- /aria/ariaupload.js: -------------------------------------------------------------------------------- 1 | const {sendmsg, edit} = require("../telegram/msgutils"); 2 | const { 3 | humantime, 4 | humanbytes, 5 | DownloadList 6 | 7 | } = require("../utils/utils"); 8 | 9 | const path = require("path"); 10 | 11 | const {zipIt} = require("../utils/zipper"); 12 | const {gdriveClient} = require("../drive/classupload"); 13 | 14 | async function ariaUpload(res, msg, bot, is_zip = false) { 15 | // DownloadList.pop(msg.from.id) 16 | const user_id = msg.from.id.toString() 17 | const name = res.bittorrent.info.name; 18 | const Totalsize = humanbytes(res.totalLength); 19 | const file_path = path.join(__dirname, `../downloads/${user_id}/${name}`); 20 | 21 | console.log("uploading Started...", file_path) 22 | let sentm = await sendmsg( 23 | status_str(name,Totalsize,"Download complete"), 24 | msg, 25 | bot 26 | ); 27 | try { 28 | var drive = await new gdriveClient(user_id) 29 | } catch (e) { 30 | console.error(e.message) 31 | return 32 | } 33 | // If isDirectory 34 | 35 | if (is_zip) { 36 | await edit(status_str(name,Totalsize,"Zipping"), sentm, bot); 37 | try { 38 | let zipFilePath = await zipIt(file_path) 39 | await edit(status_str(name,Totalsize,"Uploading"), sentm, bot); 40 | let downloadUrl = await drive.upload_handler(zipFilePath) 41 | let successMsg = `Name : ${name}\nSize : ${Totalsize}\nDownload : ${name}🗄 ` 42 | // await edit(successMsg, sentm, bot); 43 | await send_download_msg(name, Totalsize, downloadUrl, bot, sentm) 44 | } catch (error) { 45 | console.log("zip error : ", error.message) 46 | await edit(`zip Upload Error : ${error.message} \n#error`, sentm, bot); 47 | } 48 | } 49 | else { 50 | // withoutzip 51 | try { 52 | edit(status_str(name,Totalsize,"uploading"), sentm, bot); 53 | 54 | const downloadUrl = await drive.upload_handler(file_path) 55 | const successMsg = `Name : ${name}\nSize : ${Totalsize}\nDownload : ${name}🗂 ` 56 | // await edit(successMsg, sentm, bot); 57 | await send_download_msg(name, Totalsize, downloadUrl, bot, sentm) 58 | } 59 | catch (error) { 60 | console.log("upload error : ", error.message) 61 | await edit(`Upload Error : ${error.message} \n#error`, sentm, bot); 62 | } 63 | } 64 | } 65 | 66 | 67 | 68 | function status_str(name,size,status){ 69 | let smsg = `Name: ${name}\n`; 70 | smsg += `Total Size: ${size} \n`; 71 | smsg += `Status: ${status} \n` ; 72 | return smsg 73 | } 74 | 75 | async function send_download_msg(name,size,downloadUrl,bot,sentm){ 76 | const opts = { 77 | chat_id: sentm.chat.id, 78 | message_id: sentm.message_id, 79 | reply_markup: { 80 | inline_keyboard: [ 81 | [{text: "Download", url: downloadUrl}] 82 | ] 83 | }, 84 | parse_mode: "HTML" 85 | } 86 | let smsg = `Name: ${name} \nsize: ${size}\n` 87 | 88 | 89 | await bot.editMessageText(smsg, opts); 90 | } 91 | 92 | module.exports = ariaUpload 93 | -------------------------------------------------------------------------------- /database/userdb.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const { MongoClient } = require('mongodb'); 4 | const { mongoUrl } = require("../config") 5 | 6 | 7 | class MongoDB{ 8 | 9 | constructor(user_id) { 10 | this.client = new MongoClient(mongoUrl, { useUnifiedTopology: true }); 11 | this.con = null 12 | this.user_id = user_id.toString() 13 | this.db_instance = null 14 | this.col = null 15 | 16 | return new Promise(async ( resolve, reject)=>{ 17 | try { 18 | this.con = await this.client.connect(); 19 | this.db_instance = await this.con.db("gtusers"); 20 | this.col = await this.db_instance.collection("userinfo"); 21 | resolve(this) 22 | }catch (e) { 23 | reject(e) 24 | } 25 | }) 26 | } 27 | 28 | 29 | async setTeamdrive(tdid) { 30 | 31 | try { 32 | let result = await this.col.findOne({_id: this.user_id}) 33 | let isInseted = false 34 | 35 | if (result) { 36 | 37 | let myquery = {_id: this.user_id.toString} 38 | let updateData = {$set: {TD: tdid.toString()}} 39 | 40 | 41 | await this.col.updateOne(myquery, updateData) 42 | console.log("database Updated") 43 | isInseted = true 44 | } else { 45 | 46 | await this.col.insertOne({ 47 | _id: this.user_id, 48 | teamdriveid: tdid.toString() 49 | }) 50 | console.log("Teamdrive Id Inserted") 51 | isInseted = true 52 | 53 | } 54 | 55 | return isInseted 56 | } catch (e) { 57 | console.log(e); 58 | return false 59 | } // Not closing it here bcz i need it in get td id 60 | //finally { 61 | // await this.con.close() 62 | // } 63 | } 64 | 65 | 66 | 67 | async getTeamdrive() { 68 | 69 | try { 70 | const result = await this.col.findOne({_id: this.user_id}); 71 | let teamdriveid = null 72 | 73 | if (result) { 74 | 75 | teamdriveid = result.teamdriveid 76 | } 77 | return teamdriveid 78 | } 79 | catch (e) { 80 | console.log(e.message); 81 | 82 | }finally { 83 | await this.con.close() 84 | } 85 | } // constructor 86 | 87 | 88 | 89 | async removeTeamdrive() { 90 | 91 | try { 92 | 93 | const result = await this.col.findOne({_id: this.user_id}); 94 | let deleted = false 95 | 96 | if (result) { 97 | await this.col.deleteOne({ _id: this.user_id }) 98 | deleted = true 99 | } 100 | else { 101 | console.log("There Is No Teamdrive Attached") 102 | } 103 | 104 | 105 | return deleted 106 | } 107 | catch (e) { 108 | console.log(e.message); 109 | return false 110 | }finally { 111 | await this.con.close() 112 | } 113 | } 114 | 115 | 116 | } // class 117 | 118 | 119 | // (async ()=>{ 120 | // try { 121 | // let mongo = await new MongoDB(985378987) 122 | // let td = await mongo.getTeamdrive() 123 | // console.log(td) 124 | // }catch (e) { 125 | // console.error(e.message) 126 | // } 127 | // })(); 128 | 129 | module.exports = { MongoDB} 130 | -------------------------------------------------------------------------------- /database/dbtoken.js: -------------------------------------------------------------------------------- 1 | const {MongoClient} = require('mongodb'); 2 | const {mongoUrl} = require("../config") 3 | const fs = require("fs") 4 | const path = require("path") 5 | 6 | 7 | async function TokenInsert(id) { 8 | console.log("Inserting Token In database") 9 | const client = new MongoClient(mongoUrl, {useUnifiedTopology: true}); 10 | const TokenPath = path.join(__dirname, `../creds/${id.toString()}.json`) 11 | fs.readFile(TokenPath, async (err, token) => { 12 | if (!err) { 13 | try { 14 | var con = await client.connect(); 15 | let dbinstance = await con.db("gtusers") 16 | let col = await dbinstance.collection("tokens") 17 | const result = await col.findOne({_id: id.toString()}) 18 | if (!result) { 19 | await col.insertOne({ 20 | _id: id.toString(), 21 | token: token 22 | }) 23 | console.log(`${id} inserted To Database`) 24 | } else { 25 | console.log(`${id} Already In Database`) 26 | } 27 | 28 | return true 29 | } catch (e) { 30 | console.error(e.message); 31 | return false 32 | }finally { 33 | await con.close() 34 | } 35 | } else { 36 | console.log(err.message) 37 | return false 38 | } 39 | 40 | }) 41 | 42 | 43 | } 44 | 45 | // TokenInsert(920262337) 46 | 47 | 48 | async function createTokenFile(id) { 49 | const client = new MongoClient(mongoUrl, {useUnifiedTopology: true}); 50 | const TokenPath = path.join(__dirname, `../creds/${id.toString()}.json`) 51 | try { 52 | 53 | var con = await client.connect(); 54 | 55 | let dbinstance = await con.db("gtusers") 56 | 57 | let col = await dbinstance.collection("tokens") 58 | 59 | const result = await col.findOne({_id: id.toString()}) 60 | 61 | const token = result.token 62 | 63 | con.close() 64 | 65 | 66 | if (token) { 67 | fs.writeFile(TokenPath, token, (err) => { 68 | if (!err) { 69 | console.log("Database auth found Creating Token With Database") 70 | return true 71 | } else { 72 | return false 73 | } 74 | }) 75 | 76 | } else { 77 | console.log("no Result Found"); 78 | return false; 79 | } 80 | 81 | return true 82 | } catch (e) { 83 | if (e.message !== "Cannot read property 'token' of null") 84 | console.error(e.message); 85 | else { 86 | console.log("Not found in Database Generating auth url") 87 | } 88 | return false 89 | 90 | } 91 | 92 | } 93 | 94 | // createTokenFile("920262337") 95 | 96 | 97 | async function deleteToken(id) { 98 | const client = new MongoClient(mongoUrl, {useUnifiedTopology: true}); 99 | try { 100 | var con = await client.connect(); 101 | 102 | let dbinstance = await con.db("gtusers") 103 | 104 | let col = await dbinstance.collection("tokens") 105 | 106 | const result = await col.findOne({_id: id.toString()}) 107 | if (result) { 108 | 109 | await col.deleteOne({_id: id.toString()}) 110 | console.log(`Removed ${id} from Database`) 111 | } else { 112 | console.log(`there is no Token of ${id} `) 113 | } 114 | } catch (e) { 115 | console.log(e); 116 | }finally { 117 | await con.close() 118 | } 119 | 120 | } 121 | 122 | // deleteToken("920262337") 123 | 124 | module.exports = {deleteToken, createTokenFile, TokenInsert} 125 | -------------------------------------------------------------------------------- /aria/ariahandler.js: -------------------------------------------------------------------------------- 1 | 2 | const { edit, gidSendmsg, gidEditmsg} = require("../telegram/msgutils") 3 | const {humanbytes, DownloadList, renameGid, dlDetails, getmsgcontext} = require("../utils/utils") 4 | const sendStatus = require("./status") 5 | const ariaUpload = require("./ariaupload") 6 | const crossedSizeLimit = require("./sizechecker") 7 | 8 | 9 | function ariaListners(aria2, bot) { 10 | 11 | 12 | // on download start 13 | aria2.on("onDownloadStart", async ([gid]) => { 14 | let listGid = gid 15 | // Download Start Will invoke when main File started 16 | // following = metadata file gid 17 | // followedBy = old gid 18 | var r = await aria2.call("tellStatus", listGid.gid) 19 | 20 | 21 | if (r.following) { 22 | console.log(`${r.bittorrent.info.name}Downloading Started`, gid) 23 | // replace new gid 24 | await renameGid(listGid.gid, r.following) 25 | // var metagid = r.following 26 | var newgid = listGid.gid 27 | 28 | var sentm = await gidSendmsg(`Downloading Started ...!!\n/cancel ${newgid}`, newgid, bot) 29 | const sizeExceed = await crossedSizeLimit(newgid, aria2); 30 | if (sizeExceed) { 31 | 32 | await edit(`max size Limit is 20GB But found ${humanbytes(sizeExceed)} \n #stopped 😢`, 33 | sentm, bot) 34 | try { 35 | await aria2.call("remove", newgid); 36 | 37 | } catch (e) { 38 | console.error(e.message) 39 | } 40 | } else { 41 | 42 | await sendStatus(newgid, aria2, sentm, bot) 43 | } 44 | } else { 45 | 46 | console.log("MetaData Downloading Started", gid) 47 | 48 | } 49 | }) 50 | 51 | // Ondownload Stop or cancel 52 | aria2.on("onDownloadStop", async ([gid]) => { 53 | let gids = gid 54 | console.log("stoppped", gid) 55 | DownloadList[dlDetails[gids.gid].userId] = false 56 | await gidSendmsg(`Gid ${gids.gid} Download Stopped !!`, gids.gid, bot) 57 | try { 58 | await aria2.call("remove", gids.gid) 59 | } catch (e) { 60 | console.error(e.message) 61 | } 62 | 63 | }) 64 | 65 | 66 | // download complete 67 | aria2.on("onDownloadComplete", async ([gid]) => { 68 | let gids = gid 69 | console.log("Final Complete", gid) 70 | // try { 71 | // var res = await aria2.call("tellStatus", dlDetails[gids.gid].oldgid, ['bittorrent', 'totalLength']) 72 | 73 | // console.log(dlDetails[gids.gid].chatId, dlDetails[gids.gid].msgId) 74 | 75 | // await bot.deleteMessage(dlDetails[gids.gid].chatId, dlDetails[gids.gid].msgId) 76 | 77 | 78 | // } 79 | // catch (e) { 80 | // console.log(e.message) 81 | //} 82 | 83 | 84 | }) 85 | 86 | 87 | // download error 88 | aria2.on("onDownloadError", async ([gid]) => { 89 | let gids = gid 90 | DownloadList[dlDetails[gids.gid].userId] = false 91 | delete dlDetails[gids.gid] 92 | 93 | 94 | let res = await aria2.call("tellStatus", gids.gid, ["errorMessage"]) 95 | await gidSendmsg(res.errorMessage, gids.gid, bot) 96 | console.log("on DownloadError", gid) 97 | 98 | }) 99 | 100 | 101 | // download complete but still seeding 102 | aria2.on("onBtDownloadComplete", async ([gid]) => { 103 | const gids = gid; 104 | console.log("Complete But Still seeding", gid) 105 | DownloadList[dlDetails[gids.gid].userId] = false 106 | // aria2.call("remove", gids.gid) 107 | try { 108 | var res = await aria2.call("tellStatus", gids.gid, ['bittorrent', 'totalLength']) 109 | if (res.following) { 110 | console.log(dlDetails[gids.gid]) 111 | // await bot.deleteMessage(opts.chat_id, opts.message_id) 112 | } 113 | 114 | } catch (e) { 115 | console.error(e.message) 116 | return 117 | } 118 | let msg = getmsgcontext(gids.gid) 119 | // Remove from aria cli 120 | 121 | 122 | let is_zip = dlDetails[gids.gid].zip 123 | await ariaUpload(res, msg, bot, is_zip) 124 | 125 | try { 126 | await aria2.call("remove", gids.gid) 127 | } catch (e) { 128 | console.error(e.message) 129 | } 130 | 131 | }) 132 | } 133 | 134 | 135 | module.exports = {ariaListners} 136 | -------------------------------------------------------------------------------- /utils/utils.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs-extra') 2 | const mkdirp = require('mkdirp'); 3 | const rimraf = require("rimraf"); 4 | 5 | const {downloadFolder} = require("../config"); 6 | const path = require("path"); 7 | 8 | const downloadPath = path.join(__dirname, `${downloadFolder}`); 9 | const {createTokenFile} = require("../database/dbtoken") 10 | 11 | let DownloadList = {} 12 | var dlDetails = [] 13 | 14 | 15 | async function getUserDownloadPath(msg) { 16 | let userid = msg.from.id.toString(); 17 | let dp = path.join(__dirname, `../${downloadFolder}/${userid}`); 18 | 19 | return new Promise((res, rej) => { 20 | mkdirp(dp).then(made => { 21 | console.log(`Dir Created ${made}`) 22 | res(dp) 23 | return 24 | }) 25 | }) 26 | } 27 | 28 | 29 | function humanbytes(num) { 30 | var exponent, 31 | unit, 32 | neg = num < 0, 33 | units = ["B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"]; 34 | if (neg) num = -num; 35 | if (num < 1) return (neg ? "-" : "") + num + " B"; 36 | exponent = Math.min( 37 | Math.floor(Math.log(num) / Math.log(1000)), 38 | units.length - 1 39 | ); 40 | num = Number((num / Math.pow(1000, exponent)).toFixed(2)); 41 | unit = units[exponent]; 42 | return (neg ? "-" : "") + num + " " + unit; 43 | } 44 | 45 | 46 | function humantime(ms) { 47 | let seconds = ms / 1000; 48 | let result = ""; 49 | const days = Math.floor((seconds % 31536000) / 86400); 50 | if (days > 0) result += `${days}d `; 51 | const hours = Math.floor(((seconds % 31536000) % 86400) / 3600); 52 | if (hours > 0) result += `${hours}h `; 53 | const minutes = Math.floor((((seconds % 31536000) % 86400) % 3600) / 60); 54 | if (minutes > 0) result += `${minutes}m `; 55 | seconds = ((((seconds % 31536000) % 86400) % 3600) % 60).toFixed(0); 56 | if (seconds > 0) result += `${seconds}s`; 57 | if (result === "") result += "0s"; 58 | return result; 59 | } 60 | 61 | 62 | const DownloadFolderChecker = (dpath) => { 63 | if (!fs.existsSync(dpath)) { 64 | try { 65 | fs.mkdirSync(dpath); 66 | console.log("path Created ", dpath); 67 | } catch (err) { 68 | console.log("Path not avalible"); 69 | } 70 | } else { 71 | console.log(`${dpath} is already There`) 72 | } 73 | }; 74 | 75 | 76 | async function isAuth(msg, isLogut = false) { 77 | const userId = msg.from.id.toString(); 78 | if (!isLogut) { 79 | 80 | } 81 | const credsPath = path.join(__dirname, `../creds/${userId}.json`); 82 | 83 | return new Promise(async (res, rej) => { 84 | fs.lstat(credsPath, async (err) => { 85 | // If Error That mean There is no file 86 | if (err) { 87 | 88 | console.log(`${userId} local auth file not found checking Database`); 89 | 90 | 91 | return res(await createTokenFile(userId)); 92 | } else { 93 | console.log(`${userId} is auth`); 94 | res(true); 95 | return true; 96 | } 97 | }); 98 | }); 99 | } 100 | 101 | 102 | function cleanup(file_path) { 103 | 104 | 105 | rimraf(file_path, () => console.log(`${file_path} removed from disk`)); 106 | 107 | 108 | } 109 | 110 | 111 | function addUser(msg, gid, is_zip = false) { 112 | 113 | let msgId = msg.message_id 114 | let userId = msg.from.id 115 | let chatId = msg.chat.id 116 | let userName = msg.from.username 117 | 118 | let data = { 119 | 120 | [gid]: {"msgId": msgId, "username": userName, "userId": userId, "chatId": chatId, "oldgid": gid, "zip": is_zip} 121 | } 122 | Object.assign(dlDetails, data) 123 | 124 | 125 | } 126 | 127 | 128 | function removeUser(gid) { 129 | delete dlDetails.gid 130 | console.log("removed", gid) 131 | } 132 | 133 | async function renameGid(newgid, oldgid) { 134 | 135 | try { 136 | dlDetails[newgid] = dlDetails[oldgid] 137 | delete dlDetails[oldgid] 138 | console.log(`Gid Replace Old ${oldgid} New ${newgid}`) 139 | } catch (e) { 140 | console.log("Gid Replace error :", e.message) 141 | } 142 | } 143 | 144 | 145 | function getmsgcontext(gid) { 146 | 147 | 148 | return ({ 149 | "message_id": dlDetails[gid]["message_id"], 150 | "from": { 151 | "id": dlDetails[gid]["userId"], 152 | "username": dlDetails[gid]["username"] 153 | }, 154 | "chat": { 155 | "id": dlDetails[gid]["chatId"], 156 | "username": dlDetails[gid]["username"], 157 | type: 'private' 158 | }, 159 | text: '/test sdhs', 160 | entities: [{offset: 0, length: 5, type: 'bot_command'}] 161 | }) 162 | 163 | } 164 | 165 | 166 | module.exports = { 167 | humanbytes, 168 | humantime, 169 | DownloadFolderChecker, 170 | downloadPath, 171 | cleanup, 172 | isAuth, 173 | getUserDownloadPath, 174 | DownloadList, 175 | dlDetails, 176 | addUser, 177 | removeUser, 178 | renameGid, 179 | getmsgcontext 180 | }; 181 | -------------------------------------------------------------------------------- /aria/status.js: -------------------------------------------------------------------------------- 1 | const {humanbytes} = require("../utils/utils") 2 | // const path = require("path") 3 | // const {sendmsg, edit, gidEditmsg} = require("../telegram/msgutils") 4 | // const ariaUpload = require("./ariaupload") 5 | 6 | 7 | function downloadETA(totalLength, completedLength, speed) { 8 | if (speed === 0) 9 | return '-'; 10 | const time = (totalLength - completedLength) / speed; 11 | const seconds = Math.floor(time % 60); 12 | const minutes = Math.floor((time / 60) % 60); 13 | const hours = Math.floor(time / 3600); 14 | 15 | if (hours === 0) { 16 | if (minutes === 0) { 17 | return `${seconds}s`; 18 | } else { 19 | return `${minutes}m ${seconds}s`; 20 | } 21 | } else { 22 | return `${hours}h ${minutes}m ${seconds}s`; 23 | } 24 | } 25 | 26 | const PROGRESS_MAX_SIZE = Math.floor(100 / 8); 27 | const PROGRESS_INCOMPLETE = ['▱', '▱', '▱', '▱', '▱', '▱', '▱']; 28 | 29 | 30 | function generateProgress(p) { 31 | p = Math.min(Math.max(p, 0), 100); 32 | let str = '['; 33 | const cFull = Math.floor(p / 8); 34 | const cPart = p % 8 - 1; 35 | str += '▰'.repeat(cFull); 36 | if (cPart >= 0) { 37 | str += PROGRESS_INCOMPLETE[cPart]; 38 | } 39 | str += ' '.repeat(PROGRESS_MAX_SIZE - cFull); 40 | str = `${str}] ${p}%`; 41 | 42 | return str; 43 | } 44 | 45 | 46 | function generate_status_str(res) { 47 | let smsg; // status msg 48 | let progress; 49 | if (res.totalLength === 0) { 50 | progress = 0; 51 | } else { 52 | progress = Math.round(res.completedLength * 100 / res.totalLength); 53 | } 54 | 55 | try { 56 | smsg = `Name: ${res.bittorrent.info.name}\n`; 57 | smsg += `Total Size: ${humanbytes(res.totalLength)} \n` 58 | smsg += `Downloaded : ${humanbytes(res.completedLength)}\n` 59 | smsg += `DownloadSpeed: ${humanbytes(res.downloadSpeed)}\n` 60 | smsg += `Progress: ${generateProgress(progress)}\n` 61 | smsg += `ETA: ${downloadETA(res.totalLength, res.completedLength, res.downloadSpeed)}\n` 62 | smsg += `Seeder: ${res.numSeeders}\n` 63 | smsg += `${res.gid} ` 64 | } catch (e) { 65 | smsg = `Name: Preparing Your Download\n`; 66 | smsg += `Total Size: ${humanbytes(res.totalLength)} \n` 67 | smsg += `Downloaded : ${humanbytes(res.completedLength)}\n` 68 | smsg += `DownloadSpeed: ${humanbytes(res.downloadSpeed)}\n` 69 | smsg += `Seeder: ${res.numSeeders}\n` 70 | smsg += `/cancel ${res.gid} ` 71 | } 72 | 73 | 74 | return smsg 75 | } 76 | 77 | 78 | async function sendStatus(gid, aria2, sentm, bot, pv = null) { 79 | 80 | try { 81 | let res = await aria2.call("tellStatus", gid, ['status', 'bittorrent', 'totalLength', 'completedLength', 'errorMessage', 'downloadSpeed', 'numSeeders', 'gid', 'infoHash', 'files']) 82 | await getStatus(res, gid, aria2, pv, sentm, bot) 83 | } catch (e) { 84 | console.log(e.message) 85 | } 86 | } 87 | 88 | 89 | async function getStatus(res, gid, aria2, pv, sentm, bot) { 90 | let opts = { 91 | chat_id: sentm.chat.id, 92 | message_id: sentm.message_id, 93 | reply_markup: { 94 | inline_keyboard: [ 95 | [{text: "cancel", callback_data: `cancel ${gid}`}] 96 | ] 97 | }, 98 | parse_mode: "HTML" 99 | }; 100 | 101 | if (res.status === 'active') { 102 | var smsg = generate_status_str(res); 103 | 104 | if (pv != smsg) { 105 | try { 106 | await bot.editMessageText(smsg, opts); 107 | } catch (e) { 108 | await sendStatus(gid, aria2, sentm, bot, smsg) 109 | } 110 | } 111 | 112 | } else if (res.status === 'waiting') { 113 | opts = { 114 | chat_id: sentm.chat.id, 115 | message_id: sentm.message_id, 116 | reply_markup: { 117 | inline_keyboard: [ 118 | [{text: "cancel", callback_data: `cancel ${gid}`}] 119 | ] 120 | }, 121 | parse_mode: "HTML" 122 | }; 123 | var smsg = `Gid :${res.gid}\n` 124 | smsg += `Status : Queued\n` 125 | 126 | if (pv != smsg) { 127 | try { 128 | await bot.editMessageText(smsg, opts); 129 | 130 | } catch (e) { 131 | 132 | console.warn(e.message) 133 | // ignoring error of non modified error 134 | } 135 | } 136 | } 137 | 138 | 139 | // complete 140 | else if (res.status === 'complete') { 141 | await bot.deleteMessage(sentm.chat.id, sentm.message_id) 142 | 143 | return 144 | } 145 | 146 | // Incase It stopped or Cancelled 147 | else if (res.status === 'removed') { 148 | return 149 | } 150 | // in other case maybe it not gonna come but just for backup 151 | else { 152 | return 153 | } 154 | await timeout(3000) 155 | await sendStatus(gid, aria2, sentm, bot, smsg) 156 | } 157 | 158 | 159 | function timeout(ms) { 160 | return new Promise(resolve => setTimeout(resolve, ms)); 161 | } 162 | 163 | module.exports = sendStatus 164 | -------------------------------------------------------------------------------- /drive/classupload.js: -------------------------------------------------------------------------------- 1 | "use strict" 2 | const fs = require("fs-extra"); 3 | 4 | const {google} = require("googleapis"); 5 | const path = require("path"); 6 | const {cleanup} = require("../utils/utils"); 7 | const client_file = path.join(__dirname, "../credentials.json"); 8 | const { MongoDB} = require("../database/userdb") 9 | 10 | class gdriveClient { 11 | 12 | constructor(uid) { 13 | this.user_id = uid.toString() 14 | this.TOKEN_PATH = path.join(__dirname, "../creds", `${uid}.json`); 15 | this.oAuth2Client = null 16 | this.token = null 17 | this.parent_id = null 18 | this.bot_folder = "TorrentDriveBot" 19 | this.FOLDER_MIME_TYPE = "application/vnd.google-apps.folder" 20 | this.drive = null 21 | this.teamdriveId = null 22 | 23 | return new Promise(async (resolve, reject) => { 24 | try { 25 | let mongo = await new MongoDB(this.user_id) 26 | this.teamdriveId = await mongo.getTeamdrive() 27 | 28 | await this.authorize() 29 | await this.set_botfolder() 30 | 31 | } catch (e) { 32 | reject(e) 33 | console.error(e.message) 34 | 35 | } 36 | resolve(this) 37 | 38 | }) 39 | 40 | } 41 | 42 | 43 | // set Auth and refresh 44 | authorize = () => { 45 | return new Promise(async (resolve, reject) => { 46 | 47 | try { 48 | let client_content = await fs.promises.readFile(client_file, 'utf-8') 49 | this.credentials = JSON.parse(client_content); 50 | const { 51 | client_secret, 52 | client_id, 53 | redirect_uris, 54 | } = this.credentials.installed; 55 | 56 | this.oAuth2Client = new google.auth.OAuth2( 57 | client_id, 58 | client_secret, 59 | redirect_uris[0] 60 | ); 61 | this.token = await fs.promises.readFile(this.TOKEN_PATH, 'utf-8') 62 | this.oAuth2Client.setCredentials(JSON.parse(this.token)); 63 | this.drive = google.drive({version: "v3", auth: this.oAuth2Client}); 64 | 65 | console.log("client Auth successfully ") 66 | resolve(this) 67 | 68 | } catch (e) { 69 | reject(e) 70 | } 71 | }); 72 | } 73 | 74 | 75 | set_botfolder = () => new Promise((resolve, reject) => { 76 | if(this.teamdriveId){ 77 | this.parent_id = this.teamdriveId 78 | console.log("TeamdriveId is avalible Uploading To teamdrive",this.teamdriveId) 79 | resolve(this.teamdriveId) 80 | return 81 | } 82 | this.drive.files.list({ 83 | q: "trashed = false", 84 | pageSize: 100, 85 | fields: "nextPageToken, files(id, name)", 86 | }, 87 | async (err, res) => { 88 | if (err) { 89 | reject(err) 90 | } 91 | 92 | for (let file of res.data.files) { 93 | if (file.name === this.bot_folder) { 94 | console.log(` ${file.name} found !!`); 95 | this.parent_id = file.id 96 | resolve(file.id) 97 | return 98 | } 99 | } 100 | const fol = await this.create_dir(this.bot_folder); 101 | console.log(`Folder Created ${fol.data.id} for ${this.bot_folder}`); 102 | this.parent_id = fol.data.id 103 | resolve() 104 | } 105 | ); 106 | 107 | }) 108 | 109 | // Create Directory 110 | create_dir = (name, parentId) => new Promise((resolve, reject) => { 111 | const fileMetadata = { 112 | name, 113 | mimeType: this.FOLDER_MIME_TYPE, 114 | parents: parentId ? [parentId] : null 115 | }; // prettier-ignore 116 | 117 | this.drive.files.create({ 118 | resource: fileMetadata, 119 | fields: "id", 120 | supportsAllDrives: true, 121 | }, 122 | (err, file) => (err ? reject(err) : resolve(file)) //file.data.id and name 123 | ); 124 | }) 125 | 126 | 127 | upload_handler = file_path => new Promise(async (resolve, reject) => { 128 | 129 | 130 | 131 | 132 | try { 133 | if (fs.lstatSync(file_path).isDirectory()) { 134 | let folderId = await this.upload_folder(file_path,this.parent_id) 135 | console.log(folderId) 136 | resolve(`https://drive.google.com/drive/folders/${folderId}`); 137 | } else { 138 | let file = await this.upload_file(file_path, this.parent_id) 139 | const file_id = file.data.id; 140 | resolve(`https://drive.google.com/uc?export=download&id=${file_id}`); 141 | } 142 | } catch (e) { 143 | console.error(e.message) 144 | reject(e) 145 | 146 | } finally { 147 | console.log("cleaning from Disk") 148 | cleanup(file_path) 149 | } 150 | 151 | 152 | 153 | 154 | 155 | }); 156 | 157 | 158 | upload_file = (file_path, parentId) => new Promise((resolve, reject) => { 159 | const name = path.basename(file_path); 160 | 161 | let media = {body: fs.createReadStream(file_path)}; 162 | this.drive.files.create({ 163 | resource: { 164 | name, 165 | parents: parentId ? [parentId] : null 166 | }, 167 | media: media, 168 | fields: "id", 169 | supportsAllDrives: true, 170 | }, 171 | (err, file) => (err ? reject(err) : resolve(file)) 172 | ); // prettier-ignore 173 | }); 174 | 175 | 176 | // Upload folder 177 | 178 | upload_folder = (dir_path, parentId) => new Promise(async (resolve, reject) => { 179 | const intr = dir_path.split("/"); 180 | const name = intr[intr.length - 1]; 181 | if (!fs.existsSync(dir_path)) { 182 | console.log(`Path ${dir_path} does not exists`); 183 | reject(`Path ${dir_path} does not exists`) 184 | } 185 | 186 | 187 | // make a folder in gdrive 188 | try { 189 | const folder = await this.create_dir(name, parentId); 190 | const folderId = folder.data.id; 191 | 192 | 193 | const contents = fs.readdirSync(dir_path, { withFileTypes: true }); 194 | 195 | for (let item of contents) { 196 | 197 | if (item.isDirectory()) { 198 | await this.upload_folder(`${dir_path}/${item.name}`, folderId); 199 | } 200 | else if (item.isFile()) { 201 | 202 | await this.upload_file(`${dir_path}/${item.name}`, folderId); 203 | } 204 | 205 | } 206 | 207 | resolve( folderId) 208 | }catch (e) { 209 | console.error("Create Folder error",e.message) 210 | reject(e) 211 | } 212 | 213 | 214 | 215 | 216 | }); 217 | 218 | 219 | }// class 220 | 221 | 222 | 223 | module.exports = {gdriveClient} -------------------------------------------------------------------------------- /aria.sh: -------------------------------------------------------------------------------- 1 | export MAX_DOWNLOAD_SPEED=0 2 | export T_out=300 3 | export MAX_CONCURRENT_DOWNLOADS=15 4 | 5 | export trackers="[udp://tracker.coppersurfer.tk:6969/announce,udp://tracker.leechers-paradise.org:6969/announce,udp://tracker.opentrackr.org:1337/announce,udp://p4p.arenabg.com:1337/announce,udp://9.rarbg.to:2710/announce,udp://9.rarbg.me:2710/announce,udp://tracker.pomf.se:80/announce,udp://tracker.openbittorrent.com:80/announce,udp://exodus.desync.com:6969/announce,udp://tracker.tiny-vps.com:6969/announce,udp://tracker.moeking.me:6969/announce,udp://retracker.lanta-net.ru:2710/announce,udp://open.stealth.si:80/announce,udp://denis.stalker.upeer.me:6969/announce,udp://tracker.torrent.eu.org:451/announce,udp://tracker.cyberia.is:6969/announce,udp://open.demonii.si:1337/announce,udp://ipv4.tracker.harry.lu:80/announce,udp://tracker3.itzmx.com:6961/announce,udp://zephir.monocul.us:6969/announce,http://104.238.198.186:8000/announce,http://1337.abcvg.info:80/announce,http://178.175.143.27:80/announce,http://78.30.254.12:2710/announce,http://87.110.238.140:6969/announce,http://93.92.64.5:80/announce,http://[2001:1b10:1000:8101:0:242:ac11:2]:6969/announce,http://[2001:470:1:189:0:1:2:3]:6969/announce,http://[2a04:ac00:1:3dd8::1:2710]:2710/announce,http://aaa.army:8866/announce,http://atrack.pow7.com:80/announce,http://bt.pusacg.org:8080/announce,http://explodie.org:6969/announce,http://grifon.info:80/announce,http://h4.trakx.nibba.trade:80/announce,http://ns349743.ip-91-121-106.eu:80/announce,http://omg.wtftrackr.xyz:80/announce,http://open.acgnxtracker.com:80/announce,http://open.acgtracker.com:1096/announce,http://open.touki.ru:80/announce.php,http://opentracker.i2p.rocks:6969/announce,http://p4p.arenabg.com:1337/announce,http://pow7.com:80/announce,http://retracker.hotplug.ru:2710/announce,http://retracker.krs-ix.ru:80/announce,http://retracker.sevstar.net:2710/announce,http://retracker.spark-rostov.ru:80/announce,http://secure.pow7.com:80/announce,http://share.camoe.cn:8080/announce,http://t.acg.rip:6699/announce,http://t.nyaatracker.com:80/announce,http://t.overflow.biz:6969/announce,http://t1.leech.ie:80/announce,http://t1.pow7.com:80/announce,http://t2.leech.ie:80/announce,http://t2.pow7.com:80/announce,http://t3.leech.ie:80/announce,http://thetracker.org:80/announce,http://torrent.nwps.ws:80/announce,http://torrentsmd.com:8080/announce,http://tr.cili001.com:8070/announce,http://tr.kxmp.cf:80/announce,http://tracker.anonwebz.xyz:8080/announce,http://tracker.birkenwald.de:6969/announce,http://tracker.bittor.pw:1337/announce,http://tracker.bt4g.com:2095/announce,http://tracker.bz:80/announce,http://tracker.corpscorp.online:80/announce,http://tracker.dler.org:6969/announce,http://tracker.dutchtracking.nl:80/announce,http://tracker.files.fm:6969/announce,http://tracker.gbitt.info:80/announce,http://tracker.ipv6tracker.ru:80/announce,http://tracker.kamigami.org:2710/announce,http://tracker.kuroy.me:5944/announce,http://tracker.lelux.fi:80/announce,http://tracker.moeking.me:6969/announce,http://tracker.nyap2p.com:8080/announce,http://tracker.opentrackr.org:1337/announce,http://tracker.publicbt.com:80/announce,http://tracker.skyts.net:6969/announce,http://tracker.trackerfix.com:80/announce,http://tracker.uw0.xyz:6969/announce,http://tracker.ygsub.com:6969/announce,http://tracker.yoshi210.com:6969/announce,http://tracker.zerobytes.xyz:1337/announce,http://tracker1.itzmx.com:8080/announce,http://tracker2.dler.org:80/announce,http://tracker2.itzmx.com:6961/announce,http://tracker3.itzmx.com:6961/announce,http://trun.tom.ru:80/announce,http://vps02.net.orel.ru:80/announce,http://www.loushao.net:8080/announce,http://www.wareztorrent.com:80/announce,https://1337.abcvg.info:443/announce,https://2.tracker.eu.org:443/announce,https://3.tracker.eu.org:443/announce,https://aaa.army:8866/announce,https://open.kickasstracker.com:443/announce,https://opentracker.acgnx.se:443/announce,https://t1.leech.ie:443/announce,https://t2.leech.ie:443/announce,https://t3.leech.ie:443/announce,https://tk.mabo.ltd:443/announce,https://tracker.bt-hash.com:443/announce,https://tracker.gbitt.info:443/announce,https://tracker.imgoingto.icu:443/announce,https://tracker.lelux.fi:443/announce,https://tracker.nanoha.org:443/announce,https://tracker.nitrix.me:443/announce,https://tracker.sloppyta.co:443/announce,https://tracker.tamersunion.org:443/announce,https://tracker.vectahosting.eu:2053/announce,https://tracker.vectahosting.eu:8443/announce,https://tracker6.lelux.fi:443/announce,https://w.wwwww.wtf:443/announce,https://www.wareztorrent.com:443/announce,udp://104.238.198.186:8000/announce,udp://107.150.14.110:6969/announce,udp://109.121.134.121:1337/announce,udp://114.55.113.60:6969/announce,udp://128.199.70.66:5944/announce,udp://151.80.120.114:2710/announce,udp://168.235.67.63:6969/announce,udp://178.33.73.26:2710/announce,udp://182.176.139.129:6969/announce,udp://185.5.97.139:8089/announce,udp://185.83.215.123:6969/announce,udp://185.86.149.205:1337/announce,udp://188.165.253.109:1337/announce,udp://191.101.229.236:1337/announce,udp://194.106.216.222:80/announce,udp://195.123.209.37:1337/announce,udp://195.123.209.40:80/announce,udp://208.67.16.113:8000/announce,udp://212.1.226.176:2710/announce,udp://212.47.227.58:6969/announce,udp://213.163.67.56:1337/announce,udp://37.19.5.155:2710/announce,udp://46.4.109.148:6969/announce,udp://5.79.249.77:6969/announce,udp://5.79.83.193:6969/announce,udp://51.254.244.161:6969/announce,udp://52.58.128.163:6969/announce,udp://62.138.0.158:6969/announce,udp://62.212.85.66:2710/announce,udp://74.82.52.209:6969/announce,udp://78.30.254.12:2710/announce,udp://85.17.19.180:80/announce,udp://89.234.156.205:80/announce,udp://9.rarbg.com:2710/announce,udp://9.rarbg.me:2710/announce,udp://9.rarbg.me:2780/announce,udp://9.rarbg.to:2710/announce,udp://9.rarbg.to:2730/announce,udp://91.216.110.52:451/announce,udp://91.218.230.81:6969/announce,udp://94.23.183.33:6969/announce,udp://95.211.168.204:2710/announce,udp://[2001:1b10:1000:8101:0:242:ac11:2]:6969/announce,udp://[2001:470:1:189:0:1:2:3]:6969/announce,udp://[2a03:7220:8083:cd00::1]:451/announce,udp://[2a04:ac00:1:3dd8::1:2710]:2710/announce,udp://[2a04:c44:e00:32e0:4cf:6aff:fe00:aa1]:6969/announce,udp://aaa.army:8866/announce,udp://bt.okmp3.ru:2710/announce,udp://bt1.archive.org:6969/announce,udp://bt2.54new.com:8080/announce,udp://bt2.archive.org:6969/announce,udp://chihaya.de:6969/announce,udp://chihaya.toss.li:9696/announce,udp://eddie4.nl:6969/announce,udp://exodus.desync.com:6969/announce,udp://ipv4.tracker.harry.lu:80/announce,udp://ipv6.tracker.harry.lu:80/announce,udp://ipv6.tracker.zerobytes.xyz:16661/announce,udp://mgtracker.org:2710/announce,udp://open.demonii.com:1337/announce,udp://open.nyap2p.com:6969/announce,udp://open.stealth.si:80/announce,udp://opentor.org:2710/announce,udp://opentracker.i2p.rocks:6969/announce,udp://peerfect.org:6969/announce,udp://public.popcorn-tracker.org:6969/announce,udp://qg.lorzl.gq:2710/announce,udp://retracker.akado-ural.ru:80/announce,udp://retracker.baikal-telecom.net:2710/announce,udp://retracker.hotplug.ru:2710/announce,udp://retracker.lanta-net.ru:2710/announce,udp://retracker.netbynet.ru:2710/announce,udp://retracker.nts.su:2710/announce,udp://retracker.sevstar.net:2710/announce,udp://shadowshq.eddie4.nl:6969/announce,udp://shadowshq.yi.org:6969/announce,udp://thetracker.org:80/announce,udp://torrentclub.tech:6969/announce,udp://tr.bangumi.moe:6969/announce,udp://tr.cili001.com:8070/announce,udp://tracker-udp.gbitt.info:80/announce,udp://tracker.0o.is:6969/announce,udp://tracker.aletorrenty.pl:2710/announce,udp://tracker.army:6969/announce,udp://tracker.beeimg.com:6969/announce,udp://tracker.birkenwald.de:6969/announce,udp://tracker.bittor.pw:1337/announce,udp://tracker.coppersurfer.tk:6969/announce,udp://tracker.cyberia.is:6969/announce,udp://tracker.dler.org:6969/announce,udp://tracker.ds.is:6969/announce,udp://tracker.e-utp.net:6969/announce,udp://tracker.eddie4.nl:6969/announce,udp://tracker.ex.ua:80/announce,udp://tracker.filemail.com:6969/announce,udp://tracker.filepit.to:6969/announce,udp://tracker.flashtorrents.org:6969/announce,udp://tracker.fortu.io:6969/announce,udp://tracker.gbitt.info:80/announce,udp://tracker.grepler.com:6969/announce,udp://tracker.halfchub.club:6969/announce,udp://tracker.iamhansen.xyz:2000/announce,udp://tracker.internetwarriors.net:1337/announce,udp://tracker.kamigami.org:2710/announce,udp://tracker.kuroy.me:5944/announce,udp://tracker.leechers-paradise.org:6969/announce,udp://tracker.lelux.fi:6969/announce,udp://tracker.moeking.me:6969/announce,udp://tracker.msm8916.com:6969/announce,udp://tracker.open-internet.nl:6969/announce,udp://tracker.openbittorrent.com:80/announce,udp://tracker.opentrackr.org:1337/announce,udp://tracker.piratepublic.com:1337/announce,udp://tracker.publicbt.com:80/announce,udp://tracker.sbsub.com:2710/announce,udp://tracker.skyts.net:6969/announce,udp://tracker.swateam.org.uk:2710/announce,udp://tracker.teambelgium.net:6969/announce,udp://tracker.tiny-vps.com:6969/announce,udp://tracker.torrent.eu.org:451/announce,udp://tracker.torrentbay.to:6969/announce,udp://tracker.tvunderground.org.ru:3218/announce,udp://tracker.uw0.xyz:6969/announce,udp://tracker.yoshi210.com:6969/announce,udp://tracker.zerobytes.xyz:1337/announce,udp://tracker.zum.bi:6969/announce,udp://tracker1.itzmx.com:8080/announce,udp://tracker2.christianbro.pw:6969/announce,udp://tracker2.indowebster.com:6969/announce,udp://tracker2.itzmx.com:6961/announce,udp://tracker3.itzmx.com:6961/announce,udp://tracker4.itzmx.com:2710/announce,udp://tracker6.dler.org:2710/announce,udp://u.wwwww.wtf:1/announce,udp://valakas.rollo.dnsabr.com:2710/announce,udp://www.loushao.net:8080/announce,udp://xxxtor.com:2710/announce,udp://zephir.monocul.us:6969/announce,udp://zer0day.ch:1337/announce,udp://zer0day.to:1337/announce]" 6 | 7 | 8 | aria2c --enable-rpc --rpc-listen-all=false --always-resume=true --rpc-listen-port 6800 --bt-tracker=$trackers --bt-stop-timeout=$T_out --max-connection-per-server=10 --rpc-max-request-size=1024M --seed-time=0.01 --min-split-size=10M --follow-torrent=mem --split=10 --daemon=true --allow-overwrite=true --max-overall-download-limit=$MAX_DOWNLOAD_SPEED --max-overall-upload-limit=1K --max-concurrent-downloads=$MAX_CONCURRENT_DOWNLOADS 9 | echo service started 10 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | "use strict" 2 | process.env["NTBA_FIX_319"] = 1; 3 | 4 | const TelegramBot = require("node-telegram-bot-api"); 5 | const {sendmsg, edit} = require("./telegram/msgutils"); 6 | const Command = require("./telegram/command"); 7 | const fs = require("fs"); 8 | const path = require("path"); 9 | const { 10 | DownloadFolderChecker, 11 | isAuth, 12 | DownloadList, 13 | } = require("./utils/utils"); 14 | const {tgToken} = require("./config"); 15 | const {getAuthurl} = require("./drive/AuthUrl"); 16 | const {CreateToken} = require("./drive/token"); 17 | const diskinfo = require("./utils/disk"); 18 | const {deleteToken, TokenInsert} = require("./database/dbtoken"); 19 | const {MongoDB} = require("./database/userdb"); 20 | const Aria2 = require("aria2"); 21 | const {ariaListners} = require("./aria/ariahandler"); 22 | const ariaAdd = require("./aria/add"); 23 | const isTorrent = require("./utils/istorrent"); 24 | 25 | const {cancelgid} = require("./aria/ariacancel"); 26 | const PORT = 6800; 27 | const ariaOptions = { 28 | host: "localhost", 29 | port: 6800, 30 | secure: false, 31 | secret: "", 32 | path: "/jsonrpc", 33 | }; 34 | 35 | const aria2 = new Aria2(ariaOptions); 36 | 37 | aria2 38 | .open() 39 | .then(() => { 40 | console.log("Websocket Opened Port", PORT); 41 | }) 42 | .catch(() => { 43 | console.log("WebSocket is closed exiting .."); 44 | process.exit(1); 45 | }); 46 | 47 | const startTime = Date.now(); 48 | 49 | //////////////////////////// Do not Touch This part //////////////////////////////////////////////////////// 50 | const command = new Command(); 51 | // DownloadFolderChecker(); 52 | const token = tgToken; 53 | const bot = new TelegramBot(token, {polling: true}); 54 | bot.on("polling_error", (msg) => console.error(msg.message)); 55 | ////////////////////////////////////////////////////////////////////////////////////// 56 | 57 | ariaListners(aria2, bot); 58 | 59 | 60 | // Start 61 | bot.onText(command.start, async (msg) => { 62 | if (!(await userinChannel(msg))) { 63 | await sendJoinChannel(msg); 64 | return; 65 | } 66 | 67 | const opts = { 68 | reply_markup: { 69 | inline_keyboard: [ 70 | [{text: "Join Channel", url: "https://t.me/aryan_bots"}], 71 | ], 72 | },parse_mode: "HTML", 73 | }; 74 | 75 | let Startmsg = `Hey ${msg.from.first_name} 76 | Bot Uptime : ${getuptime()} 77 | Note: Check Uptime If You Think Your Download Is Not in List Or Disappear 78 | It mostly happen Due To Server overload And restart Hope You Can understand 😁 79 | 80 | check /help Command For more information 81 | `; 82 | // await sendmsg("Just A Useless Command\nJoin @aryan_bots For Useless Updates😒 ", msg, bot); 83 | await bot.sendMessage(msg.chat.id, Startmsg, opts); 84 | console.log(DownloadList); 85 | 86 | }); 87 | 88 | // callaback Function 89 | 90 | bot.on("callback_query", async callbackQuery => { 91 | const data = callbackQuery.data; 92 | const msg = callbackQuery.message; 93 | const opts = { 94 | chat_id: msg.chat.id, 95 | message_id: msg.message_id, 96 | parse_mode: "HTML", 97 | }; 98 | 99 | if (data.startsWith("cancel")) { 100 | let gid = data.split(" ")[1]; 101 | // bot.editMessageText(d, opts); 102 | await cancelgid(aria2, gid, msg, bot, opts); 103 | } 104 | }); 105 | 106 | 107 | 108 | // torrent file Handler 109 | bot.on("document", async (msg) => { 110 | if (!(await userinChannel(msg))) { 111 | await sendJoinChannel(msg); 112 | return; 113 | } 114 | 115 | if (!(await isAuth(msg))) { 116 | await sendmsg("You should Login first using /login ", msg, bot); 117 | return; 118 | } 119 | 120 | if (msg.document.mime_type === "application/x-bittorrent") { 121 | if(DownloadList[msg.from.id] === true){ 122 | await sendmsg("One Download At a Time Please Don't abuse it", msg, bot); 123 | return 124 | } 125 | 126 | let uri = await bot.getFileLink(msg.document.file_id); 127 | 128 | console.log(uri); 129 | ariaAdd(aria2, uri, msg, bot); 130 | 131 | } 132 | }); 133 | 134 | // Only zip For zip Torrent File 135 | bot.onText(command.doczip, async (msg) => { 136 | // await sendmsg("Zip Temporary disabled", msg, bot); 137 | // return ; 138 | if (!(await userinChannel(msg))) { 139 | await sendJoinChannel(msg); 140 | return; 141 | } 142 | 143 | if (!(await isAuth(msg))) { 144 | await sendmsg("You should Login first using /login ", msg, bot); 145 | return; 146 | } 147 | 148 | if ( 149 | msg.reply_to_message && 150 | msg.reply_to_message.document && 151 | msg.reply_to_message.document.mime_type === "application/x-bittorrent" 152 | ) { 153 | if(DownloadList[msg.from.id] === true){ 154 | await sendmsg("One Download At a Time Please Don't abuse it", msg, bot); 155 | return 156 | } 157 | 158 | 159 | let uri = await bot.getFileLink(msg.reply_to_message.document.file_id); 160 | 161 | console.log(uri); 162 | 163 | ariaAdd(aria2, uri, msg, bot, true); 164 | 165 | 166 | } 167 | }); 168 | 169 | 170 | 171 | 172 | 173 | // upload Command 174 | bot.onText(command.magnet, async (msg, match) => { 175 | if (!(await userinChannel(msg))) { 176 | await sendJoinChannel(msg); 177 | return; 178 | } 179 | 180 | let uri = match[0]; 181 | if(DownloadList[msg.from.id] === true){ 182 | await sendmsg("One Download At a Time Please Don't abuse it", msg, bot); 183 | return 184 | } 185 | 186 | if (uri.startsWith("http")) { 187 | if (!(await isTorrent(uri))) { 188 | await sendmsg("Supports only Torrents 😔 ", msg, bot); 189 | return; 190 | } 191 | } 192 | if (await isAuth(msg)) { 193 | // addTorrent(uri, msg, bot); 194 | 195 | ariaAdd(aria2, uri, msg, bot, false); 196 | 197 | 198 | 199 | } else { 200 | await sendmsg("You should Login first using /login ", msg, bot); 201 | } 202 | }); 203 | 204 | 205 | 206 | // login 207 | bot.onText(command.login, async (msg) => { 208 | if (!(await userinChannel(msg))) { 209 | await sendJoinChannel(msg); 210 | return; 211 | } 212 | 213 | if (await isAuth(msg)) { 214 | await sendmsg("You Are Already Authorized !!", msg, bot); 215 | } else { 216 | await getAuthurl(msg, bot); 217 | } 218 | }); 219 | 220 | // Token Handler 221 | bot.onText(command.token, async (msg, match) => { 222 | if (!(await userinChannel(msg))) { 223 | await sendJoinChannel(msg); 224 | return; 225 | } 226 | const code = match[0]; 227 | if (await isAuth(msg, true)) { 228 | await sendmsg("Your Are Alredy logged in !!", msg, bot); 229 | } else { 230 | CreateToken(code, msg, bot); 231 | setTimeout(() => { 232 | TokenInsert(msg.from.id); 233 | }, 2000); 234 | } 235 | }); 236 | 237 | //logout 238 | bot.onText(command.logout, async (msg) => { 239 | if (!(await userinChannel(msg))) { 240 | await sendJoinChannel(msg); 241 | return; 242 | } 243 | 244 | // If Error That mean There is no file 245 | const userId = msg.from.id.toString(); 246 | const credsPath = path.join(__dirname, `./creds/${userId}.json`); 247 | if (await isAuth(msg, true)) { 248 | fs.unlink(credsPath, (err) => { 249 | if (!err) { 250 | sendmsg("Logout Successfully !!", msg, bot); 251 | console.log("logout success", userId); 252 | } else { 253 | console.error("deleting creds file", err); 254 | } 255 | }); 256 | await deleteToken(userId); 257 | } else { 258 | await sendmsg("You Are not Logged In Use /login !!", msg, bot); 259 | } 260 | }); 261 | 262 | // Zip 263 | 264 | bot.onText(command.zip, async (msg, match) => { 265 | // await sendmsg("Zip Temporary disabled", msg, bot); 266 | // return; 267 | if (!(await userinChannel(msg))) { 268 | await sendJoinChannel(msg); 269 | return; 270 | } 271 | const uri = match[1]; 272 | 273 | if(DownloadList[msg.from.id] === true){ 274 | await sendmsg("One Download At a Time Please Don't abuse it", msg, bot); 275 | return 276 | } 277 | 278 | if (uri.startsWith("http")) { 279 | if (!(await isTorrent(uri))) { 280 | await sendmsg("Supports only Torrents 😔 ", msg, bot); 281 | return; 282 | } 283 | } 284 | 285 | if (await isAuth(msg)) { 286 | ariaAdd(aria2, uri, msg, bot, true); 287 | 288 | } else { 289 | await sendmsg("You should Login first using /login ", msg, bot); 290 | } 291 | }); 292 | 293 | // cancel 294 | 295 | bot.onText(command.cancel, async (msg, match) => { 296 | await sendmsg("This command is deprecated", msg, bot); 297 | return 298 | if (!(await userinChannel(msg))) { 299 | await sendJoinChannel(msg); 300 | return; 301 | } 302 | await cancelgid(aria2, match[1], msg, bot); 303 | // cancel(gid, msg, bot) 304 | }); 305 | 306 | // help 307 | bot.onText(command.help, async (msg) => { 308 | if (!(await userinChannel(msg))) { 309 | await sendJoinChannel(msg); 310 | return; 311 | } 312 | 313 | let helptext = 314 | "⭐️ I can Download Torrent In Your Google Drive Account ⭐️ \n\n"; 315 | 316 | helptext += "/start - Start Command \n\n"; 317 | helptext += "/login - Login To Your Account \n\n"; 318 | helptext += "/logout - Logout Your Account \n\n"; 319 | helptext += 320 | "Upload (no need any command): Just Send Your Magnet ,Torrent Direct Url or Torrent File: \n\n"; 321 | helptext += 322 | "/zip - Upload compressed Version in your Drive ,same as Up command \n\n"; 323 | helptext += 324 | "/addtd - Add Your Teamdrive Id eg:/addtd Xyz**** \n\n"; 325 | helptext += "/rmtd - Will Remove Teamdrive from database\n\n"; 326 | helptext += "/disk - Server Disk Info and Uptime\n\n"; 327 | helptext += "Limit : Max Size limit 20GB\n"; 328 | await sendmsg(helptext, msg, bot); 329 | }); 330 | 331 | // Disk Info 332 | 333 | bot.onText(command.server, async (msg) => { 334 | if (!(await userinChannel(msg))) { 335 | await sendJoinChannel(msg); 336 | return; 337 | } 338 | 339 | 340 | await diskinfo(getuptime(), msg, bot); 341 | }); 342 | 343 | // set Teamdrive Info 344 | 345 | bot.onText(command.setTD, async (msg, match) => { 346 | if (!(await userinChannel(msg))) { 347 | await sendJoinChannel(msg); 348 | return; 349 | } 350 | 351 | let tdId = match[1].trim(); 352 | const mongo = await new MongoDB(msg.from.id) 353 | try { 354 | const res = await mongo.setTeamdrive(tdId) 355 | if (res) { 356 | await sendmsg( 357 | `Teamdrive added ${await mongo.getTeamdrive()} `, 358 | msg, 359 | bot 360 | ); 361 | } else { 362 | await sendmsg(" Failed To Add Teamdrive", msg, bot); 363 | } 364 | }catch (e) { 365 | console.error(e.message) 366 | } 367 | 368 | }); 369 | 370 | // set Teamdrive Info 371 | 372 | bot.onText(command.removeTD, async (msg) => { 373 | if (!(await userinChannel(msg))) { 374 | await sendJoinChannel(msg); 375 | return; 376 | } 377 | const mongo = await new MongoDB(msg.from.id) 378 | await mongo.removeTeamdrive() 379 | await sendmsg(`Teamdrive Removed from Database`, msg, bot); 380 | 381 | }); 382 | 383 | const userinChannel = async (msg) => { 384 | try { 385 | let user = await bot.getChatMember("@aryan_bots", msg.from.id); 386 | 387 | if (user.status === "member" || user.status === "administrator") { 388 | console.log(user.status, msg.from.id); 389 | return true; 390 | } else { 391 | console.log(user.status, msg.from.id); 392 | return false; 393 | } 394 | } catch (e) { 395 | console.log("not a member of channel: ", e.message); 396 | return false; 397 | } 398 | }; 399 | 400 | const sendJoinChannel = async (msg) => { 401 | const opts = { 402 | reply_markup: { 403 | inline_keyboard: [ 404 | [{text: "Join Channel", url: "https://t.me/aryan_bots"}], 405 | ], 406 | }, 407 | }; 408 | 409 | // await sendmsg("Just A Useless Command\nJoin @aryan_bots For Useless Updates😒 ", msg, bot); 410 | await bot.sendMessage(msg.chat.id, "Join Channel To access Bot", opts); 411 | }; 412 | 413 | 414 | function getuptime() { 415 | const currentTime = Date.now() - startTime; 416 | const timestamp = Math.floor(currentTime / 1000); 417 | 418 | const hours = Math.floor(timestamp / 60 / 60); 419 | 420 | const minutes = Math.floor(timestamp / 60) - hours * 60; 421 | 422 | const seconds = timestamp % 60; 423 | return hours + ":" + minutes + ":" + seconds 424 | 425 | } --------------------------------------------------------------------------------