├── 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 | }
--------------------------------------------------------------------------------