diff --git a/README.md b/README.md index 3d7aa28..1d5a2ee 100644 --- a/README.md +++ b/README.md @@ -94,10 +94,10 @@ A config file will be auto-generated when you run the program for the first time 1. Duplicate the `example-config.yaml` file and name it `config.yaml` -#### Set up account details +#### Set up account details ([why do I need this?](#FAQ)) 1. Go to [Here](https://my.telegram.org/apps), login with your phone number and create a Telegram app. -2. Copy the `api_id` and `api_hash` from the Telegram app page (step 2) to the config file (`telegram -> api_id / api_hash`) +2. Copy the `api_id` and `api_hash` from the Telegram app page (step 2) to the config file (`telegram -> account -> api_id / api_hash`) #### Set up the channel to store files @@ -105,21 +105,37 @@ A config file will be auto-generated when you run the program for the first time 2. There should be a message like "Channel created". Right click the message and copy the post link. 3. The format of the link should be like `https://t.me/c/1234567/1`, where `1234567` is the channel id. Copy the channel id to the config file (`telegram -> private_file_channel`) +#### Set up a Telegram bot ([why do I need this?](#FAQ)) + +1. Go to [BotFather](https://telegram.me/BotFather), send `/newbot`, and follow the steps to create a bot. +2. Paste the bot token given by BotFater to the config file (`telegram -> bot -> token`) +3. Go to your file channel (created in the previous step), add your bot to subscriber, and promote it to admin, with permission to send/edit/delete messages. + ## Config fields explanation - telegram - - session_file: The file path to store the session data. If you want to use multiple accounts, you can set different session files for each account. + - account: + - session_file: The file path to store the session data. If you want to use multiple accounts, you can set different session files for each account. - login_timeout: Time to wait before login attempt aborts (in milliseconds). - tgfs + - users: the users authenticated by tgfs, used by both webdav authentication and monitor - download - - porgress: Whether to show a progress bar when downloading files - chunk_size_kb: The chunk size in KB when downloading files. Bigger chunk size means less requests. - webdav - host: The host of the WebDAV server listening on. - port: The port of the WebDAV server listening on. - - users: The users of the WebDAV server. - - password: The password of the user. + - path: The root path for the WebDAV server. For example, setting this value to /webdav makes the WebDAV link `http://[host]:[port]/webdav`. + +## FAQ + +**Q: Why do I need a bot when my account is also able to send messages?** + +Frequently sending messages may get your account banned, so using a bot is the best way to manage the risk. You can create another bot when it is banned. + +**Q: Why do I need an account API then?** + +The functionality of bot API is limited. For example, a bot can neither read history messages, nor send files exceeding 50MB. The account API is used when a bot cannot do the job. diff --git a/example-config.yaml b/example-config.yaml index aa663b6..b071a3a 100644 --- a/example-config.yaml +++ b/example-config.yaml @@ -1,17 +1,19 @@ telegram: - api_id: your_api_id (mandatory, refer to README) - api_hash: your_api_hash (mandatory refer to README) - session_file: ~/.tgfs/your_account.session (optional, default to ~/.tgfs/account.session) + account: + api_id: your_api_id (mandatory, refer to README) + api_hash: your_api_hash (mandatory, refer to README) + session_file: ~/.tgfs/account.session + bot: + token: your_bot_token (mandatory, refer to README) login_timeout: 300000 private_file_channel: your_channel_id (mandatory, refer to README) - public_file_channel: another_channel_id (optional) + public_file_channel: 0 tgfs: users: user: password: password download: - progress: true chunk_size_kb: 1024 webdav: diff --git a/src/auth/account.ts b/src/auth/account.ts index ab6b4eb..a098eec 100644 --- a/src/auth/account.ts +++ b/src/auth/account.ts @@ -1,7 +1,8 @@ +import * as fs from 'fs'; + import { TelegramClient } from 'telegram'; import { StringSession } from 'telegram/sessions'; -import * as fs from 'fs'; import * as input from 'input'; import { config } from 'src/config'; @@ -10,11 +11,12 @@ import { Logger } from 'src/utils/logger'; export const loginAsAccount = async ( reset: boolean = false, ): Promise => { - const apiId = config.telegram.reader.api_id; - const apiHash = config.telegram.reader.api_hash; - const session_file = config.telegram.reader.session_file; + const apiId = config.telegram.account.api_id; + const apiHash = config.telegram.account.api_hash; + const session_file = config.telegram.account.session_file; if (!reset && fs.existsSync(session_file)) { + console.log(`using session file: ${session_file}`); const session = new StringSession(String(fs.readFileSync(session_file))); const client = new TelegramClient(session, apiId, apiHash, { connectionRetries: 5, diff --git a/src/config.ts b/src/config.ts index 573af2a..13888e3 100644 --- a/src/config.ts +++ b/src/config.ts @@ -1,4 +1,5 @@ import fs from 'fs'; + import input from 'input'; import yaml from 'js-yaml'; import os from 'os'; @@ -10,24 +11,21 @@ export const loadConfig = (configPath: string) => { const file = fs.readFileSync(configPath, 'utf8'); const cfg = yaml.load(file); - const createSessionFileDir = (session_file: string) => { - if (session_file[0] === '~') { - session_file = path.join(os.homedir(), session_file.slice(1)); - } - if (!fs.existsSync(session_file)) { - const dir = path.dirname(session_file); - fs.mkdirSync(dir, { recursive: true }); - } - }; + let session_file = cfg['telegram']['account']['session_file']; - createSessionFileDir(cfg['telegram']['account']['session_file']); - createSessionFileDir(cfg['telegram']['bot']['session_file']); + if (session_file[0] === '~') { + session_file = path.join(os.homedir(), session_file.slice(1)); + } + if (!fs.existsSync(session_file)) { + const dir = path.dirname(session_file); + fs.mkdirSync(dir, { recursive: true }); + } config.telegram = { account: { api_id: cfg['telegram']['account']['api_id'], api_hash: cfg['telegram']['account']['api_hash'], - session_file: cfg['telegram']['account']['session_file'], + session_file, }, bot: { token: cfg['telegram']['bot']['token'], @@ -107,9 +105,9 @@ export const createConfig = async () => { console.log( '\nGo to https://t.me/botfather to create a Bot and paste the bot token here.', ); - config.telegram.bot.token = Number( - await input.text('Bot token', { validate: validateNotEmpty }), - ); + config.telegram.bot.token = await input.text('Bot token', { + validate: validateNotEmpty, + }); console.log('\nCreate a PRIVATE channel and paste the channel id here'); config.telegram.private_file_channel = Number( diff --git a/src/index.ts b/src/index.ts index a8b7409..667b490 100644 --- a/src/index.ts +++ b/src/index.ts @@ -47,6 +47,7 @@ const { argv }: any = yargs(hideBin(process.argv)) try { loadConfig(configPath); } catch (err) { + Logger.debug(err); configPath = await createConfig(); loadConfig(configPath); } diff --git a/src/model/directory.ts b/src/model/directory.ts index 0402431..9337d82 100644 --- a/src/model/directory.ts +++ b/src/model/directory.ts @@ -1,5 +1,3 @@ -import { Api } from 'telegram'; - import { FileOrDirectoryAlreadyExistsError } from 'src/errors/path'; import { TGFSDirectoryObject, TGFSFileRefObject } from './message'; diff --git a/src/utils/logger.ts b/src/utils/logger.ts index c97978a..6fc11ab 100644 --- a/src/utils/logger.ts +++ b/src/utils/logger.ts @@ -7,6 +7,12 @@ export class Logger { return new Date(Date.now() - this.tzOffset).toISOString().slice(0, -1); } + static debug(...args: any[]) { + if (process.env.DEBUG === 'true') { + console.debug(`[${this.getTime()}] [DEBUG]`, ...args); + } + } + static info(...args: any[]) { console.info(`[${this.getTime()}] [INFO]`, ...args); }